本文整理汇总了C++中InvokeInst::getUnwindDest方法的典型用法代码示例。如果您正苦于以下问题:C++ InvokeInst::getUnwindDest方法的具体用法?C++ InvokeInst::getUnwindDest怎么用?C++ InvokeInst::getUnwindDest使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类InvokeInst
的用法示例。
在下文中一共展示了InvokeInst::getUnwindDest方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CallSite
CallSite GNUstep::IMPCacher::SplitSend(CallSite msgSend)
{
BasicBlock *lookupBB = msgSend->getParent();
Function *F = lookupBB->getParent();
Module *M = F->getParent();
Function *send = M->getFunction("objc_msgSend");
Function *send_stret = M->getFunction("objc_msgSend_stret");
Function *send_fpret = M->getFunction("objc_msgSend_fpret");
Value *self;
Value *cmd;
int selfIndex = 0;
if ((msgSend.getCalledFunction() == send) ||
(msgSend.getCalledFunction() == send_fpret)) {
self = msgSend.getArgument(0);
cmd = msgSend.getArgument(1);
} else if (msgSend.getCalledFunction() == send_stret) {
selfIndex = 1;
self = msgSend.getArgument(1);
cmd = msgSend.getArgument(2);
} else {
abort();
return CallSite();
}
CGBuilder B(&F->getEntryBlock(), F->getEntryBlock().begin());
Value *selfPtr = B.CreateAlloca(self->getType());
B.SetInsertPoint(msgSend.getInstruction());
B.CreateStore(self, selfPtr, true);
LLVMType *impTy = msgSend.getCalledValue()->getType();
LLVMType *slotTy = PointerType::getUnqual(StructType::get(PtrTy, PtrTy, PtrTy,
IntTy, impTy, PtrTy, NULL));
Value *slot;
Constant *lookupFn = M->getOrInsertFunction("objc_msg_lookup_sender",
slotTy, selfPtr->getType(), cmd->getType(), PtrTy, NULL);
if (msgSend.isCall()) {
slot = B.CreateCall3(lookupFn, selfPtr, cmd, Constant::getNullValue(PtrTy));
} else {
InvokeInst *inv = cast<InvokeInst>(msgSend.getInstruction());
BasicBlock *callBB = SplitBlock(lookupBB, msgSend.getInstruction(), Owner);
removeTerminator(lookupBB);
B.SetInsertPoint(lookupBB);
slot = B.CreateInvoke3(lookupFn, callBB, inv->getUnwindDest(), selfPtr, cmd,
Constant::getNullValue(PtrTy));
addPredecssor(inv->getUnwindDest(), msgSend->getParent(), lookupBB);
B.SetInsertPoint(msgSend.getInstruction());
}
Value *imp = B.CreateLoad(B.CreateStructGEP(slot, 4));
msgSend.setArgument(selfIndex, B.CreateLoad(selfPtr, true));
msgSend.setCalledFunction(imp);
return CallSite(slot);
}
示例2: SplitLandingPadPreds
/// SplitLandingPadPreds - The landing pad needs to be extracted with the invoke
/// instruction. The critical edge breaker will refuse to break critical edges
/// to a landing pad. So do them here. After this method runs, all landing pads
/// should have only one predecessor.
void BlockExtractorPass::SplitLandingPadPreds(Function *F) {
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
InvokeInst *II = dyn_cast<InvokeInst>(I);
if (!II) continue;
BasicBlock *Parent = II->getParent();
BasicBlock *LPad = II->getUnwindDest();
// Look through the landing pad's predecessors. If one of them ends in an
// 'invoke', then we want to split the landing pad.
bool Split = false;
for (pred_iterator
PI = pred_begin(LPad), PE = pred_end(LPad); PI != PE; ++PI) {
BasicBlock *BB = *PI;
if (BB->isLandingPad() && BB != Parent &&
isa<InvokeInst>(Parent->getTerminator())) {
Split = true;
break;
}
}
if (!Split) continue;
SmallVector<BasicBlock*, 2> NewBBs;
SplitLandingPadPredecessors(LPad, Parent, ".1", ".2", NewBBs);
}
}
示例3: splitLandingPadPreds
/// Extracts the landing pads to make sure all of them have only one
/// predecessor.
void BlockExtractor::splitLandingPadPreds(Function &F) {
for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
if (!isa<InvokeInst>(&I))
continue;
InvokeInst *II = cast<InvokeInst>(&I);
BasicBlock *Parent = II->getParent();
BasicBlock *LPad = II->getUnwindDest();
// Look through the landing pad's predecessors. If one of them ends in an
// 'invoke', then we want to split the landing pad.
bool Split = false;
for (auto PredBB : predecessors(LPad)) {
if (PredBB->isLandingPad() && PredBB != Parent &&
isa<InvokeInst>(Parent->getTerminator())) {
Split = true;
break;
}
}
if (!Split)
continue;
SmallVector<BasicBlock *, 2> NewBBs;
SplitLandingPadPredecessors(LPad, Parent, ".1", ".2", NewBBs);
}
}
}
示例4: visitInvokeInst
// visitInvokeInst - Converting the "invoke" instruction is fairly
// straight-forward. The old exception part is replaced by a query asking
// if this is a longjmp exception. If it is, then it goes to the longjmp
// exception blocks. Otherwise, control is passed the old exception.
void LowerSetJmp::visitInvokeInst(InvokeInst& II)
{
if (II.getCalledFunction())
if (!IsTransformableFunction(II.getCalledFunction()->getName()) ||
II.getCalledFunction()->isIntrinsic()) return;
BasicBlock* BB = II.getParent();
// If not reachable from a setjmp call, don't transform.
if (!DFSBlocks.count(BB)) return;
BasicBlock* ExceptBB = II.getUnwindDest();
Function* Func = BB->getParent();
BasicBlock* NewExceptBB = BasicBlock::Create("InvokeExcept", Func);
BasicBlock::InstListType& InstList = NewExceptBB->getInstList();
// If this is a longjmp exception, then branch to the preliminary BB of
// the longjmp exception handling. Otherwise, go to the old exception.
CallInst* IsLJExcept = CallInst::Create(IsLJException, "IsLJExcept");
InstList.push_back(IsLJExcept);
BranchInst::Create(PrelimBBMap[Func], ExceptBB, IsLJExcept, NewExceptBB);
II.setUnwindDest(NewExceptBB);
++InvokesTransformed;
}
示例5: assert
/// Replaces the given call site (Call or Invoke) with a gc.statepoint
/// intrinsic with an empty deoptimization arguments list. This does
/// NOT do explicit relocation for GC support.
static Value *ReplaceWithStatepoint(const CallSite &CS /* to replace */) {
assert(CS.getInstruction()->getModule() && "must be set");
// TODO: technically, a pass is not allowed to get functions from within a
// function pass since it might trigger a new function addition. Refactor
// this logic out to the initialization of the pass. Doesn't appear to
// matter in practice.
// Then go ahead and use the builder do actually do the inserts. We insert
// immediately before the previous instruction under the assumption that all
// arguments will be available here. We can't insert afterwards since we may
// be replacing a terminator.
IRBuilder<> Builder(CS.getInstruction());
// Note: The gc args are not filled in at this time, that's handled by
// RewriteStatepointsForGC (which is currently under review).
// Create the statepoint given all the arguments
Instruction *Token = nullptr;
uint64_t ID;
uint32_t NumPatchBytes;
AttributeSet OriginalAttrs = CS.getAttributes();
Attribute AttrID =
OriginalAttrs.getAttribute(AttributeSet::FunctionIndex, "statepoint-id");
Attribute AttrNumPatchBytes = OriginalAttrs.getAttribute(
AttributeSet::FunctionIndex, "statepoint-num-patch-bytes");
AttrBuilder AttrsToRemove;
bool HasID = AttrID.isStringAttribute() &&
!AttrID.getValueAsString().getAsInteger(10, ID);
if (HasID)
AttrsToRemove.addAttribute("statepoint-id");
else
ID = 0xABCDEF00;
bool HasNumPatchBytes =
AttrNumPatchBytes.isStringAttribute() &&
!AttrNumPatchBytes.getValueAsString().getAsInteger(10, NumPatchBytes);
if (HasNumPatchBytes)
AttrsToRemove.addAttribute("statepoint-num-patch-bytes");
else
NumPatchBytes = 0;
OriginalAttrs = OriginalAttrs.removeAttributes(
CS.getInstruction()->getContext(), AttributeSet::FunctionIndex,
AttrsToRemove);
if (CS.isCall()) {
CallInst *ToReplace = cast<CallInst>(CS.getInstruction());
CallInst *Call = Builder.CreateGCStatepointCall(
ID, NumPatchBytes, CS.getCalledValue(),
makeArrayRef(CS.arg_begin(), CS.arg_end()), None, None,
"safepoint_token");
Call->setTailCall(ToReplace->isTailCall());
Call->setCallingConv(ToReplace->getCallingConv());
// In case if we can handle this set of attributes - set up function
// attributes directly on statepoint and return attributes later for
// gc_result intrinsic.
Call->setAttributes(OriginalAttrs.getFnAttributes());
Token = Call;
// Put the following gc_result and gc_relocate calls immediately after
// the old call (which we're about to delete).
assert(ToReplace->getNextNode() && "not a terminator, must have next");
Builder.SetInsertPoint(ToReplace->getNextNode());
Builder.SetCurrentDebugLocation(ToReplace->getNextNode()->getDebugLoc());
} else if (CS.isInvoke()) {
InvokeInst *ToReplace = cast<InvokeInst>(CS.getInstruction());
// Insert the new invoke into the old block. We'll remove the old one in a
// moment at which point this will become the new terminator for the
// original block.
Builder.SetInsertPoint(ToReplace->getParent());
InvokeInst *Invoke = Builder.CreateGCStatepointInvoke(
ID, NumPatchBytes, CS.getCalledValue(), ToReplace->getNormalDest(),
ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
None, None, "safepoint_token");
Invoke->setCallingConv(ToReplace->getCallingConv());
// In case if we can handle this set of attributes - set up function
// attributes directly on statepoint and return attributes later for
// gc_result intrinsic.
Invoke->setAttributes(OriginalAttrs.getFnAttributes());
Token = Invoke;
// We'll insert the gc.result into the normal block
BasicBlock *NormalDest = ToReplace->getNormalDest();
// Can not insert gc.result in case of phi nodes preset.
// Should have removed this cases prior to running this function
//.........这里部分代码省略.........
示例6: SplitCriticalEdge
// First thing we need to do is scan the whole function for values that are
// live across unwind edges. Each value that is live across an unwind edge
// we spill into a stack location, guaranteeing that there is nothing live
// across the unwind edge. This process also splits all critical edges
// coming out of invoke's.
void LowerInvoke::
splitLiveRangesLiveAcrossInvokes(std::vector<InvokeInst*> &Invokes) {
// First step, split all critical edges from invoke instructions.
for (unsigned i = 0, e = Invokes.size(); i != e; ++i) {
InvokeInst *II = Invokes[i];
SplitCriticalEdge(II, 0, this);
SplitCriticalEdge(II, 1, this);
assert(!isa<PHINode>(II->getNormalDest()) &&
!isa<PHINode>(II->getUnwindDest()) &&
"critical edge splitting left single entry phi nodes?");
}
Function *F = Invokes.back()->getParent()->getParent();
// To avoid having to handle incoming arguments specially, we lower each arg
// to a copy instruction in the entry block. This ensures that the argument
// value itself cannot be live across the entry block.
BasicBlock::iterator AfterAllocaInsertPt = F->begin()->begin();
while (isa<AllocaInst>(AfterAllocaInsertPt) &&
isa<ConstantInt>(cast<AllocaInst>(AfterAllocaInsertPt)->getArraySize()))
++AfterAllocaInsertPt;
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI) {
// This is always a no-op cast because we're casting AI to AI->getType() so
// src and destination types are identical. BitCast is the only possibility.
CastInst *NC = new BitCastInst(
AI, AI->getType(), AI->getName()+".tmp", AfterAllocaInsertPt);
AI->replaceAllUsesWith(NC);
// Normally its is forbidden to replace a CastInst's operand because it
// could cause the opcode to reflect an illegal conversion. However, we're
// replacing it here with the same value it was constructed with to simply
// make NC its user.
NC->setOperand(0, AI);
}
// Finally, scan the code looking for instructions with bad live ranges.
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) {
// Ignore obvious cases we don't have to handle. In particular, most
// instructions either have no uses or only have a single use inside the
// current block. Ignore them quickly.
Instruction *Inst = II;
if (Inst->use_empty()) continue;
if (Inst->hasOneUse() &&
cast<Instruction>(Inst->use_back())->getParent() == BB &&
!isa<PHINode>(Inst->use_back())) continue;
// If this is an alloca in the entry block, it's not a real register
// value.
if (AllocaInst *AI = dyn_cast<AllocaInst>(Inst))
if (isa<ConstantInt>(AI->getArraySize()) && BB == F->begin())
continue;
// Avoid iterator invalidation by copying users to a temporary vector.
std::vector<Instruction*> Users;
for (Value::use_iterator UI = Inst->use_begin(), E = Inst->use_end();
UI != E; ++UI) {
Instruction *User = cast<Instruction>(*UI);
if (User->getParent() != BB || isa<PHINode>(User))
Users.push_back(User);
}
// Scan all of the uses and see if the live range is live across an unwind
// edge. If we find a use live across an invoke edge, create an alloca
// and spill the value.
std::set<InvokeInst*> InvokesWithStoreInserted;
// Find all of the blocks that this value is live in.
std::set<BasicBlock*> LiveBBs;
LiveBBs.insert(Inst->getParent());
while (!Users.empty()) {
Instruction *U = Users.back();
Users.pop_back();
if (!isa<PHINode>(U)) {
MarkBlocksLiveIn(U->getParent(), LiveBBs);
} else {
// Uses for a PHI node occur in their predecessor block.
PHINode *PN = cast<PHINode>(U);
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
if (PN->getIncomingValue(i) == Inst)
MarkBlocksLiveIn(PN->getIncomingBlock(i), LiveBBs);
}
}
// Now that we know all of the blocks that this thing is live in, see if
// it includes any of the unwind locations.
bool NeedsSpill = false;
for (unsigned i = 0, e = Invokes.size(); i != e; ++i) {
BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest();
if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) {
NeedsSpill = true;
}
}
//.........这里部分代码省略.........
示例7: processCallSite
bool CSDataRando::processCallSite(CallSite CS, FuncInfo &FI, PointerEquivalenceAnalysis &P, DSGraph *G) {
bool IndirectCall = !isa<Function>(CS.getCalledValue()->stripPointerCasts());
if (IndirectCall) { NumIndirectCalls++; }
CallSite OriginalCS = originalCallSite(FI, CS);
if (!DSA->canEncryptCall(OriginalCS)) {
if (IndirectCall) { NumIndirectCantEncrypt++; }
return false;
}
DSCallSite DSCS = G->getDSCallSiteForCallSite(OriginalCS);
const Function *Callee = getEffectiveCallee(DSCS, FI, G);
if (!Callee) {
if (IndirectCall) { NumIndirectCantEncrypt++; }
return false;
}
FuncInfo &CalleeInfo = FunctionInfo[Callee];
Value *Clone = getCloneCalledValue(CS, CalleeInfo);
if (!Clone || CalleeInfo.ArgNodes.empty()) {
if (IndirectCall) { NumIndirectCantEncrypt++; }
return false;
}
// We create a mapping of the formal argument nodes in the callee function and
// actual argument nodes in the caller function's graph.
DSGraph::NodeMapTy NodeMap;
DSGraph *CalleeG = DSA->getDSGraph(*Callee);
// getArgNodesForCall places the return node and the vanode in the
// first two slots of the vector, followed by the nodes for the regular
// pointer arguments.
std::vector<DSNodeHandle> ArgNodes;
getArgNodesForCall(CalleeG, DSCS, ArgNodes);
// First the return value
DSNodeHandle CalleeRetNode = ArgNodes[0];
DSGraph::computeNodeMapping(CalleeRetNode, DSCS.getRetVal(), NodeMap);
// Then VarArgs
DSNodeHandle CalleeVarArgNode = ArgNodes[1];
DSGraph::computeNodeMapping(CalleeVarArgNode, DSCS.getVAVal(), NodeMap);
// And last the regular arguments.
for (unsigned int i = 0; i < DSCS.getNumPtrArgs() && i + 2 < ArgNodes.size(); i++) {
DSGraph::computeNodeMapping(ArgNodes[i + 2], DSCS.getPtrArg(i), NodeMap);
}
// Collect the arguments and masks to pass to call
SmallVector<Value*, 8> Args;
unsigned int i = 0;
for (unsigned int e = CS.getFunctionType()->getNumParams(); i < e; i++) {
Args.push_back(CS.getArgOperand(i));
}
for (const DSNode *N : CalleeInfo.ArgNodes) {
Value *Mask = P.getMaskForNode(NodeMap[N]);
Args.push_back(Mask);
}
// VarArgs go after masks
for (unsigned int e = CS.arg_size(); i < e; i++) {
Args.push_back(CS.getArgOperand(i));
}
// Do replacement
Instruction *CI = CS.getInstruction();
Value *Call;
if (CS.isCall()) {
Call = CallInst::Create(Clone, Args, "", CI);
} else {
InvokeInst *II = cast<InvokeInst>(CI);
Call = InvokeInst::Create(Clone, II->getNormalDest(), II->getUnwindDest(), Args, "", II);
}
CallSite NewCS(Call);
NewCS.setCallingConv(CS.getCallingConv());
CI->replaceAllUsesWith(Call);
P.replace(CI, Call);
CI->eraseFromParent();
return true;
}
示例8: next
/// Replaces the given call site (Call or Invoke) with a gc.statepoint
/// intrinsic with an empty deoptimization arguments list. This does
/// NOT do explicit relocation for GC support.
static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */
Pass *P) {
BasicBlock *BB = CS.getInstruction()->getParent();
Function *F = BB->getParent();
Module *M = F->getParent();
assert(M && "must be set");
// TODO: technically, a pass is not allowed to get functions from within a
// function pass since it might trigger a new function addition. Refactor
// this logic out to the initialization of the pass. Doesn't appear to
// matter in practice.
// Fill in the one generic type'd argument (the function is also vararg)
std::vector<Type *> argTypes;
argTypes.push_back(CS.getCalledValue()->getType());
Function *gc_statepoint_decl = Intrinsic::getDeclaration(
M, Intrinsic::experimental_gc_statepoint, argTypes);
// Then go ahead and use the builder do actually do the inserts. We insert
// immediately before the previous instruction under the assumption that all
// arguments will be available here. We can't insert afterwards since we may
// be replacing a terminator.
Instruction *insertBefore = CS.getInstruction();
IRBuilder<> Builder(insertBefore);
// First, create the statepoint (with all live ptrs as arguments).
std::vector<llvm::Value *> args;
// target, #args, unused, args
Value *Target = CS.getCalledValue();
args.push_back(Target);
int callArgSize = CS.arg_size();
args.push_back(
ConstantInt::get(Type::getInt32Ty(M->getContext()), callArgSize));
// TODO: add a 'Needs GC-rewrite' later flag
args.push_back(ConstantInt::get(Type::getInt32Ty(M->getContext()), 0));
// Copy all the arguments of the original call
args.insert(args.end(), CS.arg_begin(), CS.arg_end());
// Create the statepoint given all the arguments
Instruction *token = nullptr;
AttributeSet return_attributes;
if (CS.isCall()) {
CallInst *toReplace = cast<CallInst>(CS.getInstruction());
CallInst *call =
Builder.CreateCall(gc_statepoint_decl, args, "safepoint_token");
call->setTailCall(toReplace->isTailCall());
call->setCallingConv(toReplace->getCallingConv());
// Before we have to worry about GC semantics, all attributes are legal
AttributeSet new_attrs = toReplace->getAttributes();
// In case if we can handle this set of sttributes - set up function attrs
// directly on statepoint and return attrs later for gc_result intrinsic.
call->setAttributes(new_attrs.getFnAttributes());
return_attributes = new_attrs.getRetAttributes();
// TODO: handle param attributes
token = call;
// Put the following gc_result and gc_relocate calls immediately after the
// the old call (which we're about to delete)
BasicBlock::iterator next(toReplace);
assert(BB->end() != next && "not a terminator, must have next");
next++;
Instruction *IP = &*(next);
Builder.SetInsertPoint(IP);
Builder.SetCurrentDebugLocation(IP->getDebugLoc());
} else if (CS.isInvoke()) {
InvokeInst *toReplace = cast<InvokeInst>(CS.getInstruction());
// Insert the new invoke into the old block. We'll remove the old one in a
// moment at which point this will become the new terminator for the
// original block.
InvokeInst *invoke = InvokeInst::Create(
gc_statepoint_decl, toReplace->getNormalDest(),
toReplace->getUnwindDest(), args, "", toReplace->getParent());
invoke->setCallingConv(toReplace->getCallingConv());
// Currently we will fail on parameter attributes and on certain
// function attributes.
AttributeSet new_attrs = toReplace->getAttributes();
// In case if we can handle this set of sttributes - set up function attrs
// directly on statepoint and return attrs later for gc_result intrinsic.
invoke->setAttributes(new_attrs.getFnAttributes());
return_attributes = new_attrs.getRetAttributes();
token = invoke;
// We'll insert the gc.result into the normal block
BasicBlock *normalDest = normalizeBBForInvokeSafepoint(
toReplace->getNormalDest(), invoke->getParent());
Instruction *IP = &*(normalDest->getFirstInsertionPt());
Builder.SetInsertPoint(IP);
} else {
llvm_unreachable("unexpect type of CallSite");
}
//.........这里部分代码省略.........
示例9: CS
// Specialize F by replacing the arguments (keys) in replacements with the
// constants (values). Replace all calls to F with those constants with
// a call to the specialized function. Returns the specialized function
static Function*
SpecializeFunction(Function* F,
ValueMap<const Value*, Value*>& replacements) {
// arg numbers of deleted arguments
DenseMap<unsigned, const Argument*> deleted;
for (ValueMap<const Value*, Value*>::iterator
repb = replacements.begin(), repe = replacements.end();
repb != repe; ++repb) {
Argument const *arg = cast<const Argument>(repb->first);
deleted[arg->getArgNo()] = arg;
}
Function* NF = CloneFunction(F, replacements,
/*ModuleLevelChanges=*/false);
NF->setLinkage(GlobalValue::InternalLinkage);
F->getParent()->getFunctionList().push_back(NF);
for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
ii != ee; ) {
Value::use_iterator i = ii;
++ii;
User *U = *i;
CallSite CS(U);
if (CS) {
if (CS.getCalledFunction() == F) {
SmallVector<Value*, 6> args;
// Assemble the non-specialized arguments for the updated callsite.
// In the process, make sure that the specialized arguments are
// constant and match the specialization. If that's not the case,
// this callsite needs to call the original or some other
// specialization; don't change it here.
CallSite::arg_iterator as = CS.arg_begin(), ae = CS.arg_end();
for (CallSite::arg_iterator ai = as; ai != ae; ++ai) {
DenseMap<unsigned, const Argument*>::iterator delit = deleted.find(
std::distance(as, ai));
if (delit == deleted.end())
args.push_back(cast<Value>(ai));
else {
Constant *ci = dyn_cast<Constant>(ai);
if (!(ci && ci == replacements[delit->second]))
goto next_use;
}
}
Value* NCall;
if (CallInst *CI = dyn_cast<CallInst>(U)) {
NCall = CallInst::Create(NF, args.begin(), args.end(),
CI->getName(), CI);
cast<CallInst>(NCall)->setTailCall(CI->isTailCall());
cast<CallInst>(NCall)->setCallingConv(CI->getCallingConv());
} else {
InvokeInst *II = cast<InvokeInst>(U);
NCall = InvokeInst::Create(NF, II->getNormalDest(),
II->getUnwindDest(),
args.begin(), args.end(),
II->getName(), II);
cast<InvokeInst>(NCall)->setCallingConv(II->getCallingConv());
}
CS.getInstruction()->replaceAllUsesWith(NCall);
CS.getInstruction()->eraseFromParent();
++numReplaced;
}
}
next_use:;
}
return NF;
}
示例10: runOnModule
bool ICFGBuilder::runOnModule(Module &M) {
MicroBasicBlockBuilder &MBBB = getAnalysis<MicroBasicBlockBuilder>();
forallbb(M, bb) {
for (mbb_iterator mi = MBBB.begin(bb), E = MBBB.end(bb); mi != E; ++mi)
getOrInsertMBB(mi);
}
forallbb(M, bb) {
for (mbb_iterator mi = MBBB.begin(bb), E = MBBB.end(bb); mi != E; ++mi) {
// The ICFG will not contain any inter-thread edge.
// It's also difficult to handle them. How to deal with the return
// edges? They are supposed to go to the pthread_join sites.
if (mi->end() != bb->end() && !is_pthread_create(mi->end())) {
FPCallGraph &CG = getAnalysis<FPCallGraph>();
FuncList callees = CG.getCalledFunctions(mi->end());
bool calls_decl = false;
for (size_t i = 0; i < callees.size(); ++i) {
Function *callee = callees[i];
if (callee->isDeclaration()) {
calls_decl = true;
} else {
MicroBasicBlock *entry_mbb = MBBB.begin(callee->begin());
addEdge(mi, entry_mbb);
}
}
if (calls_decl) {
mbb_iterator next_mbb = mi; ++next_mbb;
addEdge(mi, next_mbb);
}
} else {
for (succ_iterator si = succ_begin(bb); si != succ_end(bb); ++si) {
MicroBasicBlock *succ_mbb = MBBB.begin(*si);
addEdge(mi, succ_mbb);
}
TerminatorInst *ti = bb->getTerminator();
if (is_ret(ti)) {
FPCallGraph &CG = getAnalysis<FPCallGraph>();
InstList call_sites = CG.getCallSites(bb->getParent());
for (size_t i = 0; i < call_sites.size(); ++i) {
Instruction *call_site = call_sites[i];
// Ignore inter-thread edges.
if (is_pthread_create(call_site))
continue;
MicroBasicBlock *next_mbb;
if (isa<CallInst>(call_site)) {
BasicBlock::iterator next = call_site;
++next;
next_mbb = MBBB.parent(next);
} else {
assert(isa<InvokeInst>(call_site));
InvokeInst *inv = dyn_cast<InvokeInst>(call_site);
if (isa<ReturnInst>(ti)) {
next_mbb = MBBB.begin(inv->getNormalDest());
} else {
next_mbb = MBBB.begin(inv->getUnwindDest());
}
}
addEdge(mi, next_mbb);
}
}
}
}
}
return false;
}