Add support for not strength reducing GEPs where the element size is a small

power of two.  This emphatically includes the zeroeth power of two.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20429 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jeff Cohen 2005-03-04 04:04:26 +00:00
parent 8d46a268c5
commit 2f3c9b7562
2 changed files with 30 additions and 4 deletions

View File

@ -129,9 +129,12 @@ FunctionPass *createLICMPass();
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// LoopStrengthReduce - This pass is strength reduces GEP instructions that use // LoopStrengthReduce - This pass is strength reduces GEP instructions that use
// a loop's canonical induction variable as one of their indices. // a loop's canonical induction variable as one of their indices. The
// MaxTargetAMSize is the largest element size that the target architecture
// can handle in its addressing modes. Power of two multipliers less than or
// equal to this value are not reduced.
// //
FunctionPass *createLoopStrengthReducePass(); FunctionPass *createLoopStrengthReducePass(unsigned MaxTargetAMSize = 1);
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //

View File

@ -22,10 +22,12 @@
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopInfo.h"
#include "llvm/Support/CFG.h" #include "llvm/Support/CFG.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include <set> #include <set>
using namespace llvm; using namespace llvm;
@ -37,7 +39,12 @@ namespace {
LoopInfo *LI; LoopInfo *LI;
DominatorSet *DS; DominatorSet *DS;
bool Changed; bool Changed;
unsigned MaxTargetAMSize;
public: public:
LoopStrengthReduce(unsigned MTAMS = 1)
: MaxTargetAMSize(MTAMS) {
}
virtual bool runOnFunction(Function &) { virtual bool runOnFunction(Function &) {
LI = &getAnalysis<LoopInfo>(); LI = &getAnalysis<LoopInfo>();
DS = &getAnalysis<DominatorSet>(); DS = &getAnalysis<DominatorSet>();
@ -53,6 +60,7 @@ namespace {
AU.addRequiredID(LoopSimplifyID); AU.addRequiredID(LoopSimplifyID);
AU.addRequired<LoopInfo>(); AU.addRequired<LoopInfo>();
AU.addRequired<DominatorSet>(); AU.addRequired<DominatorSet>();
AU.addRequired<TargetData>();
} }
private: private:
void runOnLoop(Loop *L); void runOnLoop(Loop *L);
@ -65,8 +73,8 @@ namespace {
"Strength Reduce GEP Uses of Ind. Vars"); "Strength Reduce GEP Uses of Ind. Vars");
} }
FunctionPass *llvm::createLoopStrengthReducePass() { FunctionPass *llvm::createLoopStrengthReducePass(unsigned MaxTargetAMSize) {
return new LoopStrengthReduce(); return new LoopStrengthReduce(MaxTargetAMSize);
} }
/// DeleteTriviallyDeadInstructions - If any of the instructions is the /// DeleteTriviallyDeadInstructions - If any of the instructions is the
@ -104,6 +112,7 @@ void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
unsigned indvar = 0; unsigned indvar = 0;
std::vector<Value *> pre_op_vector; std::vector<Value *> pre_op_vector;
std::vector<Value *> inc_op_vector; std::vector<Value *> inc_op_vector;
const Type *ty = GEPI->getOperand(0)->getType();
Value *CanonicalIndVar = L->getCanonicalInductionVariable(); Value *CanonicalIndVar = L->getCanonicalInductionVariable();
BasicBlock *Header = L->getHeader(); BasicBlock *Header = L->getHeader();
BasicBlock *Preheader = L->getLoopPreheader(); BasicBlock *Preheader = L->getLoopPreheader();
@ -111,6 +120,14 @@ void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
for (unsigned op = 1, e = GEPI->getNumOperands(); op != e; ++op) { for (unsigned op = 1, e = GEPI->getNumOperands(); op != e; ++op) {
Value *operand = GEPI->getOperand(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) { if (operand == CanonicalIndVar) {
// FIXME: use getCanonicalInductionVariableIncrement to choose between // FIXME: use getCanonicalInductionVariableIncrement to choose between
// one and neg one maybe? We need to support int *foo = GEP base, -1 // one and neg one maybe? We need to support int *foo = GEP base, -1
@ -139,6 +156,12 @@ void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
if (Instruction *GepPtrOp = dyn_cast<Instruction>(GEPI->getOperand(0))) if (Instruction *GepPtrOp = dyn_cast<Instruction>(GEPI->getOperand(0)))
if (!DS->dominates(GepPtrOp, Preheader->getTerminator())) if (!DS->dominates(GepPtrOp, Preheader->getTerminator()))
return; return;
// Don't reduced 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 // If all operands of the GEP we are going to insert into the preheader
// are constants, generate a GEP ConstantExpr instead. // are constants, generate a GEP ConstantExpr instead.