[llvm-commits] [poolalloc] r132169 - in /poolalloc/trunk: include/assistDS/TypeChecks.h lib/AssistDS/TypeChecks.cpp

Arushi Aggarwal aggarwa4 at illinois.edu
Thu May 26 17:43:53 PDT 2011


Author: aggarwa4
Date: Thu May 26 19:43:53 2011
New Revision: 132169

URL: http://llvm.org/viewvc/llvm-project?rev=132169&view=rev
Log:
WIP:Allow handling of internal functions that have an
explicit va_list argument.

Modified:
    poolalloc/trunk/include/assistDS/TypeChecks.h
    poolalloc/trunk/lib/AssistDS/TypeChecks.cpp

Modified: poolalloc/trunk/include/assistDS/TypeChecks.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/TypeChecks.h?rev=132169&r1=132168&r2=132169&view=diff
==============================================================================
--- poolalloc/trunk/include/assistDS/TypeChecks.h (original)
+++ poolalloc/trunk/include/assistDS/TypeChecks.h Thu May 26 19:43:53 2011
@@ -32,6 +32,7 @@
 class TypeChecks : public ModulePass {
 private:
   std::map<const Type *, unsigned int> UsedTypes;
+  std::map<Function *, Function *> VAListFunctions;
 
   // Analysis from other passes.
   TargetData *TD;
@@ -61,6 +62,7 @@
   bool visitByValFunction(Module &M, Function &F); 
   bool visitMain(Module &M, Function &F); 
   bool visitVarArgFunction(Module &M, Function &F); 
+  bool visitVAListFunction(Module &M, Function &F); 
   bool visitInternalVarArgFunction(Module &M, Function &F); 
   bool visitLoadInst(Module &M, LoadInst &LI);
   bool visitStoreInst(Module &M, StoreInst &SI);
@@ -70,6 +72,7 @@
   bool visitCopyingStoreInst(Module &M, StoreInst &SI, Value *SS);
   bool visitInputFunctionValue(Module &M, Value *V, Instruction *CI);
 
+  void visitVAListCall(Function *F);
   unsigned int getTypeMarker(const llvm::Type*);
   // Return the map containing all of the types used in the module.
   const std::map<const Type *, unsigned int> &getTypes() const {

Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=132169&r1=132168&r2=132169&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Thu May 26 19:43:53 2011
@@ -76,6 +76,7 @@
   VoidPtrTy = PointerType::getUnqual(Int8Ty);
 
   UsedTypes.clear(); // Reset if run multiple times.
+  VAListFunctions.clear();
 
   Function *MainF = M.getFunction("main");
   if (MainF == 0 || MainF->isDeclaration()) {
@@ -101,12 +102,14 @@
   }
 
   std::vector<Function *> toProcess;
+  std::vector<Function *> toProcess1;
   for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
     Function &F = *MI;
     if(F.isDeclaration())
       continue;
     // record all the original functions in the program
     toProcess.push_back(&F);
+    toProcess1.push_back(&F);
 
     // Loop over all of the instructions in the function, 
     // adding their return type as well as the types of their operands.
@@ -139,6 +142,19 @@
     Function *F = toProcess.back();
     toProcess.pop_back();
     modified |= visitByValFunction(M, *F);
+    modified |= visitVAListFunction(M, *F);
+    // NOTE:must visit first
+  }
+ 
+  // iterate through all the VAList funtions and modify call sites
+  // to call the new function 
+  std::map<Function *, Function *>::iterator FI = VAListFunctions.begin(), FE = VAListFunctions.end();
+  for(; FI != FE; FI++) {
+    visitVAListCall(FI->second);
+  }
+  while(!toProcess1.empty()) {
+    Function *F = toProcess1.back();
+    toProcess1.pop_back();
     if(F->isVarArg()) {
       modified |= visitVarArgFunction(M, *F);
     }
@@ -149,6 +165,141 @@
   return modified;
 }
 
+void
+TypeChecks::visitVAListCall(Function *F) {
+  for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+    for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+      CallInst *CI = dyn_cast<CallInst>(I++);
+      if(!CI)
+        continue;
+      Function *CalledF = dyn_cast<Function>(CI->getCalledFunction());
+      if(VAListFunctions.find(CalledF) == VAListFunctions.end())
+        continue;
+      Function::arg_iterator NII = F->arg_begin();
+      std::vector<Value *>Args;
+      Args.push_back(NII++); // toatl count
+      Args.push_back(NII++); // current count
+      Args.push_back(NII); // MD
+      for(unsigned i = 1 ;i < CI->getNumOperands(); i++) {
+        // Add the original argument
+        Args.push_back(CI->getOperand(i));
+      }
+      CallInst *CINew = CallInst::Create(VAListFunctions[CalledF], Args.begin(), Args.end(), "", CI);
+      CI->replaceAllUsesWith(CINew);
+      CI->eraseFromParent();
+    }
+  }
+}
+
+bool
+TypeChecks::visitVAListFunction(Module &M, Function &F_orig) {
+  if(!F_orig.hasInternalLinkage())
+    return false;
+
+  int VAListArgNum = 0;
+  // Check if one of the arguments is a va_list
+  bool isVAListFunc = false;
+  const Type *ListType  = M.getTypeByName("struct.__va_list_tag");
+  const Type *ListPtrType = ListType->getPointerTo();
+  Argument *VAListArg = NULL; 
+  for (Function::arg_iterator I = F_orig.arg_begin(), E = F_orig.arg_end(); I != E; ++I) {
+    VAListArgNum ++;
+    if(I->getType() == ListPtrType) {
+      VAListArg = I;
+      isVAListFunc = true;
+      break;
+    }
+  }
+  if(!isVAListFunc)
+    return false;
+
+  // Clone the function to add arguments for count, MD
+
+  // 1. Create the new argument types vector
+  std::vector<const Type*>TP;
+  TP.push_back(Int64Ty); // for count
+  TP.push_back(Int64Ty); // for count
+  TP.push_back(VoidPtrTy); // for MD
+  for (Function::arg_iterator I = F_orig.arg_begin(), E = F_orig.arg_end(); I != E; ++I) {
+    TP.push_back(I->getType());
+  }
+  // 2. Create the new function prototype
+  const FunctionType *NewFTy = FunctionType::get(F_orig.getReturnType(), TP, false);
+  Function *F = Function::Create(NewFTy,
+                                 GlobalValue::InternalLinkage,
+                                 F_orig.getNameStr() + ".INT",
+                                 &M);
+
+  // 3. Set the mapping for args
+  Function::arg_iterator NI = F->arg_begin();
+  DenseMap<const Value*, Value*> ValueMap;
+  NI->setName("TotalCount");
+  NI++;
+  NI->setName("CurrentCount");
+  NI++;
+  NI->setName("MD");
+  NI++;
+  for (Function::arg_iterator II = F_orig.arg_begin(); NI != F->arg_end(); ++II, ++NI) {
+    // Each new argument maps to the argument in the old function
+    // For these arguments, also copy over the attributes
+    ValueMap[II] = NI;
+    NI->setName(II->getName());
+    NI->addAttr(F_orig.getAttributes().getParamAttributes(II->getArgNo() + 1));
+  }
+
+  // 4. Copy over the attributes for the function.
+  F->setAttributes(F->getAttributes()
+                   .addAttr(0, F_orig.getAttributes().getRetAttributes()));
+  F->setAttributes(F->getAttributes().addAttr(~0, F_orig.getAttributes().getFnAttributes()));
+
+  // 5. Perform the cloning.
+  SmallVector<ReturnInst*,100> Returns;
+  CloneFunctionInto(F, &F_orig, ValueMap, Returns);
+
+  VAListFunctions[&F_orig] =  F;
+  inst_iterator InsPt = inst_begin(F);
+
+  // Store the information
+  Function::arg_iterator NII = F->arg_begin();
+  AllocaInst *VASizeLoc = new AllocaInst(Int64Ty, "", &*InsPt);
+  new StoreInst(NII, VASizeLoc, &*InsPt);
+  NII++;
+  AllocaInst *Counter = new AllocaInst(Int64Ty, "",&*InsPt);
+  new StoreInst(NII, Counter, &*InsPt); 
+  NII++;
+  AllocaInst *VAMDLoc = new AllocaInst(VoidPtrTy, "", &*InsPt);
+  new StoreInst(NII, VAMDLoc, &*InsPt);
+
+  // instrument va_arg to increment the counter
+  for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+    for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+      VAArgInst *VI = dyn_cast<VAArgInst>(I++);
+      if(!VI)
+        continue;
+      Constant *One = ConstantInt::get(Int64Ty, 1);
+      LoadInst *OldValue = new LoadInst(Counter, "count", VI);
+      Instruction *NewValue = BinaryOperator::Create(BinaryOperator::Add,
+                                                     OldValue,
+                                                     One,
+                                                     "count",
+                                                     VI);
+      new StoreInst(NewValue, Counter, VI);
+      std::vector<Value *> Args;
+      Instruction *VASize = new LoadInst(VASizeLoc, "", VI);
+      Instruction *VAMetaData = new LoadInst(VAMDLoc, "", VI);
+      Args.push_back(VASize);
+      Args.push_back(OldValue);
+      Args.push_back(ConstantInt::get(Int8Ty, getTypeMarker(VI->getType())));
+      Args.push_back(VAMetaData);
+      Args.push_back(ConstantInt::get(Int32Ty, tagCounter++));
+      Constant *Func = M.getOrInsertFunction("compareTypeAndNumber", VoidTy, Int64Ty, Int64Ty, Int8Ty, VoidPtrTy, Int32Ty, NULL);
+      CallInst::Create(Func, Args.begin(), Args.end(), "", VI);
+    }
+  }
+
+return true;
+}
+
 // Transform Variable Argument functions, by also passing
 // the relavant metadata info
 bool
@@ -156,7 +307,7 @@
   if(F.hasInternalLinkage()) {
     return visitInternalVarArgFunction(M, F);
   }
-    
+
   // create internal clone
   Function *F_clone = CloneFunction(&F);
   F_clone->setName(F.getNameStr() + "internal");
@@ -262,6 +413,30 @@
     }
   }
   assert(VAStart && "Varargs function without a call to VAStart???");
+  for (Function::iterator B = F.begin(), FE = F.end(); B != FE; ++B) {
+    for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+      CallInst *CI = dyn_cast<CallInst>(I++);
+      if(!CI)
+        continue;
+      Function *CalledF = dyn_cast<Function>(CI->getCalledFunction());
+      if(VAListFunctions.find(CalledF) == VAListFunctions.end())
+        continue;
+      std::vector<Value *>Args;
+      Instruction *VASize = new LoadInst(VASizeLoc, "", CI);
+      Instruction *VACounter = new LoadInst(Counter, "", CI);
+      Instruction *VAMetaData = new LoadInst(VAMDLoc, "", CI);
+      Args.push_back(VASize); // toatl count
+      Args.push_back(VACounter); // current count
+      Args.push_back(VAMetaData); // MD
+      for(unsigned i = 1 ;i < CI->getNumOperands(); i++) {
+        // Add the original argument
+        Args.push_back(CI->getOperand(i));
+      }
+      CallInst *CINew = CallInst::Create(VAListFunctions[CalledF], Args.begin(), Args.end(), "", CI);
+      CI->replaceAllUsesWith(CINew);
+      CI->eraseFromParent();
+    }
+  }
 
   // Find all uses of the function
   for(Value::use_iterator ui = F.use_begin(), ue = F.use_end();
@@ -308,7 +483,7 @@
 
 bool
 TypeChecks::visitByValFunction(Module &M, Function &F) {
-  
+
   // check for byval arguments
   bool hasByValArg = false;
   for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {





More information about the llvm-commits mailing list