llvm.org GIT mirror llvm / 037d1c0
indvars -disable-iv-rewrite: Added SimplifyCongruentIVs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134530 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 8 years ago
3 changed file(s) with 113 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
5757 #include "llvm/Transforms/Utils/Local.h"
5858 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
5959 #include "llvm/Target/TargetData.h"
60 #include "llvm/ADT/DenseMap.h"
6061 #include "llvm/ADT/SmallVector.h"
6162 #include "llvm/ADT/Statistic.h"
6263 #include "llvm/ADT/STLExtras.h"
7172 STATISTIC(NumElimExt , "Number of IV sign/zero extends eliminated");
7273 STATISTIC(NumElimRem , "Number of IV remainder operations eliminated");
7374 STATISTIC(NumElimCmp , "Number of IV comparisons eliminated");
75 STATISTIC(NumElimIV , "Number of congruent IVs eliminated");
7476
7577 static cl::opt DisableIVRewrite(
7678 "disable-iv-rewrite", cl::Hidden,
7880
7981 namespace {
8082 class IndVarSimplify : public LoopPass {
83 typedef DenseMap ExprToIVMapTy;
84
8185 IVUsers *IU;
8286 LoopInfo *LI;
8387 ScalarEvolution *SE;
8488 DominatorTree *DT;
8589 TargetData *TD;
8690
91 ExprToIVMapTy ExprToIVMap;
8792 SmallVector DeadInsts;
8893 bool Changed;
8994 public:
113118 }
114119
115120 private:
121 virtual void releaseMemory() {
122 ExprToIVMap.clear();
123 DeadInsts.clear();
124 }
125
116126 bool isValidRewrite(Value *FromVal, Value *ToVal);
117127
118128 void SimplifyIVUsers(SCEVExpander &Rewriter);
131141 SCEVExpander &Rewriter);
132142
133143 void RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter);
144
145 void SimplifyCongruentIVs(Loop *L);
134146
135147 void RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter);
136148
11281140 // Instructions processed by SimplifyIVUsers for CurrIV.
11291141 SmallPtrSet Simplified;
11301142
1131 // Use-def pairs if IVUsers waiting to be processed for CurrIV.
1143 // Use-def pairs if IV users waiting to be processed for CurrIV.
11321144 SmallVector, 8> SimpleIVUsers;
11331145
11341146 // Push users of the current LoopPhi. In rare cases, pushIVUsers may be
11741186 }
11751187 }
11761188
1189 /// SimplifyCongruentIVs - Check for congruent phis in this loop header and
1190 /// populate ExprToIVMap for use later.
1191 ///
1192 void IndVarSimplify::SimplifyCongruentIVs(Loop *L) {
1193 for (BasicBlock::iterator I = L->getHeader()->begin(); isa(I); ++I) {
1194 PHINode *Phi = cast(I);
1195 const SCEV *S = SE->getSCEV(Phi);
1196 ExprToIVMapTy::const_iterator Pos;
1197 bool Inserted;
1198 tie(Pos, Inserted) = ExprToIVMap.insert(std::make_pair(S, Phi));
1199 if (Inserted)
1200 continue;
1201 PHINode *OrigPhi = Pos->second;
1202 // Replacing the congruent phi is sufficient because acyclic redundancy
1203 // elimination, CSE/GVN, should handle the rest. However, once SCEV proves
1204 // that a phi is congruent, it's almost certain to be the head of an IV
1205 // user cycle that is isomorphic with the original phi. So it's worth
1206 // eagerly cleaning up the common case of a single IV increment.
1207 if (BasicBlock *LatchBlock = L->getLoopLatch()) {
1208 Instruction *OrigInc =
1209 cast(OrigPhi->getIncomingValueForBlock(LatchBlock));
1210 Instruction *IsomorphicInc =
1211 cast(Phi->getIncomingValueForBlock(LatchBlock));
1212 if (OrigInc != IsomorphicInc &&
1213 SE->getSCEV(OrigInc) == SE->getSCEV(IsomorphicInc) &&
1214 HoistStep(OrigInc, IsomorphicInc, DT)) {
1215 DEBUG(dbgs() << "INDVARS: Eliminated congruent iv.inc: "
1216 << *IsomorphicInc << '\n');
1217 IsomorphicInc->replaceAllUsesWith(OrigInc);
1218 DeadInsts.push_back(IsomorphicInc);
1219 }
1220 }
1221 DEBUG(dbgs() << "INDVARS: Eliminated congruent iv: " << *Phi << '\n');
1222 ++NumElimIV;
1223 Phi->replaceAllUsesWith(OrigPhi);
1224 DeadInsts.push_back(Phi);
1225 }
1226 }
1227
11771228 bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
11781229 // If LoopSimplify form is not available, stay out of trouble. Some notes:
11791230 // - LSR currently only supports LoopSimplify-form loops. Indvars'
11931244 DT = &getAnalysis();
11941245 TD = getAnalysisIfAvailable();
11951246
1247 ExprToIVMap.clear();
11961248 DeadInsts.clear();
11971249 Changed = false;
11981250
12281280 // Eliminate redundant IV users.
12291281 if (!DisableIVRewrite)
12301282 SimplifyIVUsers(Rewriter);
1283
1284 // Eliminate redundant IV cycles and populate ExprToIVMap.
1285 // TODO: use ExprToIVMap to allow LFTR without canonical IVs
1286 if (DisableIVRewrite)
1287 SimplifyCongruentIVs(L);
12311288
12321289 // Compute the type of the largest recurrence expression, and decide whether
12331290 // a canonical induction variable should be inserted.
269269 return:
270270 ret i32 %i.0
271271 }
272
273 ; Eliminate the congruent phis j, k, and l.
274 ; Eliminate the redundant IV increments k.next and l.next.
275 ; Two phis should remain, one starting at %init, and one at %init1.
276 ; Two increments should remain, one by %step and one by %step1.
277 ; CHECK: loop:
278 ; CHECK: phi i32
279 ; CHECK: phi i32
280 ; CHECK-NOT: phi
281 ; CHECK: add i32
282 ; CHECK: add i32
283 ; CHECK-NOT: add
284 ; CHECK: return:
285 ;
286 ; Five live-outs should remain.
287 ; CHECK: lcssa = phi
288 ; CHECK: lcssa = phi
289 ; CHECK: lcssa = phi
290 ; CHECK: lcssa = phi
291 ; CHECK: lcssa = phi
292 ; CHECK-NOT: phi
293 ; CHECK: ret
294 define i32 @isomorphic(i32 %init, i32 %step, i32 %lim) nounwind {
295 entry:
296 %step1 = add i32 %step, 1
297 %init1 = add i32 %init, %step1
298 %l.0 = sub i32 %init1, %step1
299 br label %loop
300
301 loop:
302 %ii = phi i32 [ %init1, %entry ], [ %ii.next, %loop ]
303 %i = phi i32 [ %init, %entry ], [ %ii, %loop ]
304 %j = phi i32 [ %init, %entry ], [ %j.next, %loop ]
305 %k = phi i32 [ %init1, %entry ], [ %k.next, %loop ]
306 %l = phi i32 [ %l.0, %entry ], [ %l.next, %loop ]
307 %ii.next = add i32 %ii, %step1
308 %j.next = add i32 %j, %step1
309 %k.next = add i32 %k, %step1
310 %l.step = add i32 %l, %step
311 %l.next = add i32 %l.step, 1
312 %cmp = icmp ne i32 %ii.next, %lim
313 br i1 %cmp, label %loop, label %return
314
315 return:
316 %sum1 = add i32 %i, %j.next
317 %sum2 = add i32 %sum1, %k.next
318 %sum3 = add i32 %sum1, %l.step
319 %sum4 = add i32 %sum1, %l.next
320 ret i32 %sum4
321 }
None ; RUN: opt < %s -indvars -instcombine -S | \
1 ; RUN: grep {store i32 0}
0 ; RUN: opt < %s -indvars -instcombine -S | FileCheck %s
1 ; RUN: opt < %s -indvars -disable-iv-rewrite -instcombine -S | FileCheck %s
2 ;
23 ; Test that -indvars can reduce variable stride IVs. If it can reduce variable
3 ; stride iv's, it will make %iv. and %m.0.0 isomorphic to each other without
4 ; stride iv's, it will make %iv. and %m.0.0 isomorphic to each other without
45 ; cycles, allowing the tmp.21 subtraction to be eliminated.
5 ; END.
66
77 define void @vnum_test8(i32* %data) {
88 entry:
1919 %tmp.16 = getelementptr i32* %data, i32 %tmp.9 ; [#uses=1]
2020 br label %no_exit
2121
22 ; CHECK: store i32 0
2223 no_exit: ; preds = %no_exit, %no_exit.preheader
2324 %iv.ui = phi i32 [ 0, %no_exit.preheader ], [ %iv..inc.ui, %no_exit ] ; [#uses=1]
2425 %iv. = phi i32 [ %tmp.5, %no_exit.preheader ], [ %iv..inc, %no_exit ] ; [#uses=2]