[llvm-commits] [poolalloc] r128971 - /poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp
Arushi Aggarwal
aggarwa4 at illinois.edu
Tue Apr 5 18:01:26 PDT 2011
Author: aggarwa4
Date: Tue Apr 5 20:01:26 2011
New Revision: 128971
URL: http://llvm.org/viewvc/llvm-project?rev=128971&view=rev
Log:
Added more comments.
Modified:
poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp
Modified: poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp?rev=128971&r1=128970&r2=128971&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp Tue Apr 5 20:01:26 2011
@@ -1,3 +1,17 @@
+//===--------------- SimplifyGEP.cpp - Simplify GEPs types ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Simplify GEPs with bitcasts (mostly cloned from InstCombine)
+//
+//===----------------------------------------------------------------------===//
+
+
#define DEBUG_TYPE "simplifygep"
#include "llvm/Instructions.h"
@@ -38,10 +52,26 @@
public:
static char ID;
SimplifyGEP() : ModulePass(&ID) {}
+ //
+ // Method: runOnModule()
+ //
+ // Description:
+ // Entry point for this LLVM pass.
+ // Find all GEPs, and simplify them.
+ //
+ // Inputs:
+ // M - A reference to the LLVM module to transform
+ //
+ // Outputs:
+ // M - The transformed LLVM module.
+ //
+ // Return value:
+ // true - The module was modified.
+ // false - The module was not modified.
+ //
bool runOnModule(Module& M) {
- TD = &getAnalysis<TargetData>();
+ 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++) {
@@ -50,16 +80,26 @@
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
Value *PtrOp = GEP->getOperand(0);
Value *StrippedPtr = PtrOp->stripPointerCasts();
+ // Check if the GEP base pointer is enclosed in a cast
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();
+ // Transform: GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ...
+ // into : GEP [10 x i8]* X, i32 0, ...
+ //
+ // Likewise, transform: GEP (bitcast i8* X to [0 x i8]*), i32 0, ...
+ // into : GEP i8* X, ...
+ //
+ // This occurs when the program declares an array extern like "int X[];"
if (HasZeroPointerIndex) {
const PointerType *CPTy = cast<PointerType>(PtrOp->getType());
if (const ArrayType *CATy =
dyn_cast<ArrayType>(CPTy->getElementType())) {
+ // GEP (bitcast i8* X to [0 x i8]*), i32 0, ... ?
if (CATy->getElementType() == StrippedPtrTy->getElementType()) {
+ // -> GEP i8* X, ...
SmallVector<Value*, 8> Idx(GEP->idx_begin()+1, GEP->idx_end());
GetElementPtrInst *Res =
GetElementPtrInst::Create(StrippedPtr, Idx.begin(),
@@ -68,10 +108,16 @@
GEP->replaceAllUsesWith(Res);
continue;
}
-
+
if (const ArrayType *XATy =
dyn_cast<ArrayType>(StrippedPtrTy->getElementType())){
+ // GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... ?
if (CATy->getElementType() == XATy->getElementType()) {
+ // -> GEP [10 x i8]* X, i32 0, ...
+ // At this point, we know that the cast source type is a pointer
+ // to an array of the same type as the destination pointer
+ // array. Because the array type is never stepped over (there
+ // is a leading zero) we can fold the cast into this GEP.
GEP->setOperand(0, StrippedPtr);
continue;
}
@@ -90,23 +136,23 @@
Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
Idx[1] = GEP->getOperand(1);
Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx,
- Idx+2, GEP->getName(), GEP);
+ 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.
+ // allow either a mul, shift, or constant here.
Value *NewIdx = 0;
ConstantInt *Scale = 0;
if (ArrayEltSize == 1) {
@@ -129,7 +175,7 @@
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
@@ -143,13 +189,13 @@
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);
+ Idx+2, GEP->getName(), GEP);
GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
continue;
}
@@ -168,6 +214,9 @@
};
}
+// Pass ID variable
char SimplifyGEP::ID = 0;
+
+// Register the pass
static RegisterPass<SimplifyGEP>
X("simplifygep", "Simplify GEPs");
More information about the llvm-commits
mailing list