Newer
Older
//===- LoopStrengthReduce.cpp - Strength Reduce GEPs in Loops -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Nate Begeman and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass performs a strength reduction on array references inside loops that
// have as one or more of their components the loop induction variable. This is
// accomplished by creating a new Value to hold the initial value of the array
// access for the first iteration, and then creating a new GEP instruction in
// the loop to increment the value by the appropriate amount.
//
// There are currently several deficiencies in the implementation, marked with
// FIXME in the code.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Type.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Support/CFG.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/Statistic.h"
#include <set>
using namespace llvm;
namespace {
Statistic<> NumReduced ("loop-reduce", "Number of GEPs strength reduced");
Jeff Cohen
committed
class GEPCache
{
public:
GEPCache() : CachedPHINode(0), Map() {}
GEPCache* operator[](Value *v) {
std::map<Value *, GEPCache>::iterator I = Map.find(v);
if (I == Map.end())
I = Map.insert(std::pair<Value *, GEPCache>(v, GEPCache())).first;
return &(I->second);
}
PHINode *CachedPHINode;
std::map<Value *, GEPCache> Map;
};
class LoopStrengthReduce : public FunctionPass {
LoopInfo *LI;
DominatorSet *DS;
bool Changed;
unsigned MaxTargetAMSize;
public:
LoopStrengthReduce(unsigned MTAMS = 1)
: MaxTargetAMSize(MTAMS) {
}
virtual bool runOnFunction(Function &) {
LI = &getAnalysis<LoopInfo>();
DS = &getAnalysis<DominatorSet>();
Changed = false;
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
runOnLoop(*I);
return Changed;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
Jeff Cohen
committed
AU.addRequiredID(LoopSimplifyID);
AU.addRequired<LoopInfo>();
AU.addRequired<DominatorSet>();
AU.addRequired<TargetData>();
}
private:
void runOnLoop(Loop *L);
void strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
Jeff Cohen
committed
GEPCache* GEPCache,
Instruction *InsertBefore,
std::set<Instruction*> &DeadInsts);
void DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts);
};
RegisterOpt<LoopStrengthReduce> X("loop-reduce",
"Strength Reduce GEP Uses of Ind. Vars");
}
FunctionPass *llvm::createLoopStrengthReducePass(unsigned MaxTargetAMSize) {
return new LoopStrengthReduce(MaxTargetAMSize);
}
/// DeleteTriviallyDeadInstructions - If any of the instructions is the
/// specified set are trivially dead, delete them and see if this makes any of
/// their operands subsequently dead.
void LoopStrengthReduce::
DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts) {
while (!Insts.empty()) {
Instruction *I = *Insts.begin();
Insts.erase(Insts.begin());
if (isInstructionTriviallyDead(I)) {
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
if (Instruction *U = dyn_cast<Instruction>(I->getOperand(i)))
Insts.insert(U);
I->getParent()->getInstList().erase(I);
Changed = true;
}
}
}
void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
Jeff Cohen
committed
GEPCache *Cache,
Instruction *InsertBefore,
std::set<Instruction*> &DeadInsts) {
// We will strength reduce the GEP by splitting it into two parts. The first
// is a GEP to hold the initial value of the non-strength-reduced GEP upon
// entering the loop, which we will insert at the end of the loop preheader.
// The second is a GEP to hold the incremented value of the initial GEP.
// The LoopIndVarSimplify pass guarantees that loop counts start at zero, so
// we will replace the indvar with a constant zero value to create the first
// GEP.
//
// We currently only handle GEP instructions that consist of zero or more
// constants or loop invariable expressions prior to an instance of the
// canonical induction variable.
Jeff Cohen
committed
unsigned indvar = 0;
std::vector<Value *> pre_op_vector;
std::vector<Value *> inc_op_vector;
const Type *ty = GEPI->getOperand(0)->getType();
Value *CanonicalIndVar = L->getCanonicalInductionVariable();
Jeff Cohen
committed
BasicBlock *Header = L->getHeader();
BasicBlock *Preheader = L->getLoopPreheader();
bool AllConstantOperands = true;
Jeff Cohen
committed
Cache = (*Cache)[GEPI->getOperand(0)];
Jeff Cohen
committed
for (unsigned op = 1, e = GEPI->getNumOperands(); op != e; ++op) {
Value *operand = GEPI->getOperand(op);
if (ty->getTypeID() == Type::StructTyID) {
assert(isa<ConstantUInt>(operand));
ConstantUInt *c = dyn_cast<ConstantUInt>(operand);
ty = ty->getContainedType(unsigned(c->getValue()));
} else {
ty = ty->getContainedType(0);
}
if (operand == CanonicalIndVar) {
// FIXME: use getCanonicalInductionVariableIncrement to choose between
// one and neg one maybe? We need to support int *foo = GEP base, -1
const Type *Ty = CanonicalIndVar->getType();
pre_op_vector.push_back(Constant::getNullValue(Ty));
inc_op_vector.push_back(ConstantInt::get(Ty, 1));
Jeff Cohen
committed
indvar = op;
break;
} else if (isa<Constant>(operand)) {
pre_op_vector.push_back(operand);
Jeff Cohen
committed
} else if (Instruction *inst = dyn_cast<Instruction>(operand)) {
if (!DS->dominates(inst, Preheader->getTerminator()))
Jeff Cohen
committed
return;
pre_op_vector.push_back(operand);
} else
return;
Jeff Cohen
committed
Cache = (*Cache)[operand];
}
Jeff Cohen
committed
assert(indvar > 0 && "Indvar used by GEP not found in operand list");
Jeff Cohen
committed
// Ensure the pointer base is loop invariant. While strength reduction
// makes sense even if the pointer changed on every iteration, there is no
// realistic way of handling it unless GEPs were completely decomposed into
// their constituent operations so we have explicit multiplications to work
// with.
if (Instruction *GepPtrOp = dyn_cast<Instruction>(GEPI->getOperand(0)))
if (!DS->dominates(GepPtrOp, Preheader->getTerminator()))
return;
Jeff Cohen
committed
// Don't reduce multiplies that the target can handle via addressing modes.
uint64_t sz = getAnalysis<TargetData>().getTypeSize(ty);
for (unsigned i = 1; i <= MaxTargetAMSize; i *= 2)
if (i == sz)
return;
// If all operands of the GEP we are going to insert into the preheader
// are constants, generate a GEP ConstantExpr instead.
//
// If there is only one operand after the initial non-constant one, we know
// that it was the induction variable, and has been replaced by a constant
// null value. In this case, replace the GEP with a use of pointer directly.
Jeff Cohen
committed
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
PHINode *NewPHI;
if (1) {
Value *PreGEP;
if (AllConstantOperands && isa<Constant>(GEPI->getOperand(0))) {
Constant *C = dyn_cast<Constant>(GEPI->getOperand(0));
PreGEP = ConstantExpr::getGetElementPtr(C, pre_op_vector);
} else if (pre_op_vector.size() == 1) {
PreGEP = GEPI->getOperand(0);
} else {
PreGEP = new GetElementPtrInst(GEPI->getOperand(0),
pre_op_vector, GEPI->getName()+".pre",
Preheader->getTerminator());
}
// The next step of the strength reduction is to create a PHI that will choose
// between the initial GEP we created and inserted into the preheader, and
// the incremented GEP that we will create below and insert into the loop body
NewPHI = new PHINode(PreGEP->getType(),
GEPI->getName()+".str", InsertBefore);
NewPHI->addIncoming(PreGEP, Preheader);
// Now, create the GEP instruction to increment by one the value selected by
// the PHI instruction we just created above, and add it as the second
// incoming Value/BasicBlock pair to the PHINode. It is inserted before the
// increment of the canonical induction variable.
Instruction *IncrInst =
const_cast<Instruction*>(L->getCanonicalInductionVariableIncrement());
GetElementPtrInst *StrGEP = new GetElementPtrInst(NewPHI, inc_op_vector,
GEPI->getName()+".inc",
IncrInst);
pred_iterator PI = pred_begin(Header);
if (*PI == Preheader)
++PI;
NewPHI->addIncoming(StrGEP, *PI);
Cache->CachedPHINode = NewPHI;
} else {
Jeff Cohen
committed
// Reuse previously created pointer, as it is identical to the one we were
// about to create.
NewPHI = Cache->CachedPHINode;
}
Jeff Cohen
committed
if (GEPI->getNumOperands() - 1 == indvar) {
// If there were no operands following the induction variable, replace all
// uses of the old GEP instruction with the new PHI.
GEPI->replaceAllUsesWith(NewPHI);
} else {
// Create a new GEP instruction using the new PHI as the base. The
// operands of the original GEP past the induction variable become
// operands of this new GEP.
std::vector<Value *> op_vector;
const Type *Ty = CanonicalIndVar->getType();
op_vector.push_back(Constant::getNullValue(Ty));
for (unsigned op = indvar + 1; op < GEPI->getNumOperands(); op++)
op_vector.push_back(GEPI->getOperand(op));
GetElementPtrInst *newGEP = new GetElementPtrInst(NewPHI, op_vector,
GEPI->getName() + ".lsr",
GEPI);
GEPI->replaceAllUsesWith(newGEP);
}
// The old GEP is now dead.
DeadInsts.insert(GEPI);
++NumReduced;
}
void LoopStrengthReduce::runOnLoop(Loop *L) {
// First step, transform all loops nesting inside of this loop.
for (LoopInfo::iterator I = L->begin(), E = L->end(); I != E; ++I)
runOnLoop(*I);
// Next, get the first PHINode since it is guaranteed to be the canonical
// induction variable for the loop by the preceding IndVarSimplify pass.
PHINode *PN = L->getCanonicalInductionVariable();
if (0 == PN)
return;
// FIXME: Need to use SCEV to detect GEP uses of the indvar, since indvars
// pass creates code like this, which we can't currently detect:
// %tmp.1 = sub uint 2000, %indvar
// %tmp.8 = getelementptr int* %y, uint %tmp.1
// Strength reduce all GEPs in the Loop. Insert secondary PHI nodes for the
// strength reduced pointers we'll be creating after the canonical induction
// variable's PHI.
std::set<Instruction*> DeadInsts;
Jeff Cohen
committed
GEPCache Cache;
for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end();
UI != UE; ++UI)
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
Jeff Cohen
committed
strengthReduceGEP(GEPI, L, &Cache, PN->getNext(), DeadInsts);
// Clean up after ourselves
if (!DeadInsts.empty()) {
DeleteTriviallyDeadInstructions(DeadInsts);
// 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 dead, so that we
// can remove it as well. The requirements for the cann indvar to be
// considered dead are:
// 1. the cann indvar has one use
// 2. the use is an add instruction
// 3. the add has one use
// 4. the add is used by the cann indvar
// If all four cases above are true, then we can remove both the add and
// the cann indvar.
// FIXME: this needs to eliminate an induction variable even if it's being
// compared against some value to decide loop termination.
if (PN->hasOneUse()) {
BinaryOperator *BO = dyn_cast<BinaryOperator>(*(PN->use_begin()));
if (BO && BO->getOpcode() == Instruction::Add)
if (BO->hasOneUse()) {
if (PN == dyn_cast<PHINode>(*(BO->use_begin()))) {
DeadInsts.insert(BO);
// Break the cycle, then delete the PHI.
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
PN->eraseFromParent();
DeleteTriviallyDeadInstructions(DeadInsts);
}
}
}
}
}