llvm.org GIT mirror llvm / cc359d9
indvars -disable-iv-rewrite: insert new trunc instructions carefully. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134112 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 8 years ago
2 changed file(s) with 52 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
608608
609609 const SCEVAddRecExpr *GetWideRecurrence(Instruction *NarrowUse);
610610
611 Instruction *WidenIVUse(Instruction *NarrowUse,
612 Instruction *NarrowDef,
611 Instruction *WidenIVUse(Use &NarrowDefUse, Instruction *NarrowDef,
613612 Instruction *WideDef);
614613 };
615614 } // anonymous namespace
723722
724723 /// WidenIVUse - Determine whether an individual user of the narrow IV can be
725724 /// widened. If so, return the wide clone of the user.
726 Instruction *WidenIV::WidenIVUse(Instruction *NarrowUse,
727 Instruction *NarrowDef,
725 Instruction *WidenIV::WidenIVUse(Use &NarrowDefUse, Instruction *NarrowDef,
728726 Instruction *WideDef) {
727 Instruction *NarrowUse = cast(NarrowDefUse.getUser());
728
729729 // To be consistent with IVUsers, stop traversing the def-use chain at
730730 // inner-loop phis or post-loop phis.
731731 if (isa(NarrowUse) && LI->getLoopFor(NarrowUse->getParent()) != L)
743743 unsigned IVWidth = SE->getTypeSizeInBits(WideType);
744744 if (CastWidth < IVWidth) {
745745 // The cast isn't as wide as the IV, so insert a Trunc.
746 IRBuilder<> Builder(NarrowUse);
746 IRBuilder<> Builder(NarrowDefUse);
747747 NewDef = Builder.CreateTrunc(WideDef, NarrowUse->getType());
748748 }
749749 else {
777777 // This user does not evaluate to a recurence after widening, so don't
778778 // follow it. Instead insert a Trunc to kill off the original use,
779779 // eventually isolating the original narrow IV so it can be removed.
780 IRBuilder<> Builder(NarrowUse);
780 IRBuilder<> Builder(NarrowDefUse);
781781 Value *Trunc = Builder.CreateTrunc(WideDef, NarrowDef->getType());
782782 NarrowUse->replaceUsesOfWith(NarrowDef, Trunc);
783783 return 0;
784784 }
785 // We assume that block terminators are not SCEVable.
786 assert(NarrowUse != NarrowUse->getParent()->getTerminator() &&
787 "can't split terminators");
788
785789 // Reuse the IV increment that SCEVExpander created as long as it dominates
786790 // NarrowUse.
787791 Instruction *WideUse = 0;
875879 NarrowIVUsers.push_back(std::make_pair(&UI.getUse(), WidePhi));
876880 }
877881 while (!NarrowIVUsers.empty()) {
878 Use *NarrowDefUse;
882 Use *UsePtr;
879883 Instruction *WideDef;
880 tie(NarrowDefUse, WideDef) = NarrowIVUsers.pop_back_val();
884 tie(UsePtr, WideDef) = NarrowIVUsers.pop_back_val();
885 Use &NarrowDefUse = *UsePtr;
881886
882887 // Process a def-use edge. This may replace the use, so don't hold a
883888 // use_iterator across it.
884 Instruction *NarrowDef = cast(NarrowDefUse->get());
885 Instruction *NarrowUse = cast(NarrowDefUse->getUser());
886 Instruction *WideUse = WidenIVUse(NarrowUse, NarrowDef, WideDef);
889 Instruction *NarrowDef = cast(NarrowDefUse.get());
890 Instruction *WideUse = WidenIVUse(NarrowDefUse, NarrowDef, WideDef);
887891
888892 // Follow all def-use edges from the previous narrow use.
889893 if (WideUse) {
890 for (Value::use_iterator UI = NarrowUse->use_begin(),
891 UE = NarrowUse->use_end(); UI != UE; ++UI) {
894 for (Value::use_iterator UI = NarrowDefUse.getUser()->use_begin(),
895 UE = NarrowDefUse.getUser()->use_end(); UI != UE; ++UI) {
892896 NarrowIVUsers.push_back(std::make_pair(&UI.getUse(), WideUse));
893897 }
894898 }
10491053
10501054 // Get the symbolic expression for this instruction.
10511055 const SCEV *S = SE->getSCEV(I);
1056
1057 // We assume that terminators are not SCEVable.
1058 assert((!S || I != I->getParent()->getTerminator()) &&
1059 "can't fold terminators");
10521060
10531061 // Only consider affine recurrences.
10541062 const SCEVAddRecExpr *AR = dyn_cast(S);
152152 br i1 %cond, label %loop, label %exit
153153
154154 exit:
155 br label %return
155 ret void
156 }
156157
157 return:
158 define void @maxvisitor(i32 %limit, i32* %base) nounwind {
159 entry: br label %loop
160
161 ; CHECK: loop:
162 ; CHECK: phi i64
163 ; CHECK: trunc
164 ; CHECK: exit
165 loop:
166 %idx = phi i32 [ 0, %entry ], [ %idx.next, %loop.inc ]
167 %max = phi i32 [ 0, %entry ], [ %max.next, %loop.inc ]
168 %idxprom = sext i32 %idx to i64
169 %adr = getelementptr inbounds i32* %base, i64 %idxprom
170 %val = load i32* %adr
171 %cmp19 = icmp sgt i32 %val, %max
172 br i1 %cmp19, label %if.then, label %if.else
173
174 if.then:
175 br label %loop.inc
176
177 if.else:
178 br label %loop.inc
179
180 loop.inc:
181 %max.next = phi i32 [ %idx, %if.then ], [ %max, %if.else ]
182 %idx.next = add nsw i32 %idx, 1
183 %cmp = icmp slt i32 %idx.next, %limit
184 br i1 %cmp, label %loop, label %exit
185
186 exit:
158187 ret void
159188 }