blob: 53dd06d24bb5b01cb34e30fb0f70a0043fa06982 [file] [log] [blame]
Dan Gohman6000e252009-10-26 19:12:14 +00001//===- 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"
22using namespace llvm;
23
24namespace {
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 Anderson90c579d2010-08-06 18:33:48 +000030 explicit GEPSplitter() : FunctionPass(ID) {}
Dan Gohman6000e252009-10-26 19:12:14 +000031 };
32}
33
34char GEPSplitter::ID = 0;
Owen Andersond13db2c2010-07-21 22:09:45 +000035INITIALIZE_PASS(GEPSplitter, "split-geps",
36 "split complex GEPs into simple GEPs", false, false);
Dan Gohman6000e252009-10-26 19:12:14 +000037
38FunctionPass *llvm::createGEPSplitterPass() {
39 return new GEPSplitter();
40}
41
42bool 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
79void GEPSplitter::getAnalysisUsage(AnalysisUsage &AU) const {
80 AU.setPreservesCFG();
81}