[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