Dan Gohman | 6000e25 | 2009-10-26 19:12:14 +0000 | [diff] [blame] | 1 | //===- GEPSplitter.cpp - Split complex GEPs into simple ones --------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This function breaks GEPs with more than 2 non-zero operands into smaller |
| 11 | // GEPs each with no more than 2 non-zero operands. This exposes redundancy |
| 12 | // between GEPs with common initial operand sequences. |
| 13 | // |
| 14 | //===----------------------------------------------------------------------===// |
| 15 | |
| 16 | #define DEBUG_TYPE "split-geps" |
| 17 | #include "llvm/Transforms/Scalar.h" |
| 18 | #include "llvm/Constants.h" |
| 19 | #include "llvm/Function.h" |
| 20 | #include "llvm/Instructions.h" |
| 21 | #include "llvm/Pass.h" |
| 22 | using namespace llvm; |
| 23 | |
| 24 | namespace { |
| 25 | class GEPSplitter : public FunctionPass { |
| 26 | virtual bool runOnFunction(Function &F); |
| 27 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; |
| 28 | public: |
| 29 | static char ID; // Pass identification, replacement for typeid |
Owen Anderson | 90c579d | 2010-08-06 18:33:48 +0000 | [diff] [blame] | 30 | explicit GEPSplitter() : FunctionPass(ID) {} |
Dan Gohman | 6000e25 | 2009-10-26 19:12:14 +0000 | [diff] [blame] | 31 | }; |
| 32 | } |
| 33 | |
| 34 | char GEPSplitter::ID = 0; |
Owen Anderson | d13db2c | 2010-07-21 22:09:45 +0000 | [diff] [blame] | 35 | INITIALIZE_PASS(GEPSplitter, "split-geps", |
| 36 | "split complex GEPs into simple GEPs", false, false); |
Dan Gohman | 6000e25 | 2009-10-26 19:12:14 +0000 | [diff] [blame] | 37 | |
| 38 | FunctionPass *llvm::createGEPSplitterPass() { |
| 39 | return new GEPSplitter(); |
| 40 | } |
| 41 | |
| 42 | bool GEPSplitter::runOnFunction(Function &F) { |
| 43 | bool Changed = false; |
| 44 | |
| 45 | // Visit each GEP instruction. |
| 46 | for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) |
| 47 | for (BasicBlock::iterator II = I->begin(), IE = I->end(); II != IE; ) |
| 48 | if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(II++)) { |
| 49 | unsigned NumOps = GEP->getNumOperands(); |
| 50 | // Ignore GEPs which are already simple. |
| 51 | if (NumOps <= 2) |
| 52 | continue; |
| 53 | bool FirstIndexIsZero = isa<ConstantInt>(GEP->getOperand(1)) && |
| 54 | cast<ConstantInt>(GEP->getOperand(1))->isZero(); |
| 55 | if (NumOps == 3 && FirstIndexIsZero) |
| 56 | continue; |
| 57 | // The first index is special and gets expanded with a 2-operand GEP |
| 58 | // (unless it's zero, in which case we can skip this). |
| 59 | Value *NewGEP = FirstIndexIsZero ? |
| 60 | GEP->getOperand(0) : |
| 61 | GetElementPtrInst::Create(GEP->getOperand(0), GEP->getOperand(1), |
| 62 | "tmp", GEP); |
| 63 | // All remaining indices get expanded with a 3-operand GEP with zero |
| 64 | // as the second operand. |
| 65 | Value *Idxs[2]; |
| 66 | Idxs[0] = ConstantInt::get(Type::getInt64Ty(F.getContext()), 0); |
| 67 | for (unsigned i = 2; i != NumOps; ++i) { |
| 68 | Idxs[1] = GEP->getOperand(i); |
| 69 | NewGEP = GetElementPtrInst::Create(NewGEP, Idxs, Idxs+2, "tmp", GEP); |
| 70 | } |
| 71 | GEP->replaceAllUsesWith(NewGEP); |
| 72 | GEP->eraseFromParent(); |
| 73 | Changed = true; |
| 74 | } |
| 75 | |
| 76 | return Changed; |
| 77 | } |
| 78 | |
| 79 | void GEPSplitter::getAnalysisUsage(AnalysisUsage &AU) const { |
| 80 | AU.setPreservesCFG(); |
| 81 | } |