本文整理汇总了C++中CallInst::getOperand方法的典型用法代码示例。如果您正苦于以下问题:C++ CallInst::getOperand方法的具体用法?C++ CallInst::getOperand怎么用?C++ CallInst::getOperand使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CallInst
的用法示例。
在下文中一共展示了CallInst::getOperand方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: AddCatchInfo
/// AddCatchInfo - Extract the personality and type infos from an eh.selector
/// call, and add them to the specified machine basic block.
void llvm::AddCatchInfo(CallInst &I, MachineModuleInfo *MMI,
MachineBasicBlock *MBB) {
// Inform the MachineModuleInfo of the personality for this landing pad.
ConstantExpr *CE = cast<ConstantExpr>(I.getOperand(2));
assert(CE->getOpcode() == Instruction::BitCast &&
isa<Function>(CE->getOperand(0)) &&
"Personality should be a function");
MMI->addPersonality(MBB, cast<Function>(CE->getOperand(0)));
// Gather all the type infos for this landing pad and pass them along to
// MachineModuleInfo.
std::vector<GlobalVariable *> TyInfo;
unsigned N = I.getNumOperands();
for (unsigned i = N - 1; i > 2; --i) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(i))) {
unsigned FilterLength = CI->getZExtValue();
unsigned FirstCatch = i + FilterLength + !FilterLength;
assert (FirstCatch <= N && "Invalid filter length");
if (FirstCatch < N) {
TyInfo.reserve(N - FirstCatch);
for (unsigned j = FirstCatch; j < N; ++j)
TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
MMI->addCatchTypeInfo(MBB, TyInfo);
TyInfo.clear();
}
if (!FilterLength) {
// Cleanup.
MMI->addCleanup(MBB);
} else {
// Filter.
TyInfo.reserve(FilterLength - 1);
for (unsigned j = i + 1; j < FirstCatch; ++j)
TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
MMI->addFilterTypeInfo(MBB, TyInfo);
TyInfo.clear();
}
N = i;
}
}
if (N > 3) {
TyInfo.reserve(N - 3);
for (unsigned j = 3; j < N; ++j)
TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
MMI->addCatchTypeInfo(MBB, TyInfo);
}
}
示例2: getDSNodeHandle
//
// Function: makeFSParameterCallsComplete()
//
// Description:
// Finds calls to sc.fsparameter and fills in the completeness byte which
// is the last argument to such call. The second argument to the function
// is the one which is analyzed for completeness.
//
// Inputs:
// M - Reference to the the module to analyze
//
void
CompleteChecks::makeFSParameterCallsComplete(Module &M)
{
Function *sc_fsparameter = M.getFunction("sc.fsparameter");
if (sc_fsparameter == NULL)
return;
std::set<CallInst *> toComplete;
//
// Iterate over all uses of sc.fsparameter and discover which have a complete
// pointer argument.
//
for (Function::use_iterator i = sc_fsparameter->use_begin();
i != sc_fsparameter->use_end(); ++i) {
CallInst *CI;
CI = dyn_cast<CallInst>(*i);
if (CI == 0 || CI->getCalledFunction() != sc_fsparameter)
continue;
//
// Get the parent function to which this call belongs.
//
Function *P = CI->getParent()->getParent();
Value *PtrOperand = CI->getOperand(2);
DSNode *N = getDSNodeHandle(PtrOperand, P).getNode();
if (N == 0 ||
N->isExternalNode() ||
N->isIncompleteNode() ||
N->isUnknownNode() ||
N->isPtrToIntNode() ||
N->isIntToPtrNode()) {
continue;
}
toComplete.insert(CI);
}
//
// Fill in a 1 for each call instruction that has a complete pointer
// argument.
//
Type *int8 = Type::getInt8Ty(M.getContext());
Constant *complete = ConstantInt::get(int8, 1);
for (std::set<CallInst *>::iterator i = toComplete.begin();
i != toComplete.end();
++i) {
CallInst *CI = *i;
CI->setOperand(4, complete);
}
return;
}
示例3: changeFunctionCall
CallInst* FunctionCalls::changeFunctionCall(Module &module, Change* change) {
FunctionChange *funChange = (FunctionChange*)change;
CallInst *oldCallInst = dyn_cast<CallInst>(funChange->getValue());
CallInst *newCallInst = NULL;
string oldFunction = oldCallInst->getCalledFunction()->getName();
string newFunction = funChange->getSwitch();
// TODO: use the types vector to not assume signature
Function *newCallee = module.getFunction(newFunction);
if (newCallee) {
errs() << "Changing function call from " << oldFunction << " to " << newFunction << "\n";
if (oldFunction != newFunction) {
// retrieving original operand
Value *oldOperand = oldCallInst->getOperand(0);
// downcasting operand
Type *fType = Type::getFloatTy(module.getContext());
FPTruncInst *newOperand = new FPTruncInst(oldOperand, fType, "", oldCallInst);
// populating array of operands
vector<Value*> operands;
operands.push_back(newOperand);
ArrayRef<Value*> *arrayRefOperands = new ArrayRef<Value*>(operands);
// creating the new CallInst
newCallInst = CallInst::Create(newCallee, *arrayRefOperands, "newCall", oldCallInst);
// casting result to double
Type *dType = Type::getDoubleTy(module.getContext());
FPExtInst *result = new FPExtInst(newCallInst, dType, "", oldCallInst);
// replacing all uses of call instruction
oldCallInst->replaceAllUsesWith(result);
// deleting old callInst
oldCallInst->eraseFromParent();
errs() << "\tChange was successful\n";
}
else {
errs() << "\tNo change required\n";
}
}
else {
errs() << "\tDid not find function " << newFunction << "\n";
}
return newCallInst;
}
示例4: handleCallInst
void LLVMDefUseAnalysis::handleCallInst(LLVMNode *node)
{
CallInst *CI = cast<CallInst>(node->getKey());
if (CI->isInlineAsm()) {
handleInlineAsm(node);
return;
}
Function *func
= dyn_cast<Function>(CI->getCalledValue()->stripPointerCasts());
if (func) {
if (func->isIntrinsic() && !isa<DbgInfoIntrinsic>(CI)) {
handleIntrinsicCall(node, CI);
return;
}
// for realloc, we need to make it data dependent on the
// memory it reallocates, since that is the memory it copies
if (func->size() == 0) {
using analysis::AllocationFunction;
auto type = _options.getAllocationFunction(func->getName());
if (type == AllocationFunction::REALLOC) {
addDataDependence(node, CI, CI->getOperand(0), Offset::UNKNOWN /* FIXME */);
} else if (type == AllocationFunction::NONE) {
handleUndefinedCall(node, CI);
}// else {
// we do not want to do anything for the memory
// allocation functions
// }
// the function is undefined, so do not even try to
// add the edges from return statements
return;
}
}
// add edges from the return nodes of subprocedure
// to the call (if the call returns something)
for (LLVMDependenceGraph *subgraph : node->getSubgraphs())
addReturnEdge(node, subgraph);
}
示例5: handleInlineAsm
void LLVMDefUseAnalysis::handleInlineAsm(LLVMNode *callNode)
{
CallInst *CI = cast<CallInst>(callNode->getValue());
LLVMDependenceGraph *dg = callNode->getDG();
// the last operand is the asm itself, so iterate only to e - 1
for (unsigned i = 0, e = CI->getNumOperands(); i < e - 1; ++i) {
Value *opVal = CI->getOperand(i);
if (!opVal->getType()->isPointerTy())
continue;
LLVMNode *opNode = dg->getNode(opVal->stripInBoundsOffsets());
if (!opNode) {
// FIXME: ConstantExpr
llvmutils::printerr("WARN: unhandled inline asm operand: ", opVal);
continue;
}
assert(opNode && "Do not have an operand for inline asm");
// if nothing else, this call at least uses the operands
opNode->addDataDependence(callNode);
}
}
示例6: visitCallInst
void visitCallInst(CallInst &I) {
string intrinsic = I.getCalledFunction()->getName().str();
if(intrinsic.find("modmul") != -1) {
CallInst *enterMontpro1 = enterMontgomery(I.getOperand(0), I.getOperand(2), &I);
CallInst *enterMontpro2 = enterMontgomery(I.getOperand(1), I.getOperand(2), &I);
CallInst *mulMontpro = mulMontgomery(I.getName().str(), enterMontpro1, enterMontpro2, I.getOperand(2), &I);
CallInst *exitMontpro = leaveMontgomery(mulMontpro, I.getOperand(2), &I);
I.replaceAllUsesWith(exitMontpro);
I.removeFromParent();
} else if(intrinsic.find("modexp") != -1) {
CallInst *enterMontpro1 = enterMontgomery(I.getOperand(0), I.getOperand(2), &I);
CallInst *expMontpro = expMontgomery(I.getName().str(), enterMontpro1, I.getOperand(1), I.getOperand(2), &I);
CallInst *exitMontpro = leaveMontgomery(expMontpro, I.getOperand(2), &I);
I.replaceAllUsesWith(exitMontpro);
I.eraseFromParent();
}
}
示例7: assert
//
// Function: makeCStdLibCallsComplete()
//
// Description:
// Fills in completeness information for all calls of a given CStdLib function
// assumed to be of the form:
//
// pool_X(POOL *p1, ..., POOL *pN, void *a1, ..., void *aN, ..., uint8_t c);
//
// Specifically, this function assumes that there are as many pointer arguments
// to check as there are initial pool arguments, and the pointer arguments
// follow the pool arguments in corresponding order. Also, it is assumed that
// the final argument to the function is a byte sized bit vector.
//
// This function fills in this final byte with a constant value whose ith
// bit is set exactly when the ith pointer argument is complete.
//
// Inputs:
//
// F - A pointer to the CStdLib function appearing in the module
// (non-null).
// PoolArgs - The number of initial pool arguments for which a
// corresponding pointer value requires a completeness check
// (required to be at most 8).
//
void
CompleteChecks::makeCStdLibCallsComplete(Function *F, unsigned PoolArgs) {
assert(F != 0 && "Null function argument!");
assert(PoolArgs <= 8 && \
"Only up to 8 arguments are supported by CStdLib completeness checks!");
Value::use_iterator U = F->use_begin();
Value::use_iterator E = F->use_end();
//
// Hold the call instructions that need changing.
//
typedef std::pair<CallInst *, uint8_t> VectorReplacement;
std::set<VectorReplacement> callsToChange;
Type *int8ty = Type::getInt8Ty(F->getContext());
FunctionType *F_type = F->getFunctionType();
//
// Verify the type of the function is as expected.
//
// There should be as many pointer parameters to check for completeness
// as there are pool parameters. The last parameter should be a byte.
//
assert(F_type->getNumParams() >= PoolArgs * 2 && \
"Not enough arguments to transformed CStdLib function call!");
for (unsigned arg = PoolArgs; arg < PoolArgs * 2; ++arg)
assert(isa<PointerType>(F_type->getParamType(arg)) && \
"Expected pointer argument to function!");
//
// This is the position of the vector operand in the call.
//
unsigned vect_position = F_type->getNumParams();
assert(F_type->getParamType(vect_position - 1) == int8ty && \
"Last parameter to the function should be a byte!");
//
// Iterate over all calls of the function in the module, computing the
// vectors for each call as it is found.
//
for (; U != E; ++U) {
CallInst *CI;
if ((CI = dyn_cast<CallInst>(*U)) && \
CI->getCalledValue()->stripPointerCasts() == F) {
uint8_t vector = 0x0;
//
// Get the parent function to which this instruction belongs.
//
Function *P = CI->getParent()->getParent();
//
// Iterate over the pointer arguments that need completeness checking
// and build the completeness vector.
//
for (unsigned arg = 0; arg < PoolArgs; ++arg) {
bool complete = true;
//
// Go past all the pool arguments to get the pointer to check.
//
Value *V = CI->getOperand(1 + PoolArgs + arg);
//
// Check for completeness of the pointer using DSA and
// set the bit in the vector accordingly.
//
DSNode *N;
if ((N = getDSNodeHandle(V, P).getNode()) &&
(N->isExternalNode() || N->isIncompleteNode() ||
N->isUnknownNode() || N->isIntToPtrNode() ||
N->isPtrToIntNode()) ) {
//.........这里部分代码省略.........
示例8: runOnModule
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass.
// Clone functions that take GEPs as arguments
//
// 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 GEPExprArgs::runOnModule(Module& M) {
bool changed;
do {
changed = false;
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;) {
CallInst *CI = dyn_cast<CallInst>(I++);
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->isVarArg())
continue;
// find the argument we must replace
Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
unsigned argNum = 1;
for(; argNum < CI->getNumOperands();argNum++, ++ai) {
if(ai->use_empty())
continue;
if (isa<GEPOperator>(CI->getOperand(argNum)))
break;
}
// if no argument was a GEP operator to be changed
if(ai == ae)
continue;
GEPOperator *GEP = dyn_cast<GEPOperator>(CI->getOperand(argNum));
if(!GEP->hasAllConstantIndices())
continue;
// Construct the new Type
// Appends the struct Type at the beginning
std::vector<Type*>TP;
TP.push_back(GEP->getPointerOperand()->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
FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
Function *NewF;
numSimplified++;
if(numSimplified > 800)
return true;
NewF = Function::Create(NewFTy,
GlobalValue::InternalLinkage,
F->getName().str() + ".TEST",
&M);
Function::arg_iterator NI = NewF->arg_begin();
NI->setName("GEParg");
++NI;
ValueToValueMapTy ValueMap;
for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) {
ValueMap[II] = NI;
NI->setName(II->getName());
NI->addAttr(F->getAttributes().getParamAttributes(II->getArgNo() + 1));
}
NewF->setAttributes(NewF->getAttributes().addAttr(
0, F->getAttributes().getRetAttributes()));
// Perform the cloning.
SmallVector<ReturnInst*,100> Returns;
CloneFunctionInto(NewF, F, ValueMap, false, Returns);
std::vector<Value*> fargs;
for(Function::arg_iterator ai = NewF->arg_begin(),
ae= NewF->arg_end(); ai != ae; ++ai) {
fargs.push_back(ai);
}
//.........这里部分代码省略.........
示例9: visitCallInst
void TracingNoGiri::visitCallInst(CallInst &CI) {
// Attempt to get the called function.
Function *CalledFunc = CI.getCalledFunction();
if (!CalledFunc)
return;
// Do not instrument calls to tracing run-time functions or debug functions.
if (isTracerFunction(CalledFunc))
return;
if (!CalledFunc->getName().str().compare(0,9,"llvm.dbg."))
return;
// Instrument external calls which can have invariants on its return value
if (CalledFunc->isDeclaration() && CalledFunc->isIntrinsic()) {
// Instrument special external calls which loads/stores
// e.g. strlen(), strcpy(), memcpy() etc.
visitSpecialCall(CI);
return;
}
// If the called value is inline assembly code, then don't instrument it.
if (isa<InlineAsm>(CI.getCalledValue()->stripPointerCasts()))
return;
instrumentLock(&CI);
// Get the ID of the store instruction.
Value *CallID = ConstantInt::get(Int32Type, lsNumPass->getID(&CI));
// Get the called function value and cast it to a void pointer.
Value *FP = castTo(CI.getCalledValue(), VoidPtrType, "", &CI);
// Create the call to the run-time to record the call instruction.
std::vector<Value *> args = make_vector<Value *>(CallID, FP, 0);
// Do not add calls to function call stack for external functions
// as return records won't be used/needed for them, so call a special record function
// FIXME!!!! Do we still need it after adding separate return records????
Instruction *RC;
if (CalledFunc->isDeclaration())
RC = CallInst::Create(RecordExtCall, args, "", &CI);
else
RC = CallInst::Create(RecordCall, args, "", &CI);
instrumentUnlock(RC);
// Create the call to the run-time to record the return of call instruction.
CallInst *CallInst = CallInst::Create(RecordReturn, args, "", &CI);
CI.moveBefore(CallInst);
instrumentLock(CallInst);
instrumentUnlock(CallInst);
++NumCalls; // Update statistics
// The best way to handle external call is to set a flag before calling ext fn and
// use that to determine if an internal function is called from ext fn. It flag can be
// reset afterwards and restored to its original value before returning to ext code.
// FIXME!!!! LATER
#if 0
if (CalledFunc->isDeclaration() &&
CalledFunc->getName().str() == "pthread_create") {
// If pthread_create is called then handle it specially as it calls
// functions externally and add an extra call for the externally
// called functions with the same id so that returns can match with it.
// In addition to a function call to pthread_create.
// Get the external function pointer operand and cast it to a void pointer
Value *FP = castTo(CI.getOperand(2), VoidPtrType, "", &CI);
// Create the call to the run-time to record the call instruction.
std::vector<Value *> argsExt = make_vector<Value *>(CallID, FP, 0);
CallInst = CallInst::Create(RecordCall, argsExt, "", &CI);
CI.moveBefore(CallInst);
// Update statistics
++Calls;
// For, both external functions and internal/ext functions called from
// external functions, return records are not useful as they won't be used.
// Since, we won't create return records for them, simply update the call
// stack to mark the end of function call.
//args = make_vector<Value *>(CallID, FP, 0);
//CallInst::Create(RecordExtCallRet, args.begin(), args.end(), "", &CI);
// Create the call to the run-time to record the return of call instruction.
CallInst::Create(RecordReturn, argsExt, "", &CI);
}
#endif
// Instrument special external calls which loads/stores
// like strlen, strcpy, memcpy etc.
visitSpecialCall(CI);
}
示例10: visitSpecialCall
bool TracingNoGiri::visitSpecialCall(CallInst &CI) {
Function *CalledFunc = CI.getCalledFunction();
// We do not support indirect calls to special functions.
if (CalledFunc == nullptr)
return false;
// Do not consider a function special if it has a function body; in this
// case, the programmer has supplied his or her version of the function, and
// we will instrument it.
if (!CalledFunc->isDeclaration())
return false;
// Check the name of the function against a list of known special functions.
std::string name = CalledFunc->getName().str();
if (name.substr(0,12) == "llvm.memset.") {
instrumentLock(&CI);
// Get the destination pointer and cast it to a void pointer.
Value *dstPointer = CI.getOperand(0);
dstPointer = castTo(dstPointer, VoidPtrType, dstPointer->getName(), &CI);
// Get the number of bytes that will be written into the buffer.
Value *NumElts = CI.getOperand(2);
// Get the ID of the external funtion call instruction.
Value *CallID = ConstantInt::get(Int32Type, lsNumPass->getID(&CI));
// Create the call to the run-time to record the external call instruction.
std::vector<Value *> args = make_vector(CallID, dstPointer, NumElts, 0);
CallInst::Create(RecordStore, args, "", &CI);
instrumentUnlock(&CI);
++NumExtFuns; // Update statistics
return true;
} else if (name.substr(0,12) == "llvm.memcpy." ||
name.substr(0,13) == "llvm.memmove." ||
name == "strcpy") {
instrumentLock(&CI);
/* Record Load src, [CI] Load dst [CI] */
// Get the destination and source pointers and cast them to void pointers.
Value *dstPointer = CI.getOperand(0);
Value *srcPointer = CI.getOperand(1);
dstPointer = castTo(dstPointer, VoidPtrType, dstPointer->getName(), &CI);
srcPointer = castTo(srcPointer, VoidPtrType, srcPointer->getName(), &CI);
// Get the ID of the ext fun call instruction.
Value *CallID = ConstantInt::get(Int32Type, lsNumPass->getID(&CI));
// Create the call to the run-time to record the loads and stores of
// external call instruction.
if(name == "strcpy") {
// FIXME: If the tracer function should be inserted before or after????
std::vector<Value *> args = make_vector(CallID, srcPointer, 0);
CallInst::Create(RecordStrLoad, args, "", &CI);
args = make_vector(CallID, dstPointer, 0);
CallInst *recStore = CallInst::Create(RecordStrStore, args, "", &CI);
CI.moveBefore(recStore);
} else {
// get the num elements to be transfered
Value *NumElts = CI.getOperand(2);
std::vector<Value *> args = make_vector(CallID, srcPointer, NumElts, 0);
CallInst::Create(RecordLoad, args, "", &CI);
args = make_vector(CallID, dstPointer, NumElts, 0);
CallInst::Create(RecordStore, args, "", &CI);
}
instrumentUnlock(&CI);
++NumExtFuns; // Update statistics
return true;
} else if (name == "strcat") { /* Record Load dst, Load Src, Store dst-end before call inst */
instrumentLock(&CI);
// Get the destination and source pointers and cast them to void pointers.
Value *dstPointer = CI.getOperand(0);
Value *srcPointer = CI.getOperand(1);
dstPointer = castTo(dstPointer, VoidPtrType, dstPointer->getName(), &CI);
srcPointer = castTo(srcPointer, VoidPtrType, srcPointer->getName(), &CI);
// Get the ID of the ext fun call instruction.
Value *CallID = ConstantInt::get(Int32Type, lsNumPass->getID(&CI));
// Create the call to the run-time to record the loads and stores of
// external call instruction.
// CHECK: If the tracer function should be inserted before or after????
std::vector<Value *> args = make_vector(CallID, dstPointer, 0);
CallInst::Create(RecordStrLoad, args, "", &CI);
args = make_vector(CallID, srcPointer, 0);
CallInst::Create(RecordStrLoad, args, "", &CI);
// Record the addresses before concat as they will be lost after concat
args = make_vector(CallID, dstPointer, srcPointer, 0);
CallInst::Create(RecordStrcatStore, args, "", &CI);
instrumentUnlock(&CI);
++NumExtFuns; // Update statistics
return true;
} else if (name == "strlen") { /* Record Load */
instrumentLock(&CI);
//.........这里部分代码省略.........
示例11: runOnModule
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass.
// Search for all call sites to casted functions.
// Check if they only differ in an argument type
// Cast the argument, and call the original 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 ArgCast::runOnModule(Module& M) {
std::vector<CallInst*> worklist;
for (Module::iterator I = M.begin(); I != M.end(); ++I) {
if (I->mayBeOverridden())
continue;
// Find all uses of this function
for(Value::user_iterator ui = I->user_begin(), ue = I->user_end(); ui != ue; ) {
// check if is ever casted to a different function type
ConstantExpr *CE = dyn_cast<ConstantExpr>(*ui++);
if(!CE)
continue;
if (CE->getOpcode() != Instruction::BitCast)
continue;
if(CE->getOperand(0) != I)
continue;
const PointerType *PTy = dyn_cast<PointerType>(CE->getType());
if (!PTy)
continue;
const Type *ETy = PTy->getElementType();
const FunctionType *FTy = dyn_cast<FunctionType>(ETy);
if(!FTy)
continue;
// casting to a varargs funtion
// or function with same number of arguments
// possibly varying types of arguments
if(FTy->getNumParams() != I->arg_size() && !FTy->isVarArg())
continue;
for(Value::user_iterator uii = CE->user_begin(),
uee = CE->user_end(); uii != uee; ++uii) {
// Find all uses of the casted value, and check if it is
// used in a Call Instruction
if (CallInst* CI = dyn_cast<CallInst>(*uii)) {
// Check that it is the called value, and not an argument
if(CI->getCalledValue() != CE)
continue;
// Check that the number of arguments passed, and expected
// by the function are the same.
if(!I->isVarArg()) {
if(CI->getNumOperands() != I->arg_size() + 1)
continue;
} else {
if(CI->getNumOperands() < I->arg_size() + 1)
continue;
}
// If so, add to worklist
worklist.push_back(CI);
}
}
}
}
// Proces the worklist of potential call sites to transform
while(!worklist.empty()) {
CallInst *CI = worklist.back();
worklist.pop_back();
// Get the called Function
Function *F = cast<Function>(CI->getCalledValue()->stripPointerCasts());
const FunctionType *FTy = F->getFunctionType();
SmallVector<Value*, 8> Args;
unsigned i =0;
for(i =0; i< FTy->getNumParams(); ++i) {
Type *ArgType = CI->getOperand(i+1)->getType();
Type *FormalType = FTy->getParamType(i);
// If the types for this argument match, just add it to the
// parameter list. No cast needs to be inserted.
if(ArgType == FormalType) {
Args.push_back(CI->getOperand(i+1));
}
else if(ArgType->isPointerTy() && FormalType->isPointerTy()) {
CastInst *CastI = CastInst::CreatePointerCast(CI->getOperand(i+1),
FormalType, "", CI);
Args.push_back(CastI);
} else if (ArgType->isIntegerTy() && FormalType->isIntegerTy()) {
unsigned SrcBits = ArgType->getScalarSizeInBits();
unsigned DstBits = FormalType->getScalarSizeInBits();
if(SrcBits > DstBits) {
CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
FormalType, true, "", CI);
//.........这里部分代码省略.........
示例12: runOnModule
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass.
// If a function returns a struct, make it return
// a pointer to the struct.
//
// 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 StructRet::runOnModule(Module& M) {
const llvm::DataLayout targetData(&M);
std::vector<Function*> worklist;
for (Module::iterator I = M.begin(); I != M.end(); ++I)
if (!I->mayBeOverridden()) {
if(I->hasAddressTaken())
continue;
if(I->getReturnType()->isStructTy()) {
worklist.push_back(I);
}
}
while(!worklist.empty()) {
Function *F = worklist.back();
worklist.pop_back();
Type *NewArgType = F->getReturnType()->getPointerTo();
// Construct the new Type
std::vector<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());
}
FunctionType *NFTy = FunctionType::get(F->getReturnType(), TP, F->isVarArg());
// Create the new function body and insert it into the module.
Function *NF = Function::Create(NFTy,
F->getLinkage(),
F->getName(), &M);
ValueToValueMapTy 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) {
ValueMap[II] = NI;
NI->setName(II->getName());
AttributeSet attrs = F->getAttributes().getParamAttributes(II->getArgNo() + 1);
if (!attrs.isEmpty())
NI->addAttr(attrs);
}
// Perform the cloning.
SmallVector<ReturnInst*,100> Returns;
if (!F->isDeclaration())
CloneFunctionInto(NF, F, ValueMap, false, Returns);
std::vector<Value*> fargs;
for(Function::arg_iterator ai = NF->arg_begin(),
ae= NF->arg_end(); ai != ae; ++ai) {
fargs.push_back(ai);
}
NF->setAttributes(NF->getAttributes().addAttributes(
M.getContext(), 0, F->getAttributes().getRetAttributes()));
NF->setAttributes(NF->getAttributes().addAttributes(
M.getContext(), ~0, F->getAttributes().getFnAttributes()));
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;
LoadInst *LI = dyn_cast<LoadInst>(RI->getOperand(0));
assert(LI && "Return should be preceded by a load instruction");
IRBuilder<> Builder(RI);
Builder.CreateMemCpy(fargs.at(0),
LI->getPointerOperand(),
targetData.getTypeStoreSize(LI->getType()),
targetData.getPrefTypeAlignment(LI->getType()));
}
}
for(Value::use_iterator ui = F->use_begin(), ue = F->use_end();
ui != ue; ) {
CallInst *CI = dyn_cast<CallInst>(*ui++);
if(!CI)
continue;
if(CI->getCalledFunction() != F)
continue;
if(CI->hasByValArgument())
continue;
AllocaInst *AllocaNew = new AllocaInst(F->getReturnType(), 0, "", CI);
//.........这里部分代码省略.........
示例13: translateKnownIntrinsic
bool IRTranslator::translateKnownIntrinsic(const CallInst &CI,
Intrinsic::ID ID) {
unsigned Op = 0;
switch (ID) {
default: return false;
case Intrinsic::uadd_with_overflow: Op = TargetOpcode::G_UADDE; break;
case Intrinsic::sadd_with_overflow: Op = TargetOpcode::G_SADDO; break;
case Intrinsic::usub_with_overflow: Op = TargetOpcode::G_USUBE; break;
case Intrinsic::ssub_with_overflow: Op = TargetOpcode::G_SSUBO; break;
case Intrinsic::umul_with_overflow: Op = TargetOpcode::G_UMULO; break;
case Intrinsic::smul_with_overflow: Op = TargetOpcode::G_SMULO; break;
case Intrinsic::memcpy:
return translateMemcpy(CI);
case Intrinsic::eh_typeid_for: {
GlobalValue *GV = ExtractTypeInfo(CI.getArgOperand(0));
unsigned Reg = getOrCreateVReg(CI);
unsigned TypeID = MIRBuilder.getMF().getMMI().getTypeIDFor(GV);
MIRBuilder.buildConstant(Reg, TypeID);
return true;
}
case Intrinsic::objectsize: {
// If we don't know by now, we're never going to know.
const ConstantInt *Min = cast<ConstantInt>(CI.getArgOperand(1));
MIRBuilder.buildConstant(getOrCreateVReg(CI), Min->isZero() ? -1ULL : 0);
return true;
}
case Intrinsic::stackguard:
getStackGuard(getOrCreateVReg(CI));
return true;
case Intrinsic::stackprotector: {
MachineFunction &MF = MIRBuilder.getMF();
LLT PtrTy{*CI.getArgOperand(0)->getType(), *DL};
unsigned GuardVal = MRI->createGenericVirtualRegister(PtrTy);
getStackGuard(GuardVal);
AllocaInst *Slot = cast<AllocaInst>(CI.getArgOperand(1));
MIRBuilder.buildStore(
GuardVal, getOrCreateVReg(*Slot),
*MF.getMachineMemOperand(
MachinePointerInfo::getFixedStack(MF, getOrCreateFrameIndex(*Slot)),
MachineMemOperand::MOStore | MachineMemOperand::MOVolatile,
PtrTy.getSizeInBits() / 8, 8));
return true;
}
}
LLT Ty{*CI.getOperand(0)->getType(), *DL};
LLT s1 = LLT::scalar(1);
unsigned Width = Ty.getSizeInBits();
unsigned Res = MRI->createGenericVirtualRegister(Ty);
unsigned Overflow = MRI->createGenericVirtualRegister(s1);
auto MIB = MIRBuilder.buildInstr(Op)
.addDef(Res)
.addDef(Overflow)
.addUse(getOrCreateVReg(*CI.getOperand(0)))
.addUse(getOrCreateVReg(*CI.getOperand(1)));
if (Op == TargetOpcode::G_UADDE || Op == TargetOpcode::G_USUBE) {
unsigned Zero = MRI->createGenericVirtualRegister(s1);
EntryBuilder.buildConstant(Zero, 0);
MIB.addUse(Zero);
}
MIRBuilder.buildSequence(getOrCreateVReg(CI), Res, 0, Overflow, Width);
return true;
}
示例14: runOnModule
bool TypeChecksOpt::runOnModule(Module &M) {
TS = &getAnalysis<dsa::TypeSafety<TDDataStructures> >();
// Create the necessary prototypes
VoidTy = IntegerType::getVoidTy(M.getContext());
Int8Ty = IntegerType::getInt8Ty(M.getContext());
Int32Ty = IntegerType::getInt32Ty(M.getContext());
Int64Ty = IntegerType::getInt64Ty(M.getContext());
VoidPtrTy = PointerType::getUnqual(Int8Ty);
TypeTagTy = Int8Ty;
TypeTagPtrTy = PointerType::getUnqual(TypeTagTy);
Constant *memsetF = M.getOrInsertFunction ("llvm.memset.i64", VoidTy,
VoidPtrTy,
Int8Ty,
Int64Ty,
Int32Ty,
NULL);
trackGlobal = M.getOrInsertFunction("trackGlobal",
VoidTy,
VoidPtrTy,/*ptr*/
TypeTagTy,/*type*/
Int64Ty,/*size*/
Int32Ty,/*tag*/
NULL);
trackInitInst = M.getOrInsertFunction("trackInitInst",
VoidTy,
VoidPtrTy,/*ptr*/
Int64Ty,/*size*/
Int32Ty,/*tag*/
NULL);
trackUnInitInst = M.getOrInsertFunction("trackUnInitInst",
VoidTy,
VoidPtrTy,/*ptr*/
Int64Ty,/*size*/
Int32Ty,/*tag*/
NULL);
trackStoreInst = M.getOrInsertFunction("trackStoreInst",
VoidTy,
VoidPtrTy,/*ptr*/
TypeTagTy,/*type*/
Int64Ty,/*size*/
Int32Ty,/*tag*/
NULL);
checkTypeInst = M.getOrInsertFunction("checkType",
VoidTy,
TypeTagTy,/*type*/
Int64Ty,/*size*/
TypeTagPtrTy,
VoidPtrTy,/*ptr*/
Int32Ty,/*tag*/
NULL);
copyTypeInfo = M.getOrInsertFunction("copyTypeInfo",
VoidTy,
VoidPtrTy,/*dest ptr*/
VoidPtrTy,/*src ptr*/
Int64Ty,/*size*/
Int32Ty,/*tag*/
NULL);
setTypeInfo = M.getOrInsertFunction("setTypeInfo",
VoidTy,
VoidPtrTy,/*dest ptr*/
TypeTagPtrTy,/*metadata*/
Int64Ty,/*size*/
TypeTagTy,
VoidPtrTy,
Int32Ty,/*tag*/
NULL);
trackStringInput = M.getOrInsertFunction("trackStringInput",
VoidTy,
VoidPtrTy,
Int32Ty,
NULL);
getTypeTag = M.getOrInsertFunction("getTypeTag",
VoidTy,
VoidPtrTy, /*ptr*/
Int64Ty, /*size*/
TypeTagPtrTy, /*dest for type tag*/
Int32Ty, /*tag*/
NULL);
MallocFunc = M.getFunction("malloc");
for(Value::use_iterator User = trackGlobal->use_begin(); User != trackGlobal->use_end(); ++User) {
CallInst *CI = dyn_cast<CallInst>(*User);
assert(CI);
if(TS->isTypeSafe(CI->getOperand(1)->stripPointerCasts(), CI->getParent()->getParent())) {
std::vector<Value*>Args;
Args.push_back(CI->getOperand(1));
Args.push_back(CI->getOperand(3));
Args.push_back(CI->getOperand(4));
CallInst::Create(trackInitInst, Args, "", CI);
toDelete.push_back(CI);
}
}
for(Value::use_iterator User = checkTypeInst->use_begin(); User != checkTypeInst->use_end(); ++User) {
CallInst *CI = dyn_cast<CallInst>(*User);
assert(CI);
if(TS->isTypeSafe(CI->getOperand(4)->stripPointerCasts(), CI->getParent()->getParent())) {
//.........这里部分代码省略.........
示例15: parseName
string esp::parseName(Value *value){
// has existed
if(names.find(value) != names.end())
return names[value];
string name = "";
Value *current = value;
/*
bool continueFlag = true;
do{
if(isa<Instruction > (current)){
Instruction* inst = dyn_cast<Instruction>(current);
unsigned op = inst->getOpcode();
switch(op){
case Instruction::Ret :{
break;
}
case Instruction::Br :{
break;
}
case Instruction::Switch :{
break;
}
case Instruction::Call :{
CallInst *callinst = (CallInst*) current;
if (((CallInst*) current)->getCalledFunction() != NULL) {
name += string("@")+((CallInst*) current)->getCalledFunction()->getNameStr() + "(";
} else {
name += string("@[funcPTR](");
name += ((CallInst*) current)->getCalledValue()->getNameStr();
}
for (unsigned i = 1; i < callinst->getNumOperands(); i++) {
name += esp::parseName(callinst->getOperand(i));
}
name += string(")");
continueFlag = false;
break;
}
case Instruction::PHI :{
name += string("PHI[");
name += current->getNameStr();
PHINode *phi = (PHINode*) current;
for (unsigned i = 0; i < phi->getNumIncomingValues(); i++) {
Value *incoming = phi->getIncomingValue(i);
if (i != 0) name += ",";
if (!hasLoop(incoming)) {
if (!incoming->hasName()) {
name += esp::parseName(incoming);
} else {
name += incoming->getNameStr();
}
}
}
name += std::string("]");
continueFlag = false;
break;
}
case Instruction::Select :{
break;
}
case Instruction::Add :{
name += "+";
name += parseBinaryOpName(inst);
break;
}
case Instruction::Sub :{
name += "-";
name += parseBinaryOpName(inst);
break;
}
case Instruction::Mul :{
name += "*";
name += parseBinaryOpName(inst);
break;
}
case Instruction::UDiv :{
name += "/";
name += parseBinaryOpName(inst);
break;
}
case Instruction::SDiv :{
name += "//";
name += parseBinaryOpName(inst);
break;
//.........这里部分代码省略.........