[llvm-commits] [poolalloc] r132525 - in /poolalloc/trunk: include/assistDS/TypeChecks.h lib/AssistDS/TypeChecks.cpp
Arushi Aggarwal
aggarwa4 at illinois.edu
Thu Jun 2 19:14:26 PDT 2011
Author: aggarwa4
Date: Thu Jun 2 21:14:26 2011
New Revision: 132525
URL: http://llvm.org/viewvc/llvm-project?rev=132525&view=rev
Log:
Add tracking on indirect call targets.
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=132525&r1=132524&r2=132525&view=diff
==============================================================================
--- poolalloc/trunk/include/assistDS/TypeChecks.h (original)
+++ poolalloc/trunk/include/assistDS/TypeChecks.h Thu Jun 2 21:14:26 2011
@@ -16,6 +16,7 @@
#include "assistDS/TypeAnalysis.h"
#include "dsa/TypeSafety.h"
+#include "dsa/AddressTakenAnalysis.h"
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
@@ -33,14 +34,18 @@
private:
std::map<const Type *, unsigned int> UsedTypes;
std::map<Function *, Function *> VAListFunctionsMap;
+ std::map<Function *, Function *> IndFunctionsMap;
std::list<Function *> VAArgFunctions;
std::list<Function *> VAListFunctions;
std::list<Function *> ByValFunctions;
+ std::list<Function *> AddressTakenFunctions;
+ std::set<Instruction*> IndCalls;
// Analysis from other passes.
TargetData *TD;
TypeAnalysis *TA;
dsa::TypeSafety<TDDataStructures> *TS;
+ AddressTakenAnalysis* addrAnalysis;
public:
static char ID;
@@ -52,6 +57,7 @@
AU.addRequired<TargetData>();
AU.addRequired<dsa::TypeSafety<TDDataStructures> >();
AU.addRequired<TypeAnalysis>();
+ AU.addRequired<AddressTakenAnalysis>();
}
bool initShadow(Module &M);
@@ -59,12 +65,13 @@
bool visitCallInst(Module &M, CallInst &CI);
bool visitInvokeInst(Module &M, InvokeInst &CI);
bool visitCallSite(Module &M, CallSite CS);
- bool visitIndirectCallSite(Module &M, CallSite CS);
+ bool visitIndirectCallSite(Module &M, Instruction *I);
bool visitInternalByValFunction(Module &M, Function &F);
bool visitExternalByValFunction(Module &M, Function &F);
bool visitByValFunction(Module &M, Function &F);
bool visitMain(Module &M, Function &F);
bool visitVarArgFunction(Module &M, Function &F);
+ bool visitAddressTakenFunction(Module &M, Function &F);
bool visitVAListFunction(Module &M, Function &F);
bool visitInternalVarArgFunction(Module &M, Function &F);
bool visitLoadInst(Module &M, LoadInst &LI);
Modified: poolalloc/trunk/lib/AssistDS/TypeChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeChecks.cpp?rev=132525&r1=132524&r2=132525&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/TypeChecks.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/TypeChecks.cpp Thu Jun 2 21:14:26 2011
@@ -84,6 +84,7 @@
TD = &getAnalysis<TargetData>();
TA = &getAnalysis<TypeAnalysis>();
+ addrAnalysis = &getAnalysis<AddressTakenAnalysis>();
if(EnableTypeSafeOpt)
TS = &getAnalysis<dsa::TypeSafety<TDDataStructures> >();
@@ -107,6 +108,7 @@
VAListFunctions.clear();
VAArgFunctions.clear();
ByValFunctions.clear();
+ AddressTakenFunctions.clear();
Function *MainF = M.getFunction("main");
if (MainF == 0 || MainF->isDeclaration()) {
@@ -140,6 +142,11 @@
ByValFunctions.push_back(&F);
}
+ // Iterate and find all address taken functions
+ if(addrAnalysis->hasAddressTaken(&F)) {
+ AddressTakenFunctions.push_back(&F);
+ }
+
// Iterate and find all varargs functions
if(F.isVarArg()) {
VAArgFunctions.push_back(&F);
@@ -185,12 +192,7 @@
for(; FI != FE; FI++) {
visitVAListCall(FI->second);
}
- while(!VAArgFunctions.empty()) {
- Function *F = VAArgFunctions.back();
- VAArgFunctions.pop_back();
- assert(F->isVarArg());
- modified |= visitVarArgFunction(M, *F);
- }
+
for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
Function &F = *MI;
if(F.isDeclaration())
@@ -198,7 +200,7 @@
// Loop over all of the instructions in the function,
// adding their return type as well as the types of their operands.
- for (inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE; ++II) {
+ for (inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE;++II) {
Instruction &I = *II;
if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
if (TA->isCopyingStore(SI)) {
@@ -223,6 +225,35 @@
}
}
+ while(!VAArgFunctions.empty()) {
+ Function *F = VAArgFunctions.back();
+ VAArgFunctions.pop_back();
+ assert(F->isVarArg());
+ modified |= visitVarArgFunction(M, *F);
+ }
+
+ while(!AddressTakenFunctions.empty()) {
+ Function *F = AddressTakenFunctions.back();
+ AddressTakenFunctions.pop_back();
+ errs() << F->getNameStr()<<"\n";
+ if(F->isVarArg())
+ continue;
+ visitAddressTakenFunction(M, *F);
+ }
+
+ // visit all the uses of the address taken functions and modify if
+ // visit all the indirect call sites
+ for(std::set<Instruction*>::iterator II = IndCalls.begin(); II != IndCalls.end(); ) {
+ Instruction *I = *II++;
+ modified |= visitIndirectCallSite(M,I);
+ }
+ FI = IndFunctionsMap.begin(), FE = IndFunctionsMap.end();
+ for(;FI!=FE;++FI) {
+ Constant *C = ConstantExpr::getBitCast(FI->second, FI->first->getType());
+ FI->first->replaceAllUsesWith(C);
+ }
+
+
// add a global that contains the mapping from metadata to strings
addTypeMap(M);
@@ -418,6 +449,93 @@
return true;
}
+bool TypeChecks::visitAddressTakenFunction(Module &M, Function &F) {
+ // Clone function
+ // 1. Create the new argument types vector
+ std::vector<const Type*> TP;
+ TP.push_back(Int64Ty); // for count
+ TP.push_back(VoidPtrTy); // for MD
+ for(Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I !=E; ++I) {
+ TP.push_back(I->getType());
+ }
+
+ // 2. Create the new function prototype
+ const FunctionType *NewFTy = FunctionType::get(F.getReturnType(), TP, true);
+ Function *NewF = Function::Create(NewFTy,
+ GlobalValue::InternalLinkage,
+ F.getNameStr() + ".mod",
+ &M);
+
+ // 3. Set the mapping for the args
+ Function::arg_iterator NI = NewF->arg_begin();
+ DenseMap<const Value *, Value*> ValueMap;
+ NI->setName("TotalCount");
+ NI++;
+ NI->setName("MD");
+ NI++;
+ for(Function::arg_iterator II = F.arg_begin(); NI!=NewF->arg_end(); ++II, ++NI) {
+ // Each new argument maps to the argument in the old function
+ // For each of these also copy attributes
+ ValueMap[II] = NI;
+ NI->setName(II->getName());
+ NI->addAttr(F.getAttributes().getParamAttributes(II->getArgNo()+1));
+ }
+
+ // 4. Copy over attributes for the function
+ NewF->setAttributes(NewF->getAttributes()
+ .addAttr(0, F.getAttributes().getRetAttributes()));
+ NewF->setAttributes(NewF->getAttributes().addAttr(~0, F.getAttributes().getFnAttributes()));
+
+ // 5. Perform the cloning
+ SmallVector<ReturnInst*, 100>Returns;
+ CloneFunctionInto(NewF, &F, ValueMap, Returns);
+ IndFunctionsMap[&F] = NewF;
+
+ // Find all uses of the function
+ for(Value::use_iterator ui = F.use_begin(), ue = F.use_end();
+ ui != ue;) {
+ // Check for call sites
+ CallInst *CI = dyn_cast<CallInst>(ui++);
+ if(!CI)
+ continue;
+ std::vector<Value *> Args;
+ unsigned int i;
+ unsigned int NumArgs = CI->getNumOperands() - 1;
+ Value *NumArgsVal = ConstantInt::get(Int32Ty, NumArgs);
+ AllocaInst *AI = new AllocaInst(Int8Ty, NumArgsVal, "", CI);
+ // set the metadata for the varargs in AI
+ for(i = 1; i <CI->getNumOperands(); i++) {
+ Value *Idx[2];
+ Idx[0] = ConstantInt::get(Int32Ty, i - 1 );
+ // For each vararg argument, also add its type information
+ GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(AI,
+ Idx,
+ Idx + 1,
+ "", CI);
+ Constant *C = ConstantInt::get(Int8Ty,
+ getTypeMarker(CI->getOperand(i)->getType()));
+ new StoreInst(C, GEP, CI);
+ }
+
+ // As the first argument pass the number of var_arg arguments
+ Args.push_back(ConstantInt::get(Int64Ty, NumArgs));
+ Args.push_back(AI);
+ for(i = 1 ;i < CI->getNumOperands(); i++) {
+ // Add the original argument
+ Args.push_back(CI->getOperand(i));
+ }
+
+ // Create the new call
+ CallInst *CI_New = CallInst::Create(NewF,
+ Args.begin(), Args.end(),
+ "", CI);
+ CI->replaceAllUsesWith(CI_New);
+ CI->eraseFromParent();
+ }
+
+ return true;
+}
+
// Transform Variable Argument functions, by also passing
// the relavant metadata info
bool TypeChecks::visitVarArgFunction(Module &M, Function &F) {
@@ -614,10 +732,9 @@
Value *NumArgsVal = ConstantInt::get(Int32Ty, NumArgs);
AllocaInst *AI = new AllocaInst(Int8Ty, NumArgsVal, "", CI);
// set the metadata for the varargs in AI
- unsigned int j =0;
for(i = 1; i <CI->getNumOperands(); i++) {
Value *Idx[2];
- Idx[0] = ConstantInt::get(Int32Ty, j++);
+ Idx[0] = ConstantInt::get(Int32Ty, i - 1 );
// For each vararg argument, also add its type information
GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(AI,
Idx,
@@ -643,6 +760,7 @@
CI->replaceAllUsesWith(CI_New);
CI->eraseFromParent();
}
+ IndFunctionsMap[&F] = NewF;
return true;
}
@@ -689,7 +807,7 @@
assert(I->getType()->isPointerTy());
const Type *ETy = (cast<PointerType>(I->getType()))->getElementType();
AllocaInst *AI = new AllocaInst(ETy, "", InsertBefore);
- // Do this before add a load/store pair, so that those uses are not replaced.
+ // Do this before adding the load/store pair, so that those uses are not replaced.
I->replaceAllUsesWith(AI);
LoadInst *LI = new LoadInst(I, "", InsertBefore);
new StoreInst(LI, AI, InsertBefore);
@@ -1084,18 +1202,10 @@
std::vector<Value *> Args;
Args.push_back(BCI);
- Args.push_back(AllocSize);
+ Args.push_back(Size);
Args.push_back(ConstantInt::get(Int32Ty, tagCounter++));
CallInst *CI = CallInst::Create(trackUnInitInst, Args.begin(), Args.end());
- CI->insertAfter(BCI);
- std::vector<Value *> Args1;
- Args1.push_back(BCI);
- Args1.push_back(AllocSize);
- Args1.push_back(ArraySize);
- Args1.push_back(ConstantInt::get(Int32Ty, tagCounter++));
- CallInst *CI_Arr = CallInst::Create(trackArray, Args1.begin(), Args1.end());
- CI_Arr->insertAfter(CI);
-
+ CI->insertAfter(CI_Init);
return true;
}
@@ -1247,9 +1357,9 @@
CI->insertAfter(BCI);
std::vector<Value *> Args1;
Args1.push_back(BCI);
- Args.push_back(Size);
+ Args1.push_back(Size);
CastInst *Num = CastInst::CreateIntegerCast(I->getOperand(1), Int64Ty, false, "", I);
- Args.push_back(Num);
+ Args1.push_back(Num);
Args1.push_back(ConstantInt::get(Int32Ty, tagCounter++));
CallInst *CI_Arr = CallInst::Create(trackArray, Args1.begin(), Args1.end());
CI_Arr->insertAfter(CI);
@@ -1303,14 +1413,58 @@
}
} else {
// indirect call site
- return visitIndirectCallSite(M, CS);
+ IndCalls.insert(CS.getInstruction());
+ return false;
}
return false;
}
-bool TypeChecks::visitIndirectCallSite(Module &M, CallSite CS) {
- Instruction *I = CS.getInstruction();
- I->dump();
+bool TypeChecks::visitIndirectCallSite(Module &M, Instruction *I) {
+ // add the number of arguments as the first argument
+
+ unsigned int NumArgs = I->getNumOperands() - 1;
+ Value *NumArgsVal = ConstantInt::get(Int32Ty, NumArgs);
+
+ AllocaInst *AI = new AllocaInst(Int8Ty, NumArgsVal, "", I);
+ for(unsigned int i = 1; i < I->getNumOperands(); i++) {
+ Value *Idx[2];
+ Idx[0] = ConstantInt::get(Int32Ty, i-1);
+ GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(AI,
+ Idx,
+ Idx + 1,
+ "", I);
+ Constant *C = ConstantInt::get(Int8Ty,
+ getTypeMarker(I->getOperand(i)->getType()));
+ new StoreInst(C, GEP, I);
+ }
+ std::vector<Value *> Args;
+ Args.push_back(ConstantInt::get(Int64Ty, NumArgs));
+ Args.push_back(AI);
+
+ for(unsigned int i = 1; i < I->getNumOperands(); i++)
+ Args.push_back(I->getOperand(i));
+
+ const Type* OrigType = I->getOperand(0)->getType();
+ assert(OrigType->isPointerTy());
+ const FunctionType *FOldType = cast<FunctionType>((cast<PointerType>(OrigType))->getElementType());
+ std::vector<const Type*>TP;
+ TP.push_back(Int64Ty);
+ TP.push_back(VoidPtrTy);
+
+ for(llvm::FunctionType::param_iterator ArgI = FOldType->param_begin(); ArgI != FOldType->param_end(); ++ArgI)
+ TP.push_back(*ArgI);
+
+ const FunctionType *FTy = FunctionType::get(FOldType->getReturnType(), TP, FOldType->isVarArg());
+ CastInst *Func = CastInst::CreatePointerCast(I->getOperand(0), FTy->getPointerTo(), "", I);
+ CallInst *CI_New = CallInst::Create(Func,
+ Args.begin(),
+ Args.end(),
+ "", I);
+ I->replaceAllUsesWith(CI_New);
+ I->eraseFromParent();
+
+
+ // add they types of the argument as the second argument
return false;
}
More information about the llvm-commits
mailing list