[llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Dec 22 13:25:28 PST 2003
Changes in directory llvm/lib/Transforms/Scalar:
IndVarSimplify.cpp updated: 1.49 -> 1.50
---
Log message:
Don't mind me, I'm just refactoring away. This patch makes room for LFTR, but
contains no functionality changes.
---
Diffs of the changes: (+128 -88)
Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.49 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.50
--- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.49 Sun Dec 21 23:02:01 2003
+++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Mon Dec 22 03:53:29 2003
@@ -52,6 +52,9 @@
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,104 +195,141 @@
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();
- 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)) {
-
- // If the types are not compatible, insert a cast now...
- 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);
+ ReplaceIndVar(*IV, IterCount);
+ Changed = true;
+ ++NumRemoved;
+ }
+ }
- Val = BinaryOperator::create(Instruction::Mul, Val, IV->Step,
- IV->Phi->getName()+"-scale", AfterPHIIt);
- }
+ return Changed;
+}
- // If this is a pointer indvar...
- if (isa<PointerType>(IV->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",
- AfterPHIIt);
-
- } 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(),
- AfterPHIIt);
-
- // Insert the instruction after the phi nodes...
- Val = BinaryOperator::create(Instruction::Add, Val, IV->Start,
- IV->Phi->getName()+"-offset", AfterPHIIt);
- }
+/// 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.
- // 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);
-
+ BasicBlock::iterator AfterPHIIt = Phi;
+ while (isa<PHINode>(AfterPHIIt)) ++AfterPHIIt;
+
+ Value *Val = CIV;
+ if (Val->getType() != IVTy)
+ Val = new CastInst(Val, IVTy, Val->getName(), 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>(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,
+ Phi->getName()+"-offset",
+ AfterPHIIt);
+
+ } 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 (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,
+ Phi->getName()+"-offset", AfterPHIIt);
+ }
+
+ // If the PHI node has a different type than val is, insert a cast now...
+ 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 = Phi->getName();
+ Phi->setName("");
+ Val->setName(OldName);
+
+ return Val;
+}
+
+
+// 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...
- IV->Phi->replaceAllUsesWith(Val);
+ if (IndVarVal == 0)
+ IndVarVal = ComputeAuxIndVarValue(IV, CIV);
+ U->replaceUsesOfWith(Phi, IndVarVal);
+ }
+ }
- // Move the PHI name to it's new equivalent value...
- std::string OldName = IV->Phi->getName();
- IV->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));
-
- // Delete the old, now unused, phi node...
- Header->getInstList().erase(IV->Phi);
-
- // If the PHI is the last user of any instructions for computing PHI nodes
- // that are irrelevant now, delete those instructions.
- while (!PHIOps.empty()) {
- Instruction *MaybeDead = dyn_cast<Instruction>(PHIOps.back());
- PHIOps.pop_back();
-
- if (MaybeDead && isInstructionTriviallyDead(MaybeDead)) {
- PHIOps.insert(PHIOps.end(), MaybeDead->op_begin(),
- MaybeDead->op_end());
- MaybeDead->getParent()->getInstList().erase(MaybeDead);
-
- // Erase any duplicates entries in the PHIOps list.
- std::vector<Value*>::iterator It =
- std::find(PHIOps.begin(), PHIOps.end(), MaybeDead);
- while (It != PHIOps.end()) {
- PHIOps.erase(It);
- It = std::find(PHIOps.begin(), PHIOps.end(), MaybeDead);
- }
-
- // Erasing the instruction could invalidate the AfterPHI iterator!
- AfterPHIIt = Header->begin();
- }
+ // If the PHI is the last user of any instructions for computing PHI nodes
+ // that are irrelevant now, delete those instructions.
+ while (!PHIOps.empty()) {
+ Instruction *MaybeDead = dyn_cast<Instruction>(PHIOps.back());
+ PHIOps.pop_back();
+
+ 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);
+
+ // Erase any duplicates entries in the PHIOps list.
+ std::vector<Value*>::iterator It =
+ std::find(PHIOps.begin(), PHIOps.end(), MaybeDead);
+ while (It != PHIOps.end()) {
+ PHIOps.erase(It);
+ It = std::find(PHIOps.begin(), PHIOps.end(), MaybeDead);
}
-
- Changed = true;
- ++NumRemoved;
}
}
- return Changed;
+ // Delete the old, now unused, phi node...
+ Phi->getParent()->getInstList().erase(Phi);
}
More information about the llvm-commits
mailing list