mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Don't mind me, I'm just refactoring away. This patch makes room for LFTR, but
contains no functionality changes. llvm-svn: 10583
This commit is contained in:
parent
b0c30fd90f
commit
8ec8b9c28a
@ -52,6 +52,9 @@ namespace {
|
||||
return TD->getTypeSize(Ty); // Must be a pointer
|
||||
}
|
||||
|
||||
Value *ComputeAuxIndVarValue(InductionVariable &IV, Value *CIV);
|
||||
void ReplaceIndVar(InductionVariable &IV, Value *Counter);
|
||||
|
||||
bool runOnLoop(Loop *L);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
@ -192,74 +195,116 @@ bool IndVarSimplify::runOnLoop(Loop *Loop) {
|
||||
|
||||
DEBUG(IV->print(std::cerr));
|
||||
|
||||
while (isa<PHINode>(AfterPHIIt)) ++AfterPHIIt;
|
||||
|
||||
// Don't modify the canonical indvar or unrecognized indvars...
|
||||
if (IV != Canonical && IV->InductionType != InductionVariable::Unknown) {
|
||||
const Type *IVTy = IV->Phi->getType();
|
||||
ReplaceIndVar(*IV, IterCount);
|
||||
Changed = true;
|
||||
++NumRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
/// ComputeAuxIndVarValue - Given an auxillary induction variable, compute and
|
||||
/// return a value which will always be equal to the induction variable PHI, but
|
||||
/// is based off of the canonical induction variable CIV.
|
||||
///
|
||||
Value *IndVarSimplify::ComputeAuxIndVarValue(InductionVariable &IV, Value *CIV){
|
||||
Instruction *Phi = IV.Phi;
|
||||
const Type *IVTy = Phi->getType();
|
||||
if (isa<PointerType>(IVTy)) // If indexing into a pointer, make the
|
||||
IVTy = TD->getIntPtrType(); // index the appropriate type.
|
||||
|
||||
Instruction *Val = IterCount;
|
||||
if (!isa<ConstantInt>(IV->Step) || // If the step != 1
|
||||
!cast<ConstantInt>(IV->Step)->equalsInt(1)) {
|
||||
BasicBlock::iterator AfterPHIIt = Phi;
|
||||
while (isa<PHINode>(AfterPHIIt)) ++AfterPHIIt;
|
||||
|
||||
// If the types are not compatible, insert a cast now...
|
||||
Value *Val = CIV;
|
||||
if (Val->getType() != IVTy)
|
||||
Val = new CastInst(Val, IVTy, Val->getName(), AfterPHIIt);
|
||||
if (IV->Step->getType() != IVTy)
|
||||
IV->Step = new CastInst(IV->Step, IVTy, IV->Step->getName(),
|
||||
AfterPHIIt);
|
||||
|
||||
Val = BinaryOperator::create(Instruction::Mul, Val, IV->Step,
|
||||
IV->Phi->getName()+"-scale", AfterPHIIt);
|
||||
if (!isa<ConstantInt>(IV.Step) || // If the step != 1
|
||||
!cast<ConstantInt>(IV.Step)->equalsInt(1)) {
|
||||
|
||||
// If the types are not compatible, insert a cast now...
|
||||
if (IV.Step->getType() != IVTy)
|
||||
IV.Step = new CastInst(IV.Step, IVTy, IV.Step->getName(), AfterPHIIt);
|
||||
|
||||
Val = BinaryOperator::create(Instruction::Mul, Val, IV.Step,
|
||||
Phi->getName()+"-scale", AfterPHIIt);
|
||||
}
|
||||
|
||||
// If this is a pointer indvar...
|
||||
if (isa<PointerType>(IV->Phi->getType())) {
|
||||
if (isa<PointerType>(Phi->getType())) {
|
||||
std::vector<Value*> Idx;
|
||||
// FIXME: this should not be needed when we fix PR82!
|
||||
if (Val->getType() != Type::LongTy)
|
||||
Val = new CastInst(Val, Type::LongTy, Val->getName(), AfterPHIIt);
|
||||
Idx.push_back(Val);
|
||||
Val = new GetElementPtrInst(IV->Start, Idx,
|
||||
IV->Phi->getName()+"-offset",
|
||||
Val = new GetElementPtrInst(IV.Start, Idx,
|
||||
Phi->getName()+"-offset",
|
||||
AfterPHIIt);
|
||||
|
||||
} else if (!isa<Constant>(IV->Start) || // If Start != 0...
|
||||
!cast<Constant>(IV->Start)->isNullValue()) {
|
||||
} else if (!isa<Constant>(IV.Start) || // If Start != 0...
|
||||
!cast<Constant>(IV.Start)->isNullValue()) {
|
||||
// If the types are not compatible, insert a cast now...
|
||||
if (Val->getType() != IVTy)
|
||||
Val = new CastInst(Val, IVTy, Val->getName(), AfterPHIIt);
|
||||
if (IV->Start->getType() != IVTy)
|
||||
IV->Start = new CastInst(IV->Start, IVTy, IV->Start->getName(),
|
||||
if (IV.Start->getType() != IVTy)
|
||||
IV.Start = new CastInst(IV.Start, IVTy, IV.Start->getName(),
|
||||
AfterPHIIt);
|
||||
|
||||
// Insert the instruction after the phi nodes...
|
||||
Val = BinaryOperator::create(Instruction::Add, Val, IV->Start,
|
||||
IV->Phi->getName()+"-offset", AfterPHIIt);
|
||||
Val = BinaryOperator::create(Instruction::Add, Val, IV.Start,
|
||||
Phi->getName()+"-offset", AfterPHIIt);
|
||||
}
|
||||
|
||||
// If the PHI node has a different type than val is, insert a cast now...
|
||||
if (Val->getType() != IV->Phi->getType())
|
||||
Val = new CastInst(Val, IV->Phi->getType(), Val->getName(), AfterPHIIt);
|
||||
|
||||
// Replace all uses of the old PHI node with the new computed value...
|
||||
IV->Phi->replaceAllUsesWith(Val);
|
||||
if (Val->getType() != Phi->getType())
|
||||
Val = new CastInst(Val, Phi->getType(), Val->getName(), AfterPHIIt);
|
||||
|
||||
// Move the PHI name to it's new equivalent value...
|
||||
std::string OldName = IV->Phi->getName();
|
||||
IV->Phi->setName("");
|
||||
std::string OldName = Phi->getName();
|
||||
Phi->setName("");
|
||||
Val->setName(OldName);
|
||||
|
||||
// Get the incoming values used by the PHI node
|
||||
std::vector<Value*> PHIOps;
|
||||
PHIOps.reserve(IV->Phi->getNumIncomingValues());
|
||||
for (unsigned i = 0, e = IV->Phi->getNumIncomingValues(); i != e; ++i)
|
||||
PHIOps.push_back(IV->Phi->getIncomingValue(i));
|
||||
return Val;
|
||||
}
|
||||
|
||||
// Delete the old, now unused, phi node...
|
||||
Header->getInstList().erase(IV->Phi);
|
||||
|
||||
// ReplaceIndVar - Replace all uses of the specified induction variable with
|
||||
// expressions computed from the specified loop iteration counter variable.
|
||||
// Return true if instructions were deleted.
|
||||
void IndVarSimplify::ReplaceIndVar(InductionVariable &IV, Value *CIV) {
|
||||
Value *IndVarVal = 0;
|
||||
PHINode *Phi = IV.Phi;
|
||||
|
||||
assert(Phi->getNumOperands() == 4 &&
|
||||
"Only expect induction variables in canonical loops!");
|
||||
|
||||
// Remember the incoming values used by the PHI node
|
||||
std::vector<Value*> PHIOps;
|
||||
PHIOps.reserve(2);
|
||||
PHIOps.push_back(Phi->getIncomingValue(0));
|
||||
PHIOps.push_back(Phi->getIncomingValue(1));
|
||||
|
||||
// Delete all of the operands of the PHI node... FIXME, this should be more
|
||||
// intelligent.
|
||||
Phi->dropAllReferences();
|
||||
|
||||
// Now that we are rid of unneeded uses of the PHI node, replace any remaining
|
||||
// ones with the appropriate code using the canonical induction variable.
|
||||
while (!Phi->use_empty()) {
|
||||
Instruction *U = cast<Instruction>(Phi->use_back());
|
||||
|
||||
// TODO: Perform LFTR here if possible
|
||||
if (0) {
|
||||
|
||||
} else {
|
||||
// Replace all uses of the old PHI node with the new computed value...
|
||||
if (IndVarVal == 0)
|
||||
IndVarVal = ComputeAuxIndVarValue(IV, CIV);
|
||||
U->replaceUsesOfWith(Phi, IndVarVal);
|
||||
}
|
||||
}
|
||||
|
||||
// If the PHI is the last user of any instructions for computing PHI nodes
|
||||
// that are irrelevant now, delete those instructions.
|
||||
@ -267,7 +312,9 @@ bool IndVarSimplify::runOnLoop(Loop *Loop) {
|
||||
Instruction *MaybeDead = dyn_cast<Instruction>(PHIOps.back());
|
||||
PHIOps.pop_back();
|
||||
|
||||
if (MaybeDead && isInstructionTriviallyDead(MaybeDead)) {
|
||||
if (MaybeDead && isInstructionTriviallyDead(MaybeDead) &&
|
||||
(!isa<PHINode>(MaybeDead) ||
|
||||
MaybeDead->getParent() != Phi->getParent())) {
|
||||
PHIOps.insert(PHIOps.end(), MaybeDead->op_begin(),
|
||||
MaybeDead->op_end());
|
||||
MaybeDead->getParent()->getInstList().erase(MaybeDead);
|
||||
@ -279,17 +326,10 @@ bool IndVarSimplify::runOnLoop(Loop *Loop) {
|
||||
PHIOps.erase(It);
|
||||
It = std::find(PHIOps.begin(), PHIOps.end(), MaybeDead);
|
||||
}
|
||||
|
||||
// Erasing the instruction could invalidate the AfterPHI iterator!
|
||||
AfterPHIIt = Header->begin();
|
||||
}
|
||||
}
|
||||
|
||||
Changed = true;
|
||||
++NumRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
return Changed;
|
||||
// Delete the old, now unused, phi node...
|
||||
Phi->getParent()->getInstList().erase(Phi);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user