"clang/git@repo.hca.bsc.es:rferrer/llvm-epi-0.8.git" did not exist on "fbe2272fc898aaeb6b6871aad2f761e7b8d4636e"
Newer
Older
//===- IndVarSimplify.cpp - Induction Variable Elimination ----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Guarantees that all loops with identifiable, linear, induction variables will
// be transformed to have a single, canonical, induction variable. After this
// pass runs, it guarantees the the first PHI node of the header block in the
// loop is the canonical induction variable if there is one.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar.h"
#include "llvm/Constants.h"
#include "llvm/Type.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/InductionVariable.h"
#include "llvm/Analysis/LoopInfo.h"
Chris Lattner
committed
#include "llvm/Support/CFG.h"
#include "llvm/Transforms/Utils/Local.h"
#include "Support/Statistic.h"
using namespace llvm;
Statistic<> NumRemoved ("indvars", "Number of aux indvars removed");
Statistic<> NumInserted("indvars", "Number of canonical indvars added");
class IndVarSimplify : public FunctionPass {
LoopInfo *Loops;
TargetData *TD;
public:
virtual bool runOnFunction(Function &) {
Loops = &getAnalysis<LoopInfo>();
TD = &getAnalysis<TargetData>();
// Induction Variables live in the header nodes of loops
bool Changed = false;
for (unsigned i = 0, e = Loops->getTopLevelLoops().size(); i != e; ++i)
Changed |= runOnLoop(Loops->getTopLevelLoops()[i]);
return Changed;
}
unsigned getTypeSize(const Type *Ty) {
if (unsigned Size = Ty->getPrimitiveSize())
return Size;
return TD->getTypeSize(Ty); // Must be a pointer
}
Chris Lattner
committed
Value *ComputeAuxIndVarValue(InductionVariable &IV, Value *CIV);
void ReplaceIndVar(InductionVariable &IV, Value *Counter);
bool runOnLoop(Loop *L);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetData>(); // Need pointer size
AU.addRequired<LoopInfo>();
AU.addRequiredID(LoopSimplifyID);
AU.addPreservedID(LoopSimplifyID);
AU.setPreservesCFG();
}
};
RegisterOpt<IndVarSimplify> X("indvars", "Canonicalize Induction Variables");
Pass *llvm::createIndVarSimplifyPass() {
return new IndVarSimplify();
// Transform all subloops before this loop...
bool Changed = false;
for (unsigned i = 0, e = Loop->getSubLoops().size(); i != e; ++i)
Changed |= runOnLoop(Loop->getSubLoops()[i]);
// Get the header node for this loop. All of the phi nodes that could be
// induction variables must live in this basic block.
//
BasicBlock *Header = Loop->getHeader();
// Loop over all of the PHI nodes in the basic block, calculating the
// induction variables that they represent... stuffing the induction variable
// info into a vector...
//
std::vector<InductionVariable> IndVars; // Induction variables for block
for (; PHINode *PN = dyn_cast<PHINode>(AfterPHIIt); ++AfterPHIIt)
IndVars.push_back(InductionVariable(PN, Loops));
// If there are no phi nodes in this basic block, there can't be indvars...
// Loop over the induction variables, looking for a canonical induction
// variable, and checking to make sure they are not all unknown induction
// variables. Keep track of the largest integer size of the induction
// variable.
InductionVariable *Canonical = 0;
unsigned MaxSize = 0;
for (unsigned i = 0; i != IndVars.size(); ++i) {
InductionVariable &IV = IndVars[i];
if (IV.InductionType != InductionVariable::Unknown) {
unsigned IVSize = getTypeSize(IV.Phi->getType());
if (IV.InductionType == InductionVariable::Canonical &&
!isa<PointerType>(IV.Phi->getType()) && IVSize >= MaxSize)
Canonical = &IV;
if (IVSize > MaxSize) MaxSize = IVSize;
// If this variable is larger than the currently identified canonical
// indvar, the canonical indvar is not usable.
if (Canonical && IVSize > getTypeSize(Canonical->Phi->getType()))
Canonical = 0;
}
// No induction variables, bail early... don't add a canonical indvar
// Okay, we want to convert other induction variables to use a canonical
// indvar. If we don't have one, add one now...
if (!Canonical) {
Chris Lattner
committed
// Create the PHI node for the new induction variable, and insert the phi
// node at the start of the PHI nodes...
const Type *IVType;
switch (MaxSize) {
default: assert(0 && "Unknown integer type size!");
case 1: IVType = Type::UByteTy; break;
case 2: IVType = Type::UShortTy; break;
case 4: IVType = Type::UIntTy; break;
case 8: IVType = Type::ULongTy; break;
}
PHINode *PN = new PHINode(IVType, "cann-indvar", Header->begin());
// Create the increment instruction to add one to the counter...
Instruction *Add = BinaryOperator::create(Instruction::Add, PN,
// Figure out which block is incoming and which is the backedge for the loop
BasicBlock *Incoming, *BackEdgeBlock;
Chris Lattner
committed
pred_iterator PI = pred_begin(Header);
assert(PI != pred_end(Header) && "Loop headers should have 2 preds!");
if (Loop->contains(*PI)) { // First pred is back edge...
BackEdgeBlock = *PI++;
Incoming = *PI++;
} else {
Incoming = *PI++;
BackEdgeBlock = *PI++;
}
Chris Lattner
committed
assert(PI == pred_end(Header) && "Loop headers should have 2 preds!");
// Add incoming values for the PHI node...
PN->addIncoming(Add, BackEdgeBlock);
// Analyze the new induction variable...
IndVars.push_back(InductionVariable(PN, Loops));
assert(IndVars.back().InductionType == InductionVariable::Canonical &&
"Just inserted canonical indvar that is not canonical!");
Canonical = &IndVars.back();
++NumInserted;
} else {
// If we have a canonical induction variable, make sure that it is the first
// one in the basic block.
if (&Header->front() != Canonical->Phi)
Header->getInstList().splice(Header->begin(), Header->getInstList(),
Canonical->Phi);
DEBUG(std::cerr << "Induction variables:\n");
// Get the current loop iteration count, which is always the value of the
// canonical phi node...
PHINode *IterCount = Canonical->Phi;
// Loop through and replace all of the auxiliary induction variables with
// references to the canonical induction variable...
InductionVariable *IV = &IndVars[i];
Chris Lattner
committed
Chris Lattner
committed
DEBUG(IV->print(std::cerr));
Chris Lattner
committed
// Don't modify the canonical indvar or unrecognized indvars...
if (IV != Canonical && IV->InductionType != InductionVariable::Unknown) {
Chris Lattner
committed
ReplaceIndVar(*IV, IterCount);
Changed = true;
++NumRemoved;
}
}
Chris Lattner
committed
return Changed;
}
Chris Lattner
committed
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/// 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.
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...
Chris Lattner
committed
if (IndVarVal == 0)
IndVarVal = ComputeAuxIndVarValue(IV, CIV);
U->replaceUsesOfWith(Phi, IndVarVal);
}
}
Chris Lattner
committed
// 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);
}
Chris Lattner
committed
// Delete the old, now unused, phi node...
Phi->getParent()->getInstList().erase(Phi);