llvm.org GIT mirror llvm / 7479130
Do not remove implicit defs in BranchFolder Branch folder removes implicit defs if they are the only non-branching instructions in a block, and the branches do not use the defined registers. The problem is that in some cases these implicit defs are required for the liveness information to be correct. Differential Revision: https://reviews.llvm.org/D25478 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284036 91177308-0d34-0410-b5e6-96231b3b80d8 Krzysztof Parzyszek 3 years ago
4 changed file(s) with 30 addition(s) and 55 deletion(s). Raw diff Collapse all Expand all
144144 MLI->removeBlock(MBB);
145145 }
146146
147 /// OptimizeImpDefsBlock - If a basic block is just a bunch of implicit_def
148 /// followed by terminators, and if the implicitly defined registers are not
149 /// used by the terminators, remove those implicit_def's. e.g.
150 /// BB1:
151 /// r0 = implicit_def
152 /// r1 = implicit_def
153 /// br
154 /// This block can be optimized away later if the implicit instructions are
155 /// removed.
156 bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) {
157 SmallSet ImpDefRegs;
158 MachineBasicBlock::iterator I = MBB->begin();
159 while (I != MBB->end()) {
160 if (!I->isImplicitDef())
161 break;
162 unsigned Reg = I->getOperand(0).getReg();
163 if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
164 for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
165 SubRegs.isValid(); ++SubRegs)
166 ImpDefRegs.insert(*SubRegs);
167 } else {
168 ImpDefRegs.insert(Reg);
169 }
170 ++I;
171 }
172 if (ImpDefRegs.empty())
173 return false;
174
175 MachineBasicBlock::iterator FirstTerm = I;
176 while (I != MBB->end()) {
177 if (!TII->isUnpredicatedTerminator(*I))
178 return false;
179 // See if it uses any of the implicitly defined registers.
180 for (const MachineOperand &MO : I->operands()) {
181 if (!MO.isReg() || !MO.isUse())
182 continue;
183 unsigned Reg = MO.getReg();
184 if (ImpDefRegs.count(Reg))
185 return false;
186 }
187 ++I;
188 }
189
190 I = MBB->begin();
191 while (I != FirstTerm) {
192 MachineInstr *ImpDefMI = &*I;
193 ++I;
194 MBB->erase(ImpDefMI);
195 }
196
197 return true;
198 }
199
200147 /// OptimizeFunction - Perhaps branch folding, tail merging and other
201148 /// CFG optimizations on the given function. Block placement changes the layout
202149 /// and may create new tail merging opportunities.
227174 SmallVector Cond;
228175 if (!TII->analyzeBranch(MBB, TBB, FBB, Cond, true))
229176 MadeChange |= MBB.CorrectExtraCFGEdges(TBB, FBB, !Cond.empty());
230 MadeChange |= OptimizeImpDefsBlock(&MBB);
231177 }
232178
233179 // Recalculate funclet membership.
155155 bool OptimizeBranches(MachineFunction &MF);
156156 bool OptimizeBlock(MachineBasicBlock *MBB);
157157 void RemoveDeadBlock(MachineBasicBlock *MBB);
158 bool OptimizeImpDefsBlock(MachineBasicBlock *MBB);
159158
160159 bool HoistCommonCode(MachineFunction &MF);
161160 bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB);
0 ; RUN: llc -march=hexagon -verify-machineinstrs < %s | FileCheck %s
1 ;
2 ; Check that the testcase compiles successfully. Expect that if-conversion
3 ; took place.
4 ; CHECK-LABEL: fred:
5 ; CHECK: if (!p0) r1 = memw(r0 + #0)
6
7 target triple = "hexagon"
8
9 define void @fred(i32 %p0) local_unnamed_addr align 2 {
10 b0:
11 br i1 undef, label %b1, label %b2
12
13 b1: ; preds = %b0
14 %t0 = load i8*, i8** undef, align 4
15 br label %b2
16
17 b2: ; preds = %b1, %b0
18 %t1 = phi i8* [ %t0, %b1 ], [ undef, %b0 ]
19 %t2 = getelementptr inbounds i8, i8* %t1, i32 %p0
20 tail call void @llvm.memmove.p0i8.p0i8.i32(i8* undef, i8* %t2, i32 undef, i32 1, i1 false) #1
21 unreachable
22 }
23
24 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #0
25
26 attributes #0 = { argmemonly nounwind }
27 attributes #1 = { nounwind }
28
9999 ; CHECK-NEXT: in Loop: Header
100100 ; CHECK-NEXT: incq
101101 ; CHECK-NEXT: %for.body3.us.i
102 ; CHECK-NEXT: Parent Loop
102103 ; CHECK-NEXT: Inner Loop
103104 ; CHECK: testb
104105 ; CHECK: je