llvm.org GIT mirror llvm / 80b09fe
Teach branch folding pass about implicit_def instructions. Unfortunately we can't just eliminate them since register scavenger expects every register use to be defined. However, we can delete them when there are no intra-block uses. Carefully removing some implicit def's which enable more blocks to be optimized away. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49461 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 11 years ago
3 changed file(s) with 107 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
2626 #include "llvm/Target/TargetRegisterInfo.h"
2727 #include "llvm/Support/CommandLine.h"
2828 #include "llvm/Support/Debug.h"
29 #include "llvm/ADT/SmallSet.h"
2930 #include "llvm/ADT/Statistic.h"
3031 #include "llvm/ADT/STLExtras.h"
3132 #include
7778 bool OptimizeBranches(MachineFunction &MF);
7879 void OptimizeBlock(MachineBasicBlock *MBB);
7980 void RemoveDeadBlock(MachineBasicBlock *MBB);
81 bool OptimizeImpDefsBlock(MachineBasicBlock *MBB);
8082
8183 bool CanFallThrough(MachineBasicBlock *CurBB);
8284 bool CanFallThrough(MachineBasicBlock *CurBB, bool BranchUnAnalyzable,
116118 MF->getBasicBlockList().erase(MBB);
117119 }
118120
121 /// OptimizeImpDefsBlock - If a basic block is just a bunch of implicit_def
122 /// followed by terminators, and if the implicitly defined registers are not
123 /// used by the terminators, remove those implicit_def's. e.g.
124 /// BB1:
125 /// r0 = implicit_def
126 /// r1 = implicit_def
127 /// br
128 /// This block can be optimized away later if the implicit instructions are
129 /// removed.
130 bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) {
131 SmallSet ImpDefRegs;
132 MachineBasicBlock::iterator I = MBB->begin();
133 while (I != MBB->end()) {
134 if (I->getOpcode() != TargetInstrInfo::IMPLICIT_DEF)
135 break;
136 unsigned Reg = I->getOperand(0).getReg();
137 ImpDefRegs.insert(Reg);
138 for (const unsigned *SubRegs = RegInfo->getSubRegisters(Reg);
139 unsigned SubReg = *SubRegs; ++SubRegs)
140 ImpDefRegs.insert(SubReg);
141 ++I;
142 }
143 if (ImpDefRegs.empty())
144 return false;
145
146 MachineBasicBlock::iterator FirstTerm = I;
147 while (I != MBB->end()) {
148 if (!TII->isUnpredicatedTerminator(I))
149 return false;
150 // See if it uses any of the implicitly defined registers.
151 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
152 MachineOperand &MO = I->getOperand(i);
153 if (!MO.isReg() || !MO.isUse())
154 continue;
155 unsigned Reg = MO.getReg();
156 if (ImpDefRegs.count(Reg))
157 return false;
158 }
159 ++I;
160 }
161
162 I = MBB->begin();
163 while (I != FirstTerm) {
164 MachineInstr *ImpDefMI = &*I;
165 ++I;
166 MBB->erase(ImpDefMI);
167 }
168
169 return true;
170 }
171
119172 bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
120173 TII = MF.getTarget().getInstrInfo();
121174 if (!TII) return false;
175
176 RegInfo = MF.getTarget().getRegisterInfo();
122177
123178 // Fix CFG. The later algorithms expect it to be right.
124179 bool EverMadeChange = false;
127182 std::vector Cond;
128183 if (!TII->AnalyzeBranch(*MBB, TBB, FBB, Cond))
129184 EverMadeChange |= MBB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty());
130 }
131
132 RegInfo = MF.getTarget().getRegisterInfo();
185 EverMadeChange |= OptimizeImpDefsBlock(MBB);
186 }
187
133188 RS = RegInfo->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL;
134189
135190 MMI = getAnalysisToUpdate();
None ; RUN: llvm-as < %s | llc -mcpu=i686 | not grep jmp
0 ; RUN: llvm-as < %s | llc -march=x86 -mcpu=i686 | not grep jmp
11 ; check that branch folding understands FP_REG_KILL is not a branch
22
3 ; ModuleID = 'g.bc'
4 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
53 target triple = "i686-pc-linux-gnu"
64 %struct.FRAME.c34003a = type { float, float }
75 @report_E = global i8 0 ; [#uses=0]
0 ; RUN: llvm-as < %s | llc -march=x86 | not grep jmp
1
2 %struct..0anon = type { i32 }
3 %struct.binding_level = type { %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.binding_level*, i8, i8, i8, i8, i8, i32, %struct.tree_node* }
4 %struct.lang_decl = type opaque
5 %struct.rtx_def = type { i16, i8, i8, [1 x %struct..0anon] }
6 %struct.tree_decl = type { [12 x i8], i8*, i32, %struct.tree_node*, i32, i8, i8, i8, i8, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.rtx_def*, %struct..0anon, { %struct.rtx_def* }, %struct.tree_node*, %struct.lang_decl* }
7 %struct.tree_node = type { %struct.tree_decl }
8
9 define fastcc %struct.tree_node* @pushdecl(%struct.tree_node* %x) nounwind {
10 entry:
11 %tmp3.i40 = icmp eq %struct.binding_level* null, null ; [#uses=2]
12 br i1 false, label %bb143, label %bb140
13 bb140: ; preds = %entry
14 br i1 %tmp3.i40, label %bb160, label %bb17.i
15 bb17.i: ; preds = %bb140
16 ret %struct.tree_node* null
17 bb143: ; preds = %entry
18 %tmp8.i43 = load %struct.tree_node** null, align 4 ; <%struct.tree_node*> [#uses=1]
19 br i1 %tmp3.i40, label %bb160, label %bb9.i48
20 bb9.i48: ; preds = %bb143
21 ret %struct.tree_node* null
22 bb160: ; preds = %bb143, %bb140
23 %t.0.reg2mem.0 = phi %struct.tree_node* [ null, %bb140 ], [ %tmp8.i43, %bb143 ] ; <%struct.tree_node*> [#uses=1]
24 %tmp162 = icmp eq %struct.tree_node* %t.0.reg2mem.0, null ; [#uses=2]
25 br i1 %tmp162, label %bb174, label %bb165
26 bb165: ; preds = %bb160
27 br label %bb174
28 bb174: ; preds = %bb165, %bb160
29 %line.0 = phi i32 [ 0, %bb165 ], [ undef, %bb160 ] ; [#uses=1]
30 %file.0 = phi i8* [ null, %bb165 ], [ undef, %bb160 ] ; [#uses=1]
31 br i1 %tmp162, label %bb344, label %bb73.i
32 bb73.i: ; preds = %bb174
33 br i1 false, label %bb226.i, label %bb220.i
34 bb220.i: ; preds = %bb73.i
35 ret %struct.tree_node* null
36 bb226.i: ; preds = %bb73.i
37 br i1 false, label %bb260, label %bb273.i
38 bb273.i: ; preds = %bb226.i
39 ret %struct.tree_node* null
40 bb260: ; preds = %bb226.i
41 tail call void (i8*, i32, ...)* @pedwarn_with_file_and_line( i8* %file.0, i32 %line.0, i8* null ) nounwind
42 ret %struct.tree_node* null
43 bb344: ; preds = %bb174
44 ret %struct.tree_node* null
45 }
46
47 declare void @pedwarn_with_file_and_line(i8*, i32, ...) nounwind