[llvm-commits] [poolalloc] r126550 - /poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp

Arushi Aggarwal aggarwa4 at illinois.edu
Sat Feb 26 10:00:25 PST 2011


Author: aggarwa4
Date: Sat Feb 26 12:00:25 2011
New Revision: 126550

URL: http://llvm.org/viewvc/llvm-project?rev=126550&view=rev
Log:
Merge GEPs. Code copied from InstCombine.

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

Added: poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp?rev=126550&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp (added)
+++ poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp Sat Feb 26 12:00:25 2011
@@ -0,0 +1,125 @@
+//===-- MergeGEP.cpp - Merge GEPs for indexing in arrays ------------ ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 
+//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "mergearraygep"
+
+#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/Transforms/Utils/Cloning.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Debug.h"
+#include <vector>
+
+using namespace llvm;
+
+
+namespace {
+  class MergeArrayGEP : public ModulePass {
+  public:
+    static char ID;
+    MergeArrayGEP() : ModulePass(&ID) {}
+    bool runOnModule(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;) {
+            GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I);
+            I++;
+            if(GEP == NULL)
+              continue;
+            simplifyGEP(GEP);
+          }
+        }
+      }
+      return true;
+    }
+    static void simplifyGEP(GetElementPtrInst *GEP) {
+      Value *PtrOp = GEP->getOperand(0);
+      if (GEPOperator *Src = dyn_cast<GEPOperator>(PtrOp)) {
+        // Note that if our source is a gep chain itself that we wait for that
+        // chain to be resolved before we perform this transformation.  This
+        // avoids us creating a TON of code in some cases.
+        //
+        if (GetElementPtrInst *SrcGEP =
+            dyn_cast<GetElementPtrInst>(Src->getOperand(0)))
+          if (SrcGEP->getNumOperands() == 2)
+            return;   // Wait until our source is folded to completion.
+
+        SmallVector<Value*, 8> Indices;
+
+        // Find out whether the last index in the source GEP is a sequential idx.
+        bool EndsWithSequential = false;
+        for (gep_type_iterator I = gep_type_begin(*Src), E = gep_type_end(*Src);
+             I != E; ++I)
+          EndsWithSequential = !(*I)->isStructTy();
+
+        // Can we combine the two pointer arithmetics offsets?
+        if (EndsWithSequential) {
+          // Replace: gep (gep %P, long B), long A, ...
+          // With:    T = long A+B; gep %P, T, ...
+          //
+          Value *Sum;
+          Value *SO1 = Src->getOperand(Src->getNumOperands()-1);
+          Value *GO1 = GEP->getOperand(1);
+          if (SO1 == Constant::getNullValue(SO1->getType())) {
+            Sum = GO1;
+          } else if (GO1 == Constant::getNullValue(GO1->getType())) {
+            Sum = SO1;
+          } else {
+            // If they aren't the same type, then the input hasn't been processed
+            // by the loop above yet (which canonicalizes sequential index types to
+            // intptr_t).  Just avoid transforming this until the input has been
+            // normalized.
+            if (SO1->getType() != GO1->getType())
+              return;
+            Sum = llvm::BinaryOperator::Create(BinaryOperator::Add,SO1, GO1, PtrOp->getName()+".sum",GEP);
+          }
+
+          // Update the GEP in place if possible.
+          if (Src->getNumOperands() == 2) {
+            GEP->setOperand(0, Src->getOperand(0));
+            GEP->setOperand(1, Sum);
+            return;
+          }
+          Indices.append(Src->op_begin()+1, Src->op_end()-1);
+          Indices.push_back(Sum);
+          Indices.append(GEP->op_begin()+2, GEP->op_end());
+        } else if (isa<Constant>(GEP->idx_begin()) &&
+                   cast<Constant>(GEP->idx_begin())->isNullValue() &&
+                   Src->getNumOperands() != 1) {
+          // Otherwise we can do the fold if the first index of the GEP is a zero
+          Indices.append(Src->op_begin()+1, Src->op_end());
+          Indices.append(GEP->idx_begin()+1, GEP->idx_end());
+        }
+
+        if (!Indices.empty()){
+          GetElementPtrInst *GEPNew =  (GEP->isInBounds() && Src->isInBounds()) ?
+            GetElementPtrInst::CreateInBounds(Src->getOperand(0), Indices.begin(),
+                                              Indices.end(), GEP->getName(), GEP) :
+            GetElementPtrInst::Create(Src->getOperand(0), Indices.begin(),
+                                      Indices.end(), GEP->getName(), GEP);
+          GEP->replaceAllUsesWith(GEPNew);
+          GEP->eraseFromParent();
+        }
+      }
+
+
+    }
+  };
+}
+
+char MergeArrayGEP::ID = 0;
+static RegisterPass<MergeArrayGEP>
+X("mergearrgep", "Merge GEPs for arrays indexing");





More information about the llvm-commits mailing list