[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