Add support for not strength reducing GEPs where the element size is a small
authorJeff Cohen <jeffc@jolt-lang.org>
Fri, 4 Mar 2005 04:04:26 +0000 (04:04 +0000)
committerJeff Cohen <jeffc@jolt-lang.org>
Fri, 4 Mar 2005 04:04:26 +0000 (04:04 +0000)
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

include/llvm/Transforms/Scalar.h
lib/Transforms/Scalar/LoopStrengthReduce.cpp

index ae4f32e0b0e4f8a175b0cd9823cae896a9f758e1..7832c93be993e85bfaf0fb32ede2a5fdc511bb10 100644 (file)
@@ -129,9 +129,12 @@ FunctionPass *createLICMPass();
 //===----------------------------------------------------------------------===//
 //
 // 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);
 
 //===----------------------------------------------------------------------===//
 //
index 56bc43e62f309976a052b40732921db777492cb6..52b6b9887a79f651a3ce2a01ff201f9ff222abfc 100644 (file)
 #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;
@@ -37,7 +39,12 @@ namespace {
     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>();
@@ -53,6 +60,7 @@ namespace {
       AU.addRequiredID(LoopSimplifyID);
       AU.addRequired<LoopInfo>();
       AU.addRequired<DominatorSet>();
+      AU.addRequired<TargetData>();
     }
   private:
     void runOnLoop(Loop *L);
@@ -65,8 +73,8 @@ namespace {
                                     "Strength Reduce GEP Uses of Ind. Vars");
 }
 
-FunctionPass *llvm::createLoopStrengthReducePass() {
-  return new LoopStrengthReduce();
+FunctionPass *llvm::createLoopStrengthReducePass(unsigned MaxTargetAMSize) {
+  return new LoopStrengthReduce(MaxTargetAMSize);
 }
 
 /// DeleteTriviallyDeadInstructions - If any of the instructions is the
@@ -104,6 +112,7 @@ void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
   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();
   BasicBlock *Header = L->getHeader();
   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) {
     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
@@ -139,6 +156,12 @@ void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
   if (Instruction *GepPtrOp = dyn_cast<Instruction>(GEPI->getOperand(0)))
     if (!DS->dominates(GepPtrOp, Preheader->getTerminator()))
       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
   // are constants, generate a GEP ConstantExpr instead.