[llvm-commits] [poolalloc] r128926 - /poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp

Arushi Aggarwal aggarwa4 at illinois.edu
Tue Apr 5 13:54:12 PDT 2011


Author: aggarwa4
Date: Tue Apr  5 15:54:12 2011
New Revision: 128926

URL: http://llvm.org/viewvc/llvm-project?rev=128926&view=rev
Log:
Added comments and debug printing.

Modified:
    poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp

Modified: poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp?rev=128926&r1=128925&r2=128926&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp Tue Apr  5 15:54:12 2011
@@ -6,6 +6,12 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+// Convert calls of type 
+// call(bitcast F to (...)*) () 
+// to 
+// call F()
+// if the number and types of arguments passed matches.
+//===----------------------------------------------------------------------===//
 #define DEBUG_TYPE "varargfunc"
 
 #include "llvm/Instructions.h"
@@ -22,6 +28,7 @@
 
 using namespace llvm;
 
+// Pass statistics
 STATISTIC(numSimplified, "Number of Calls Simplified");
 
 namespace {
@@ -29,32 +36,55 @@
   public:
     static char ID;
     VarArgsFunc() : ModulePass(&ID) {}
+
+    //
+    // Method: runOnModule()
+    // Description:
+    //  Entry point for this LLVM pass. Search for functions that are
+    //  unnecessarily casted to varargs type, in a CallInst.
+    //  Replace with direct calls to the function
+    //
+    // Inputs:
+    // M - A reference to the LLVM module to transform.
+    //
+    // Outputs:
+    // M - The transformed LLVM module.
+    //
+    // Return value:
+    //  true  - The module was modified.
+    //  false - The module was not modified.
+    //
     bool runOnModule(Module& M) {
-      bool changed = false;
       std::vector<CallInst*> worklist;
+
       for (Module::iterator I = M.begin(); I != M.end(); ++I) {
-        if (!I->isDeclaration() && !I->mayBeOverridden()) {
-          //Call Sites
-          for(Value::use_iterator ui = I->use_begin(), ue = I->use_end();
-              ui != ue; ++ui) 
-            //Bitcast
-            if (Constant *C = dyn_cast<Constant>(ui)) 
-              if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) 
-                if (CE->getOpcode() == Instruction::BitCast) 
-                  if(CE->getOperand(0) == I) 
-                    if(const FunctionType *FTy  = dyn_cast<FunctionType>
-                       ((cast<PointerType>(CE->getType()))->getElementType())) 
-                      //casting to a varargs funtion
-                      if(FTy->isVarArg()) 
-                        for(Value::use_iterator uii = CE->use_begin(),
-                            uee = CE->use_end(); uii != uee; ++uii) 
-                          if (CallInst* CI = dyn_cast<CallInst>(uii)) 
-                            if(CI->getCalledValue() == CE) 
-                               worklist.push_back(CI);
-        }
+        // Go through all the functions
+        if (I->mayBeOverridden()) 
+          continue;
+        //Uses of Function I
+        for(Value::use_iterator ui = I->use_begin(), ue = I->use_end();
+            ui != ue; ++ui) 
+          //Find all casted uses of the function
+          if (Constant *C = dyn_cast<Constant>(ui)) 
+            if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) 
+              if (CE->getOpcode() == Instruction::BitCast) 
+                if(CE->getOperand(0) == I) 
+                  if(const FunctionType *FTy  = dyn_cast<FunctionType>
+                     ((cast<PointerType>(CE->getType()))->getElementType())) 
+                    //casting to a varargs funtion
+                    if(FTy->isVarArg()) { 
+                      // Check if bitcasted Value is used in a callInst
+                      for(Value::use_iterator uii = CE->use_begin(),
+                          uee = CE->use_end(); uii != uee; ++uii) 
+                        if (CallInst* CI = dyn_cast<CallInst>(uii)) 
+                          if(CI->getCalledValue() == CE) { 
+                            // add to a worklist to process
+                            worklist.push_back(CI);
+                          }
+                    }
       }
+      
       // process the worklist
-
       while(!worklist.empty()) {
         CallInst *CI = worklist.back();
         worklist.pop_back();
@@ -66,9 +96,8 @@
         // Or we can discard the returned value.
         if(F->getReturnType() != CI->getType()) {
           if(!CI->use_empty())
-          continue;
+            continue;
         }
-
         // Check if the parameters passed match the expected types of the 
         // formal arguments
         bool change = true;
@@ -79,28 +108,35 @@
             break;
           }
         }
-        
+
         if(change) {
-            // if we want to ignore the returned value, create a new CallInst
-            SmallVector<Value*, 8> Args;
-            for(unsigned j =1;j<CI->getNumOperands();j++) {
-              Args.push_back(CI->getOperand(j));
-            }
-            CallInst *CINew = CallInst::Create(F, Args.begin(), Args.end(), "", CI);
-            if(F->getReturnType() == CI->getType()){ // else means no uses
-              CI->replaceAllUsesWith(CINew);
-            }
-            CI->eraseFromParent();
-            // else just set the function to call the original function.
-          changed = true;
+          // if we want to ignore the returned value, create a new CallInst
+          SmallVector<Value*, 8> Args;
+          for(unsigned j =1;j<CI->getNumOperands();j++) {
+            Args.push_back(CI->getOperand(j));
+          }
+          CallInst *CINew = CallInst::Create(F, Args.begin(), Args.end(), "", CI);
+          if(F->getReturnType() == CI->getType()){ // else means no uses
+            CI->replaceAllUsesWith(CINew);
+          }
+          DEBUG(errs() << "VA:");
+          DEBUG(errs() << "ERASE:");
+          DEBUG(CI->dump());
+          DEBUG(errs() << "VA:");
+          DEBUG(errs() << "ADDED:");
+          DEBUG(CINew->dump());
+          CI->eraseFromParent();
           numSimplified++;
         }
       }
-      return changed;
+      return (numSimplified > 0 );
     }
   };
 }
 
+// Pass ID variable
 char VarArgsFunc::ID = 0;
+
+// Register the Pass
 static RegisterPass<VarArgsFunc>
-X("varargsfunc", "Specialize for ill-defined non-varargs functions");
+X("varargsfunc", "Optimize non-varargs to varargs function casts");





More information about the llvm-commits mailing list