mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
indvars: Added getInsertPointForUses to find a valid place to truncate the IV.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135568 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
13bcf2e68a
commit
86c98145b2
@ -216,6 +216,36 @@ bool IndVarSimplify::isValidRewrite(Value *FromVal, Value *ToVal) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determine the insertion point for this user. By default, insert immediately
|
||||||
|
/// before the user. SCEVExpander or LICM will hoist loop invariants out of the
|
||||||
|
/// loop. For PHI nodes, there may be multiple uses, so compute the nearest
|
||||||
|
/// common dominator for the incoming blocks.
|
||||||
|
static Instruction *getInsertPointForUses(Instruction *User, Value *Def,
|
||||||
|
DominatorTree *DT) {
|
||||||
|
PHINode *PHI = dyn_cast<PHINode>(User);
|
||||||
|
if (!PHI)
|
||||||
|
return User;
|
||||||
|
|
||||||
|
Instruction *InsertPt = 0;
|
||||||
|
for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) {
|
||||||
|
if (PHI->getIncomingValue(i) != Def)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BasicBlock *InsertBB = PHI->getIncomingBlock(i);
|
||||||
|
if (!InsertPt) {
|
||||||
|
InsertPt = InsertBB->getTerminator();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
InsertBB = DT->findNearestCommonDominator(InsertPt->getParent(), InsertBB);
|
||||||
|
InsertPt = InsertBB->getTerminator();
|
||||||
|
}
|
||||||
|
assert(InsertPt && "Missing phi operand");
|
||||||
|
assert(!isa<Instruction>(Def) ||
|
||||||
|
DT->dominates(cast<Instruction>(Def), InsertPt) &&
|
||||||
|
"def does not dominate all uses");
|
||||||
|
return InsertPt;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// RewriteNonIntegerIVs and helpers. Prefer integer IVs.
|
// RewriteNonIntegerIVs and helpers. Prefer integer IVs.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -697,18 +727,7 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter) {
|
|||||||
// hoist loop invariants out of the loop. For PHI nodes, there may be
|
// hoist loop invariants out of the loop. For PHI nodes, there may be
|
||||||
// multiple uses, so compute the nearest common dominator for the
|
// multiple uses, so compute the nearest common dominator for the
|
||||||
// incoming blocks.
|
// incoming blocks.
|
||||||
Instruction *InsertPt = User;
|
Instruction *InsertPt = getInsertPointForUses(User, Op, DT);
|
||||||
if (PHINode *PHI = dyn_cast<PHINode>(InsertPt))
|
|
||||||
for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
|
|
||||||
if (PHI->getIncomingValue(i) == Op) {
|
|
||||||
if (InsertPt == User)
|
|
||||||
InsertPt = PHI->getIncomingBlock(i)->getTerminator();
|
|
||||||
else
|
|
||||||
InsertPt =
|
|
||||||
DT->findNearestCommonDominator(InsertPt->getParent(),
|
|
||||||
PHI->getIncomingBlock(i))
|
|
||||||
->getTerminator();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now expand it into actual Instructions and patch it into place.
|
// Now expand it into actual Instructions and patch it into place.
|
||||||
Value *NewVal = Rewriter.expandCodeFor(AR, UseTy, InsertPt);
|
Value *NewVal = Rewriter.expandCodeFor(AR, UseTy, InsertPt);
|
||||||
@ -1023,9 +1042,7 @@ Instruction *WidenIV::WidenIVUse(NarrowIVDefUse DU) {
|
|||||||
// This user does not evaluate to a recurence after widening, so don't
|
// 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,
|
// follow it. Instead insert a Trunc to kill off the original use,
|
||||||
// eventually isolating the original narrow IV so it can be removed.
|
// eventually isolating the original narrow IV so it can be removed.
|
||||||
Use *U = std::find(DU.NarrowUse->op_begin(), DU.NarrowUse->op_end(),
|
IRBuilder<> Builder(getInsertPointForUses(DU.NarrowUse, DU.NarrowDef, DT));
|
||||||
DU.NarrowDef);
|
|
||||||
IRBuilder<> Builder(*U);
|
|
||||||
Value *Trunc = Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType());
|
Value *Trunc = Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType());
|
||||||
DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
|
DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -350,3 +350,42 @@ latch: ; preds = %for.inc50.i
|
|||||||
exit:
|
exit:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Test a widened IV that is used by a phi on different paths within the loop.
|
||||||
|
;
|
||||||
|
; CHECK: for.body:
|
||||||
|
; CHECK: phi i64
|
||||||
|
; CHECK: trunc i64
|
||||||
|
; CHECK: if.then:
|
||||||
|
; CHECK: for.inc:
|
||||||
|
; CHECK: phi i32
|
||||||
|
; CHECK: for.end:
|
||||||
|
define void @phiUsesTrunc() nounwind {
|
||||||
|
entry:
|
||||||
|
br i1 undef, label %for.body, label %for.end
|
||||||
|
|
||||||
|
for.body:
|
||||||
|
%iv = phi i32 [ %inc, %for.inc ], [ 1, %entry ]
|
||||||
|
br i1 undef, label %if.then, label %if.else
|
||||||
|
|
||||||
|
if.then:
|
||||||
|
br i1 undef, label %if.then33, label %for.inc
|
||||||
|
|
||||||
|
if.then33:
|
||||||
|
br label %for.inc
|
||||||
|
|
||||||
|
if.else:
|
||||||
|
br i1 undef, label %if.then97, label %for.inc
|
||||||
|
|
||||||
|
if.then97:
|
||||||
|
%idxprom100 = sext i32 %iv to i64
|
||||||
|
br label %for.inc
|
||||||
|
|
||||||
|
for.inc:
|
||||||
|
%kmin.1 = phi i32 [ %iv, %if.then33 ], [ 0, %if.then ], [ %iv, %if.then97 ], [ 0, %if.else ]
|
||||||
|
%inc = add nsw i32 %iv, 1
|
||||||
|
br i1 undef, label %for.body, label %for.end
|
||||||
|
|
||||||
|
for.end:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user