[llvm-commits] [poolalloc] r129646 - in /poolalloc/trunk/lib/AssistDS: LoadArgs.cpp StructReturnToPointer.cpp

Arushi Aggarwal aggarwa4 at illinois.edu
Sat Apr 16 14:20:06 PDT 2011


Author: aggarwa4
Date: Sat Apr 16 16:20:06 2011
New Revision: 129646

URL: http://llvm.org/viewvc/llvm-project?rev=129646&view=rev
Log:
StructReturn : Use alloca in caller instead of malloc
in callee.

LoadArgs : For arguments that are result of a load,
pass in the original pointer.

Added:
    poolalloc/trunk/lib/AssistDS/LoadArgs.cpp
Modified:
    poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp

Added: poolalloc/trunk/lib/AssistDS/LoadArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/LoadArgs.cpp?rev=129646&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/LoadArgs.cpp (added)
+++ poolalloc/trunk/lib/AssistDS/LoadArgs.cpp Sat Apr 16 16:20:06 2011
@@ -0,0 +1,159 @@
+//===-- 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 "ldargs"
+
+#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 Changed");
+
+namespace {
+  class LoadArgs : public ModulePass {
+  public:
+    static char ID;
+    LoadArgs() : 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<LoadInst>(I)))
+              continue;
+            // we are only interested in GEPs
+            LoadInst *LI = cast<LoadInst>(I);
+            if(LI->getType()->isPointerTy())
+              continue;
+            // If the GEP is not doing structure indexing, dont care.
+            for (Value::use_iterator UI = LI->use_begin(),UE = LI->use_end(); UI != UE; ) {
+              // check if GEP is used in a Call Inst
+              CallInst *CI = dyn_cast<CallInst>(UI++);
+              if(!CI) 
+                continue;
+
+              if(CI->hasByValArgument())
+                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;
+              if(F->hasStructRetAttr())
+                continue;
+              if(F->getFunctionType()->isVarArg())
+                continue;
+
+              // find the argument we must replace
+              unsigned argNum = 1;
+              for(; argNum < CI->getNumOperands();argNum++)
+                if(LI == CI->getOperand(argNum))
+                  break;
+
+              unsigned i = 1;
+              Function::arg_iterator II = F->arg_begin();
+              for (; i!= argNum; ++II, ++i) {
+                ;
+              }
+              if(F->paramHasAttr(argNum, Attribute::SExt) ||
+                 F->paramHasAttr(argNum, Attribute::ZExt)) 
+                continue;
+              if(II->getNumUses() !=1)
+                continue;
+              if(!isa<StoreInst>(II->use_begin()))
+                continue;
+              // Construct the new Type
+              // Appends the struct Type at the beginning
+              std::vector<const Type*>TP;
+              TP.push_back(LI->getOperand(0)->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;
+              numSimplified++;
+              if(numSimplified > 26) //26
+                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);
+              }
+
+              NewF->setAlignment(F->getAlignment());
+              //Get the point to insert the GEP instr.
+              NI = NewF->arg_begin();
+              Instruction *InsertPoint;
+              for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}
+
+              LoadInst *LI_new = new LoadInst(cast<Value>(NI), "", InsertPoint);
+              fargs.at(argNum)->replaceAllUsesWith(LI_new);
+
+              SmallVector<Value*, 8> Args;
+              Args.push_back(LI->getOperand(0));
+              for(unsigned j =1;j<CI->getNumOperands();j++) {
+                Args.push_back(CI->getOperand(j));
+              }
+              CallInst *CallI = CallInst::Create(NewF,Args.begin(), Args.end(),"", CI);
+              CallI->setCallingConv(CI->getCallingConv());
+              CallI->setAttributes(CI->getAttributes());
+              CI->dump();
+              CallI->dump();
+              LI->dump();
+              LI_new->dump();
+              //F->dump();
+              //NewF->dump();
+              CI->replaceAllUsesWith(CallI);
+              CI->eraseFromParent();
+            }
+          }
+        }
+      }
+      return true;
+    }
+  };
+}
+
+char LoadArgs::ID = 0;
+static RegisterPass<LoadArgs>
+X("ld-args", "Find GEP into structs passed as args");

Modified: poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp?rev=129646&r1=129645&r2=129646&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp Sat Apr 16 16:20:06 2011
@@ -64,64 +64,62 @@
       while(!worklistR.empty()) {
         Function *F = worklistR.back();
         worklistR.pop_back();
-        const Type *NewReturnType = F->getReturnType()->getPointerTo();
+        const Type *NewArgType = F->getReturnType()->getPointerTo();
 
         // Construct the new Type
         std::vector<const Type*>TP;
+        TP.push_back(NewArgType);
         for (Function::arg_iterator ii = F->arg_begin(), ee = F->arg_end();
              ii != ee; ++ii) {
           TP.push_back(ii->getType());
         }
 
-        const FunctionType *NFTy = FunctionType::get(NewReturnType, TP, false);
+        const FunctionType *NFTy = FunctionType::get(F->getReturnType(), TP, false);
 
         // Create the new function body and insert it into the module.
         Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName(), &M);
         NF->copyAttributesFrom(F);
+        DenseMap<const Value*, Value*> ValueMap;
         Function::arg_iterator NI = NF->arg_begin();
+        NI->setName("ret");
+        ++NI;
         for (Function::arg_iterator II = F->arg_begin(); II != F->arg_end(); ++II, ++NI) {
-          II->replaceAllUsesWith(NI);
+          //II->replaceAllUsesWith(NI);
+          ValueMap[II] = NI;
           NI->setName(II->getName());
         }
-        NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());
-        Instruction *InsertPoint;
-        for (BasicBlock::iterator insrt = NF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}
-
-        Function* MallocF = M.getFunction ("malloc");
-        const Type* IntPtrT = Type::getInt64Ty(M.getContext());
-
-        const Type *BPTy = Type::getInt8PtrTy(M.getContext());
-        Value *MallocFunc = MallocF;
-        Constant *Size;
-        if (!MallocFunc) {
-          // prototype malloc as "void *malloc(size_t)"
-          Size = ConstantInt::get (IntPtrT, 123, true);
-          MallocFunc = M.getOrInsertFunction("malloc", BPTy, IntPtrT, NULL);
-        } else {
-          Size = ConstantInt::get (MallocF->arg_begin()->getType(), 123, true);
+        // Perform the cloning.
+        SmallVector<ReturnInst*,100> Returns;
+        CloneFunctionInto(NF, F, ValueMap, Returns);
+        std::vector<Value*> fargs;
+        for(Function::arg_iterator ai = NF->arg_begin(), 
+            ae= NF->arg_end(); ai != ae; ++ai) {
+          fargs.push_back(ai);
         }
-        CallInst *MCall = CallInst::Create(MallocFunc,Size,  "ret_ptr", InsertPoint);
-        Instruction *Result = new BitCastInst(MCall, NewReturnType, "", InsertPoint);
+       NF->setAlignment(F->getAlignment());
         for (Function::iterator B = NF->begin(), FE = NF->end(); B != FE; ++B) {      
           for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
             ReturnInst * RI = dyn_cast<ReturnInst>(I++);
             if(!RI)
               continue;
-            new StoreInst(RI->getOperand(0), Result, RI);
-            ReturnInst::Create(M.getContext(), Result, RI);
-            RI->eraseFromParent();
+            new StoreInst(RI->getOperand(0), fargs.at(0), RI);
+            //ReturnInst::Create(M.getContext(), fargs, RI);
+            //RI->eraseFromParent();
           }
         }
 
         for(Value::use_iterator ui = F->use_begin(), ue = F->use_end();
             ui != ue; ) {
           CallInst *CI = dyn_cast<CallInst>(ui++);
+          AllocaInst *AllocaNew = new AllocaInst(F->getReturnType(), 0, "", CI);
           SmallVector<Value*, 8> Args;
+          
+          Args.push_back(AllocaNew);
           for(unsigned j =1;j<CI->getNumOperands();j++) {
             Args.push_back(CI->getOperand(j));
           }
-          CallInst *CINew = CallInst::Create(NF, Args.begin(), Args.end(), "", CI);
-          LoadInst *LI = new LoadInst(CINew, "", CI);
+          CallInst::Create(NF, Args.begin(), Args.end(), "", CI);
+          LoadInst *LI = new LoadInst(AllocaNew, "", CI);
           CI->replaceAllUsesWith(LI);
           CI->eraseFromParent();
         }





More information about the llvm-commits mailing list