mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-19 20:34:38 +00:00
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
This commit is contained in:
parent
3290239daf
commit
cc359d9fa2
@ -609,8 +609,7 @@ protected:
|
||||
|
||||
const SCEVAddRecExpr *GetWideRecurrence(Instruction *NarrowUse);
|
||||
|
||||
Instruction *WidenIVUse(Instruction *NarrowUse,
|
||||
Instruction *NarrowDef,
|
||||
Instruction *WidenIVUse(Use &NarrowDefUse, Instruction *NarrowDef,
|
||||
Instruction *WideDef);
|
||||
};
|
||||
} // anonymous namespace
|
||||
@ -724,9 +723,10 @@ static bool HoistStep(Instruction *IncV, Instruction *InsertPos,
|
||||
|
||||
/// WidenIVUse - Determine whether an individual user of the narrow IV can be
|
||||
/// widened. If so, return the wide clone of the user.
|
||||
Instruction *WidenIV::WidenIVUse(Instruction *NarrowUse,
|
||||
Instruction *NarrowDef,
|
||||
Instruction *WidenIV::WidenIVUse(Use &NarrowDefUse, Instruction *NarrowDef,
|
||||
Instruction *WideDef) {
|
||||
Instruction *NarrowUse = cast<Instruction>(NarrowDefUse.getUser());
|
||||
|
||||
// To be consistent with IVUsers, stop traversing the def-use chain at
|
||||
// inner-loop phis or post-loop phis.
|
||||
if (isa<PHINode>(NarrowUse) && LI->getLoopFor(NarrowUse->getParent()) != L)
|
||||
@ -744,7 +744,7 @@ Instruction *WidenIV::WidenIVUse(Instruction *NarrowUse,
|
||||
unsigned IVWidth = SE->getTypeSizeInBits(WideType);
|
||||
if (CastWidth < IVWidth) {
|
||||
// The cast isn't as wide as the IV, so insert a Trunc.
|
||||
IRBuilder<> Builder(NarrowUse);
|
||||
IRBuilder<> Builder(NarrowDefUse);
|
||||
NewDef = Builder.CreateTrunc(WideDef, NarrowUse->getType());
|
||||
}
|
||||
else {
|
||||
@ -778,11 +778,15 @@ Instruction *WidenIV::WidenIVUse(Instruction *NarrowUse,
|
||||
// This user does not evaluate to a recurence after widening, so don't
|
||||
// follow it. Instead insert a Trunc to kill off the original use,
|
||||
// eventually isolating the original narrow IV so it can be removed.
|
||||
IRBuilder<> Builder(NarrowUse);
|
||||
IRBuilder<> Builder(NarrowDefUse);
|
||||
Value *Trunc = Builder.CreateTrunc(WideDef, NarrowDef->getType());
|
||||
NarrowUse->replaceUsesOfWith(NarrowDef, Trunc);
|
||||
return 0;
|
||||
}
|
||||
// We assume that block terminators are not SCEVable.
|
||||
assert(NarrowUse != NarrowUse->getParent()->getTerminator() &&
|
||||
"can't split terminators");
|
||||
|
||||
// Reuse the IV increment that SCEVExpander created as long as it dominates
|
||||
// NarrowUse.
|
||||
Instruction *WideUse = 0;
|
||||
@ -876,20 +880,20 @@ PHINode *WidenIV::CreateWideIV(SCEVExpander &Rewriter) {
|
||||
NarrowIVUsers.push_back(std::make_pair(&UI.getUse(), WidePhi));
|
||||
}
|
||||
while (!NarrowIVUsers.empty()) {
|
||||
Use *NarrowDefUse;
|
||||
Use *UsePtr;
|
||||
Instruction *WideDef;
|
||||
tie(NarrowDefUse, WideDef) = NarrowIVUsers.pop_back_val();
|
||||
tie(UsePtr, WideDef) = NarrowIVUsers.pop_back_val();
|
||||
Use &NarrowDefUse = *UsePtr;
|
||||
|
||||
// Process a def-use edge. This may replace the use, so don't hold a
|
||||
// use_iterator across it.
|
||||
Instruction *NarrowDef = cast<Instruction>(NarrowDefUse->get());
|
||||
Instruction *NarrowUse = cast<Instruction>(NarrowDefUse->getUser());
|
||||
Instruction *WideUse = WidenIVUse(NarrowUse, NarrowDef, WideDef);
|
||||
Instruction *NarrowDef = cast<Instruction>(NarrowDefUse.get());
|
||||
Instruction *WideUse = WidenIVUse(NarrowDefUse, NarrowDef, WideDef);
|
||||
|
||||
// Follow all def-use edges from the previous narrow use.
|
||||
if (WideUse) {
|
||||
for (Value::use_iterator UI = NarrowUse->use_begin(),
|
||||
UE = NarrowUse->use_end(); UI != UE; ++UI) {
|
||||
for (Value::use_iterator UI = NarrowDefUse.getUser()->use_begin(),
|
||||
UE = NarrowDefUse.getUser()->use_end(); UI != UE; ++UI) {
|
||||
NarrowIVUsers.push_back(std::make_pair(&UI.getUse(), WideUse));
|
||||
}
|
||||
}
|
||||
@ -1051,6 +1055,10 @@ bool IndVarSimplify::isSimpleIVUser(Instruction *I, const Loop *L) {
|
||||
// Get the symbolic expression for this instruction.
|
||||
const SCEV *S = SE->getSCEV(I);
|
||||
|
||||
// We assume that terminators are not SCEVable.
|
||||
assert((!S || I != I->getParent()->getTerminator()) &&
|
||||
"can't fold terminators");
|
||||
|
||||
// Only consider affine recurrences.
|
||||
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S);
|
||||
if (AR && AR->getLoop() == L)
|
||||
|
@ -153,8 +153,37 @@ loop:
|
||||
br i1 %cond, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
br label %return
|
||||
ret void
|
||||
}
|
||||
|
||||
return:
|
||||
define void @maxvisitor(i32 %limit, i32* %base) nounwind {
|
||||
entry: br label %loop
|
||||
|
||||
; CHECK: loop:
|
||||
; CHECK: phi i64
|
||||
; CHECK: trunc
|
||||
; CHECK: exit
|
||||
loop:
|
||||
%idx = phi i32 [ 0, %entry ], [ %idx.next, %loop.inc ]
|
||||
%max = phi i32 [ 0, %entry ], [ %max.next, %loop.inc ]
|
||||
%idxprom = sext i32 %idx to i64
|
||||
%adr = getelementptr inbounds i32* %base, i64 %idxprom
|
||||
%val = load i32* %adr
|
||||
%cmp19 = icmp sgt i32 %val, %max
|
||||
br i1 %cmp19, label %if.then, label %if.else
|
||||
|
||||
if.then:
|
||||
br label %loop.inc
|
||||
|
||||
if.else:
|
||||
br label %loop.inc
|
||||
|
||||
loop.inc:
|
||||
%max.next = phi i32 [ %idx, %if.then ], [ %max, %if.else ]
|
||||
%idx.next = add nsw i32 %idx, 1
|
||||
%cmp = icmp slt i32 %idx.next, %limit
|
||||
br i1 %cmp, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user