[llvm-commits] [poolalloc] r126029 - /poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp

Arushi Aggarwal aggarwa4 at illinois.edu
Sat Feb 19 05:34:20 PST 2011


Author: aggarwa4
Date: Sat Feb 19 07:34:20 2011
New Revision: 126029

URL: http://llvm.org/viewvc/llvm-project?rev=126029&view=rev
Log:
Some code stolen from InstCombine, to help
DSA.

Added:
    poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp

Added: poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp?rev=126029&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp (added)
+++ poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp Sat Feb 19 07:34:20 2011
@@ -0,0 +1,173 @@
+#define DEBUG_TYPE "simplifygep"
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Instructions.h"
+#include "llvm/Constants.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Operator.h"
+#include "llvm/Target/TargetData.h"
+
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+  static void preprocess(Module& M) {
+    for (Module::iterator F = M.begin(); F != M.end(); ++F){
+      for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {      
+        for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
+          if(!(isa<GetElementPtrInst>(I)))
+            continue;
+          GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
+          if(BitCastInst *BI = dyn_cast<BitCastInst>(GEP->getOperand(0))) {
+            if(Constant *C = dyn_cast<Constant>(BI->getOperand(0))) {
+              GEP->setOperand(0, ConstantExpr::getBitCast(C, BI->getType()));
+            }
+          }
+        }
+      }
+    }
+  }
+  class SimplifyGEP : public ModulePass {
+  private:
+    TargetData * TD;
+  public:
+    static char ID;
+    SimplifyGEP() : ModulePass(&ID) {}
+    bool runOnModule(Module& M) {
+    TD = &getAnalysis<TargetData>();
+      preprocess(M);
+      //bool changed = false;
+      for (Module::iterator F = M.begin(); F != M.end(); ++F){
+        for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {      
+          for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
+            if(!(isa<GetElementPtrInst>(I)))
+              continue;
+            GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
+            Value *PtrOp = GEP->getOperand(0);
+            Value *StrippedPtr = PtrOp->stripPointerCasts();
+            if (StrippedPtr != PtrOp) {
+              const PointerType *StrippedPtrTy =cast<PointerType>(StrippedPtr->getType());
+              bool HasZeroPointerIndex = false;
+              if (ConstantInt *C = dyn_cast<ConstantInt>(GEP->getOperand(1)))
+                HasZeroPointerIndex = C->isZero();
+              if (HasZeroPointerIndex) {
+                const PointerType *CPTy = cast<PointerType>(PtrOp->getType());
+                if (const ArrayType *CATy =
+                    dyn_cast<ArrayType>(CPTy->getElementType())) {
+                  if (CATy->getElementType() == StrippedPtrTy->getElementType()) {
+                    SmallVector<Value*, 8> Idx(GEP->idx_begin()+1, GEP->idx_end());
+                    GetElementPtrInst *Res =
+                      GetElementPtrInst::Create(StrippedPtr, Idx.begin(),
+                                                Idx.end(), GEP->getName(), GEP);
+                    Res->setIsInBounds(GEP->isInBounds());
+                    GEP->replaceAllUsesWith(Res);
+                    continue;
+                  }
+                  
+                  if (const ArrayType *XATy =
+                      dyn_cast<ArrayType>(StrippedPtrTy->getElementType())){
+                    if (CATy->getElementType() == XATy->getElementType()) {
+                      GEP->setOperand(0, StrippedPtr);
+                      continue;
+                    }
+                  }
+                }   
+              } else if (GEP->getNumOperands() == 2) {
+                // Transform things like:
+                // %t = getelementptr i32* bitcast ([2 x i32]* %str to i32*), i32 %V
+                // into:  %t1 = getelementptr [2 x i32]* %str, i32 0, i32 %V; bitcast
+                const Type *SrcElTy = StrippedPtrTy->getElementType();
+                const Type *ResElTy=cast<PointerType>(PtrOp->getType())->getElementType();
+                if (TD && SrcElTy->isArrayTy() &&
+                    TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType()) ==
+                    TD->getTypeAllocSize(ResElTy)) {
+                  Value *Idx[2];
+                  Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
+                  Idx[1] = GEP->getOperand(1);
+                  Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx,
+                                                Idx+2, GEP->getName(), GEP);
+                  // V and GEP are both pointer types --> BitCast
+                  GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
+                  continue;
+                }
+                
+                // Transform things like:
+                // getelementptr i8* bitcast ([100 x double]* X to i8*), i32 %tmp
+                //   (where tmp = 8*tmp2) into:
+                // getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast
+                
+                if (TD && SrcElTy->isArrayTy() && ResElTy->isIntegerTy(8)) {
+                  uint64_t ArrayEltSize =
+                    TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType());
+                  
+                  // Check to see if "tmp" is a scale by a multiple of ArrayEltSize.  We
+                 // allow either a mul, shift, or constant here.
+                  Value *NewIdx = 0;
+                  ConstantInt *Scale = 0;
+                  if (ArrayEltSize == 1) {
+                    NewIdx = GEP->getOperand(1);
+                    Scale = ConstantInt::get(cast<IntegerType>(NewIdx->getType()), 1);
+                  } else if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
+                    NewIdx = ConstantInt::get(CI->getType(), 1);
+                    Scale = CI;
+                  } else if (Instruction *Inst =dyn_cast<Instruction>(GEP->getOperand(1))){
+                    if (Inst->getOpcode() == Instruction::Shl &&
+                        isa<ConstantInt>(Inst->getOperand(1))) {
+                      ConstantInt *ShAmt = cast<ConstantInt>(Inst->getOperand(1));
+                      uint32_t ShAmtVal = ShAmt->getLimitedValue(64);
+                      Scale = ConstantInt::get(cast<IntegerType>(Inst->getType()),
+                                               1ULL << ShAmtVal);
+                      NewIdx = Inst->getOperand(0);
+                    } else if (Inst->getOpcode() == Instruction::Mul &&
+                               isa<ConstantInt>(Inst->getOperand(1))) {
+                      Scale = cast<ConstantInt>(Inst->getOperand(1));
+                      NewIdx = Inst->getOperand(0);
+                    }
+                  }
+                  
+                  // If the index will be to exactly the right offset with the scale taken
+                  // out, perform the transformation. Note, we don't know whether Scale is
+                  // signed or not. We'll use unsigned version of division/modulo
+                  // operation after making sure Scale doesn't have the sign bit set.
+                  if (ArrayEltSize && Scale && Scale->getSExtValue() >= 0LL &&
+                      Scale->getZExtValue() % ArrayEltSize == 0) {
+                    Scale = ConstantInt::get(Scale->getType(),
+                                             Scale->getZExtValue() / ArrayEltSize);
+                    if (Scale->getZExtValue() != 1) {
+                      Constant *C = ConstantExpr::getIntegerCast(Scale, NewIdx->getType(),
+                                                                 false /*ZExt*/);
+                      NewIdx = BinaryOperator::Create(BinaryOperator::Mul, NewIdx, C, "idxscale");
+                    }
+                    
+                    // Insert the new GEP instruction.
+                    Value *Idx[2];
+                    Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
+                    Idx[1] = NewIdx;
+                    Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx,
+                                                Idx+2, GEP->getName(), GEP);
+                    GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
+                    continue;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return true;
+    }
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.addRequired<TargetData>();
+    }
+  };
+}
+
+char SimplifyGEP::ID = 0;
+static RegisterPass<SimplifyGEP>
+X("simplifygep", "Simplify GEPs");





More information about the llvm-commits mailing list