[llvm-commits] [poolalloc] r126412 - /poolalloc/trunk/lib/AssistDS/TestGEP.cpp

Arushi Aggarwal aggarwa4 at illinois.edu
Thu Feb 24 11:33:08 PST 2011


Author: aggarwa4
Date: Thu Feb 24 13:33:08 2011
New Revision: 126412

URL: http://llvm.org/viewvc/llvm-project?rev=126412&view=rev
Log:
If a function takes a pointer to a field inside a 
struct, clone the function, and pass the struct 
pointer instead.

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

Added: poolalloc/trunk/lib/AssistDS/TestGEP.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TestGEP.cpp?rev=126412&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/TestGEP.cpp (added)
+++ poolalloc/trunk/lib/AssistDS/TestGEP.cpp Thu Feb 24 13:33:08 2011
@@ -0,0 +1,151 @@
+//===-- 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 "gepargs"
+
+#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 "llvm/Use.h"
+#include <vector>
+#include <map>
+
+using namespace llvm;
+STATISTIC(numSimplified, "Number of Calls Simplified");
+
+
+namespace {
+  class GEPArgs : public ModulePass {
+  private:
+      std::map<std::pair<Function *, const FunctionType*>, Function*>  fnCache;
+  public:
+    static char ID;
+    GEPArgs() : 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; I++) {
+            if(!(isa<GetElementPtrInst>(I)))
+              continue;
+            // we are only interested in GEPs
+            GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
+            // Only GEPs that have constant indices, so we dont have
+            // to add more args
+            if(!GEP->hasAllConstantIndices())
+              continue;
+            // If the GEP is not doing structure indexing, dont care.
+            const PointerType *PTy = cast<PointerType>(GEP->getPointerOperand()->getType());
+            if(!PTy->getElementType()->isStructTy())
+              continue;
+            
+            for (Value::use_iterator UI = GEP->use_begin(),UE = GEP->use_end(); UI != UE; ) {
+              // check if GEP is used in a Call Inst
+              CallInst *CI = dyn_cast<CallInst>(UI++);
+              if(!CI) 
+                continue;
+              
+              // if the GEP calls a function, that is externally defined,
+              // or might be changed, ignore this call site.
+              Function *F = CI->getCalledFunction();
+              
+              if (!F || (F->isDeclaration() || F->mayBeOverridden())) 
+                continue;
+              
+
+              // find the argument we must replace
+              unsigned argNum = 1;
+              for(; argNum < CI->getNumOperands();argNum++)
+                if(GEP == CI->getOperand(argNum))
+                  break;
+
+              // Construct the new Type
+              // Appends the struct Type at the beginning
+              std::vector<const Type*>TP;
+              TP.push_back(GEP->getPointerOperand()->getType());
+              for(unsigned c = 1; c < CI->getNumOperands();c++) {
+                  TP.push_back(CI->getOperand(c)->getType());
+              }
+
+              //return type is same as that of original instruction
+              const FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
+              Function *NewF;
+              if(fnCache.find(std::make_pair(F, NewFTy)) != fnCache.end()){
+                NewF = fnCache[std::make_pair(F, NewFTy)];
+              }
+              else {
+                numSimplified++;
+                if(numSimplified >2000)
+                  return true;
+
+              NewF = Function::Create(NewFTy,
+                                                GlobalValue::InternalLinkage,
+                                                F->getNameStr() + ".TEST",
+                                                &M);
+
+              Function::arg_iterator NI = NewF->arg_begin();
+              NI->setName("Sarg");
+              ++NI;
+
+              DenseMap<const Value*, Value*> ValueMap;
+
+              for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) {
+                ValueMap[II] = NI;
+                NI->setName(II->getName());
+              }
+              // Perform the cloning.
+              SmallVector<ReturnInst*,100> Returns;
+              CloneFunctionInto(NewF, F, ValueMap, Returns);
+              std::vector<Value*> fargs;
+              for(Function::arg_iterator ai = NewF->arg_begin(), 
+                  ae= NewF->arg_end(); ai != ae; ++ai) {
+                fargs.push_back(ai);
+              }
+
+              //Get the point to insert the GEP instr.
+              NI = NewF->arg_begin();
+              SmallVector<Value*, 8> Ops(CI->op_begin()+1, CI->op_end());
+              Instruction *InsertPoint;
+              for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt);
+                         
+              SmallVector<Value*, 8> Indices;
+              Indices.append(GEP->op_begin()+1, GEP->op_end());
+              GetElementPtrInst *GEP_new = GetElementPtrInst::Create(cast<Value>(NI), Indices.begin(), Indices.end(), "", InsertPoint);
+              fargs.at(argNum)->replaceAllUsesWith(GEP_new);
+              fnCache[std::make_pair(F, NewFTy)]= NewF;
+              }
+
+              SmallVector<Value*, 8> Args;
+              Args.push_back(GEP->getPointerOperand());
+              for(unsigned j =1;j<CI->getNumOperands();j++) {
+                  Args.push_back(CI->getOperand(j));
+              }
+              CallInst *CallI = CallInst::Create(NewF,Args.begin(), Args.end(),"", CI);
+              CI->replaceAllUsesWith(CallI);
+              CI->eraseFromParent();
+            }
+          }
+        }
+      }
+      return true;
+    }
+  };
+}
+
+char GEPArgs::ID = 0;
+static RegisterPass<GEPArgs>
+X("gep-args", "Find GEP into structs passed as args");





More information about the llvm-commits mailing list