mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-27 12:26:08 +00:00
At end of LSR, replace uses of now constant (as result of SplitCriticalEdge) PHI node with the constant value.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43533 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -228,6 +228,21 @@ DeleteTriviallyDeadInstructions(SmallPtrSet<Instruction*,16> &Insts) {
|
|||||||
while (!Insts.empty()) {
|
while (!Insts.empty()) {
|
||||||
Instruction *I = *Insts.begin();
|
Instruction *I = *Insts.begin();
|
||||||
Insts.erase(I);
|
Insts.erase(I);
|
||||||
|
|
||||||
|
if (PHINode *PN = dyn_cast<PHINode>(I)) {
|
||||||
|
// If all incoming values to the Phi are the same, we can replace the Phi
|
||||||
|
// with that value.
|
||||||
|
if (Value *PNV = PN->hasConstantValue()) {
|
||||||
|
if (Instruction *U = dyn_cast<Instruction>(PNV))
|
||||||
|
Insts.insert(U);
|
||||||
|
PN->replaceAllUsesWith(PNV);
|
||||||
|
SE->deleteValueFromRecords(PN);
|
||||||
|
PN->eraseFromParent();
|
||||||
|
Changed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isInstructionTriviallyDead(I)) {
|
if (isInstructionTriviallyDead(I)) {
|
||||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
||||||
if (Instruction *U = dyn_cast<Instruction>(I->getOperand(i)))
|
if (Instruction *U = dyn_cast<Instruction>(I->getOperand(i)))
|
||||||
@@ -359,7 +374,8 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L,
|
|||||||
/// the loop, resulting in reg-reg copies (if we use the pre-inc value when we
|
/// the loop, resulting in reg-reg copies (if we use the pre-inc value when we
|
||||||
/// should use the post-inc value).
|
/// should use the post-inc value).
|
||||||
static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV,
|
static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV,
|
||||||
Loop *L, DominatorTree *DT, Pass *P) {
|
Loop *L, DominatorTree *DT, Pass *P,
|
||||||
|
SmallPtrSet<Instruction*,16> &DeadInsts){
|
||||||
// If the user is in the loop, use the preinc value.
|
// If the user is in the loop, use the preinc value.
|
||||||
if (L->contains(User->getParent())) return false;
|
if (L->contains(User->getParent())) return false;
|
||||||
|
|
||||||
@@ -399,6 +415,9 @@ static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV,
|
|||||||
e = PN->getNumIncomingValues();
|
e = PN->getNumIncomingValues();
|
||||||
if (--NumUses == 0) break;
|
if (--NumUses == 0) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PHI node might have become a constant value after SplitCriticalEdge.
|
||||||
|
DeadInsts.insert(User);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -461,7 +480,7 @@ bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L,
|
|||||||
// Okay, we found a user that we cannot reduce. Analyze the instruction
|
// Okay, we found a user that we cannot reduce. Analyze the instruction
|
||||||
// and decide what to do with it. If we are a use inside of the loop, use
|
// and decide what to do with it. If we are a use inside of the loop, use
|
||||||
// the value before incrementation, otherwise use it after incrementation.
|
// the value before incrementation, otherwise use it after incrementation.
|
||||||
if (IVUseShouldUsePostIncValue(User, I, L, DT, this)) {
|
if (IVUseShouldUsePostIncValue(User, I, L, DT, this, DeadInsts)) {
|
||||||
// The value used will be incremented by the stride more than we are
|
// The value used will be incremented by the stride more than we are
|
||||||
// expecting, so subtract this off.
|
// expecting, so subtract this off.
|
||||||
SCEVHandle NewStart = SE->getMinusSCEV(Start, Stride);
|
SCEVHandle NewStart = SE->getMinusSCEV(Start, Stride);
|
||||||
@@ -522,8 +541,8 @@ namespace {
|
|||||||
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
|
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
|
||||||
// to it.
|
// to it.
|
||||||
void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
||||||
SCEVExpander &Rewriter, Loop *L,
|
SCEVExpander &Rewriter, Loop *L, Pass *P,
|
||||||
Pass *P);
|
SmallPtrSet<Instruction*,16> &DeadInsts);
|
||||||
|
|
||||||
Value *InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
Value *InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
||||||
SCEVExpander &Rewriter,
|
SCEVExpander &Rewriter,
|
||||||
@@ -584,8 +603,8 @@ Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
|||||||
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
|
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
|
||||||
// to it.
|
// to it.
|
||||||
void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
||||||
SCEVExpander &Rewriter,
|
SCEVExpander &Rewriter, Loop *L, Pass *P,
|
||||||
Loop *L, Pass *P) {
|
SmallPtrSet<Instruction*,16> &DeadInsts) {
|
||||||
if (!isa<PHINode>(Inst)) {
|
if (!isa<PHINode>(Inst)) {
|
||||||
// By default, insert code at the user instruction.
|
// By default, insert code at the user instruction.
|
||||||
BasicBlock::iterator InsertPt = Inst;
|
BasicBlock::iterator InsertPt = Inst;
|
||||||
@@ -676,6 +695,10 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
|||||||
Rewriter.clear();
|
Rewriter.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PHI node might have become a constant value after SplitCriticalEdge.
|
||||||
|
DeadInsts.insert(Inst);
|
||||||
|
|
||||||
DOUT << " CHANGED: IMM =" << *Imm << " Inst = " << *Inst;
|
DOUT << " CHANGED: IMM =" << *Imm << " Inst = " << *Inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1373,7 +1396,8 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|||||||
// Add BaseV to the PHI value if needed.
|
// Add BaseV to the PHI value if needed.
|
||||||
RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV));
|
RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV));
|
||||||
|
|
||||||
User.RewriteInstructionToUseNewBase(RewriteExpr, Rewriter, L, this);
|
User.RewriteInstructionToUseNewBase(RewriteExpr, Rewriter, L, this,
|
||||||
|
DeadInsts);
|
||||||
|
|
||||||
// Mark old value we replaced as possibly dead, so that it is elminated
|
// Mark old value we replaced as possibly dead, so that it is elminated
|
||||||
// if we just replaced the last use of that value.
|
// if we just replaced the last use of that value.
|
||||||
@@ -1457,7 +1481,7 @@ namespace {
|
|||||||
/// v1 = v1 + 3
|
/// v1 = v1 + 3
|
||||||
/// if (v1 < 30) goto loop
|
/// if (v1 < 30) goto loop
|
||||||
ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
||||||
IVStrideUse* &CondUse,
|
IVStrideUse* &CondUse,
|
||||||
const SCEVHandle* &CondStride) {
|
const SCEVHandle* &CondStride) {
|
||||||
if (StrideOrder.size() < 2 ||
|
if (StrideOrder.size() < 2 ||
|
||||||
IVUsesByStride[*CondStride].Users.size() != 1)
|
IVUsesByStride[*CondStride].Users.size() != 1)
|
||||||
@@ -1734,7 +1758,7 @@ bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|||||||
PHINode *PN;
|
PHINode *PN;
|
||||||
while ((PN = dyn_cast<PHINode>(I))) {
|
while ((PN = dyn_cast<PHINode>(I))) {
|
||||||
++I; // Preincrement iterator to avoid invalidating it when deleting PN.
|
++I; // Preincrement iterator to avoid invalidating it when deleting PN.
|
||||||
|
|
||||||
// At this point, we know that we have killed one or more GEP
|
// At this point, we know that we have killed one or more GEP
|
||||||
// instructions. It is worth checking to see if the cann indvar is also
|
// instructions. It is worth checking to see if the cann indvar is also
|
||||||
// dead, so that we can remove it as well. The requirements for the cann
|
// dead, so that we can remove it as well. The requirements for the cann
|
||||||
|
Reference in New Issue
Block a user