本文整理汇总了C++中LandingPadInst类的典型用法代码示例。如果您正苦于以下问题:C++ LandingPadInst类的具体用法?C++ LandingPadInst怎么用?C++ LandingPadInst使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了LandingPadInst类的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: addLandingPadInfo
void llvm::addLandingPadInfo(const LandingPadInst &I, MachineBasicBlock &MBB) {
MachineFunction &MF = *MBB.getParent();
if (const auto *PF = dyn_cast<Function>(
I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts()))
MF.getMMI().addPersonality(PF);
if (I.isCleanup())
MF.addCleanup(&MBB);
// FIXME: New EH - Add the clauses in reverse order. This isn't 100% correct,
// but we need to do it this way because of how the DWARF EH emitter
// processes the clauses.
for (unsigned i = I.getNumClauses(); i != 0; --i) {
Value *Val = I.getClause(i - 1);
if (I.isCatch(i - 1)) {
MF.addCatchTypeInfo(&MBB,
dyn_cast<GlobalValue>(Val->stripPointerCasts()));
} else {
// Add filters in a list.
Constant *CVal = cast<Constant>(Val);
SmallVector<const GlobalValue *, 4> FilterList;
for (User::op_iterator II = CVal->op_begin(), IE = CVal->op_end();
II != IE; ++II)
FilterList.push_back(cast<GlobalValue>((*II)->stripPointerCasts()));
MF.addFilterTypeInfo(&MBB, FilterList);
}
}
}
示例2: getInnerResumeDest
/// forwardResume - Forward the 'resume' instruction to the caller's landing pad
/// block. When the landing pad block has only one predecessor, this is a simple
/// branch. When there is more than one predecessor, we need to split the
/// landing pad block after the landingpad instruction and jump to there.
void InvokeInliningInfo::forwardResume(ResumeInst *RI,
SmallPtrSet<LandingPadInst*, 16> &InlinedLPads) {
BasicBlock *Dest = getInnerResumeDest();
LandingPadInst *OuterLPad = getLandingPadInst();
BasicBlock *Src = RI->getParent();
BranchInst::Create(Dest, Src);
// Update the PHIs in the destination. They were inserted in an order which
// makes this work.
addIncomingPHIValuesForInto(Src, Dest);
InnerEHValuesPHI->addIncoming(RI->getOperand(0), Src);
RI->eraseFromParent();
// Append the clauses from the outer landing pad instruction into the inlined
// landing pad instructions.
for (SmallPtrSet<LandingPadInst*, 16>::iterator I = InlinedLPads.begin(),
E = InlinedLPads.end(); I != E; ++I) {
LandingPadInst *InlinedLPad = *I;
for (unsigned OuterIdx = 0, OuterNum = OuterLPad->getNumClauses();
OuterIdx != OuterNum; ++OuterIdx)
InlinedLPad->addClause(OuterLPad->getClause(OuterIdx));
}
}
示例3: escapeRegNode
/// Assign every distinct landingpad a unique state number for SEH. Unlike C++
/// EH, we can use this very simple algorithm while C++ EH cannot because catch
/// handlers aren't outlined and the runtime doesn't have to figure out which
/// catch handler frame to unwind to.
/// FIXME: __finally blocks are outlined, so this approach may break down there.
void WinEHStatePass::addSEHStateStores(Function &F, MachineModuleInfo &MMI) {
WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(&F);
// Remember and return the index that we used. We save it in WinEHFuncInfo so
// that we can lower llvm.x86.seh.recoverfp later in filter functions without
// too much trouble.
int RegNodeEscapeIndex = escapeRegNode(F);
FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
// Iterate all the instructions and emit state number stores.
int CurState = 0;
SmallPtrSet<BasicBlock *, 4> ExceptBlocks;
for (BasicBlock &BB : F) {
for (auto I = BB.begin(), E = BB.end(); I != E; ++I) {
if (auto *CI = dyn_cast<CallInst>(I)) {
auto *Intrin = dyn_cast<IntrinsicInst>(CI);
if (Intrin) {
// Calls that "don't throw" are considered to be able to throw asynch
// exceptions, but intrinsics cannot.
continue;
}
insertStateNumberStore(RegNode, CI, -1);
} else if (auto *II = dyn_cast<InvokeInst>(I)) {
// Look up the state number of the landingpad this unwinds to.
LandingPadInst *LPI = II->getUnwindDest()->getLandingPadInst();
auto InsertionPair =
FuncInfo.LandingPadStateMap.insert(std::make_pair(LPI, CurState));
auto Iter = InsertionPair.first;
int &State = Iter->second;
bool Inserted = InsertionPair.second;
if (Inserted) {
// Each action consumes a state number.
auto *EHActions = cast<IntrinsicInst>(LPI->getNextNode());
SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
parseEHActions(EHActions, ActionList);
assert(!ActionList.empty());
CurState += ActionList.size();
State += ActionList.size() - 1;
// Remember all the __except block targets.
for (auto &Handler : ActionList) {
if (auto *CH = dyn_cast<CatchHandler>(Handler.get())) {
auto *BA = cast<BlockAddress>(CH->getHandlerBlockOrFunc());
ExceptBlocks.insert(BA->getBasicBlock());
}
}
}
insertStateNumberStore(RegNode, II, State);
}
}
}
// Insert llvm.x86.seh.restoreframe() into each __except block.
Function *RestoreFrame =
Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_restoreframe);
for (BasicBlock *ExceptBB : ExceptBlocks) {
IRBuilder<> Builder(ExceptBB->begin());
Builder.CreateCall(RestoreFrame, {});
}
}
示例4: HandleCallsInBlockInlinedThroughInvoke
/// HandleCallsInBlockInlinedThroughInvoke - When we inline a basic block into
/// an invoke, we have to turn all of the calls that can throw into
/// invokes. This function analyze BB to see if there are any calls, and if so,
/// it rewrites them to be invokes that jump to InvokeDest and fills in the PHI
/// nodes in that block with the values specified in InvokeDestPHIValues.
///
/// Returns true to indicate that the next block should be skipped.
static bool HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB,
InvokeInliningInfo &Invoke) {
LandingPadInst *LPI = Invoke.getLandingPadInst();
for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
Instruction *I = BBI++;
if (LandingPadInst *L = dyn_cast<LandingPadInst>(I)) {
unsigned NumClauses = LPI->getNumClauses();
L->reserveClauses(NumClauses);
for (unsigned i = 0; i != NumClauses; ++i)
L->addClause(LPI->getClause(i));
}
// We only need to check for function calls: inlined invoke
// instructions require no special handling.
CallInst *CI = dyn_cast<CallInst>(I);
// If this call cannot unwind, don't convert it to an invoke.
// Inline asm calls cannot throw.
if (!CI || CI->doesNotThrow() || isa<InlineAsm>(CI->getCalledValue()))
continue;
// Convert this function call into an invoke instruction. First, split the
// basic block.
BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc");
// Delete the unconditional branch inserted by splitBasicBlock
BB->getInstList().pop_back();
// Create the new invoke instruction.
ImmutableCallSite CS(CI);
SmallVector<Value*, 8> InvokeArgs(CS.arg_begin(), CS.arg_end());
InvokeInst *II = InvokeInst::Create(CI->getCalledValue(), Split,
Invoke.getOuterResumeDest(),
InvokeArgs, CI->getName(), BB);
II->setCallingConv(CI->getCallingConv());
II->setAttributes(CI->getAttributes());
// Make sure that anything using the call now uses the invoke! This also
// updates the CallGraph if present, because it uses a WeakVH.
CI->replaceAllUsesWith(II);
// Delete the original call
Split->getInstList().pop_front();
// Update any PHI nodes in the exceptional block to indicate that there is
// now a new entry in them.
Invoke.addIncomingPHIValuesFor(BB);
return false;
}
return false;
}
示例5: AllocaInst
/// setupFunctionContext - Allocate the function context on the stack and fill
/// it with all of the data that we know at this point.
Value *SjLjEHPrepare::setupFunctionContext(Function &F,
ArrayRef<LandingPadInst *> LPads) {
BasicBlock *EntryBB = &F.front();
// Create an alloca for the incoming jump buffer ptr and the new jump buffer
// that needs to be restored on all exits from the function. This is an alloca
// because the value needs to be added to the global context list.
auto &DL = F.getParent()->getDataLayout();
unsigned Align = DL.getPrefTypeAlignment(FunctionContextTy);
FuncCtx = new AllocaInst(FunctionContextTy, nullptr, Align, "fn_context",
&EntryBB->front());
// Fill in the function context structure.
for (unsigned I = 0, E = LPads.size(); I != E; ++I) {
LandingPadInst *LPI = LPads[I];
IRBuilder<> Builder(LPI->getParent(),
LPI->getParent()->getFirstInsertionPt());
// Reference the __data field.
Value *FCData =
Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 2, "__data");
// The exception values come back in context->__data[0].
Value *ExceptionAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData,
0, 0, "exception_gep");
Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val");
ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy());
Value *SelectorAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData,
0, 1, "exn_selector_gep");
Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val");
substituteLPadValues(LPI, ExnVal, SelVal);
}
// Personality function
IRBuilder<> Builder(EntryBB->getTerminator());
if (!PersonalityFn)
PersonalityFn = F.getPersonalityFn();
Value *PersonalityFieldPtr = Builder.CreateConstGEP2_32(
FunctionContextTy, FuncCtx, 0, 3, "pers_fn_gep");
Builder.CreateStore(
Builder.CreateBitCast(PersonalityFn, Builder.getInt8PtrTy()),
PersonalityFieldPtr, /*isVolatile=*/true);
// LSDA address
Value *LSDA = Builder.CreateCall(LSDAAddrFn, {}, "lsda_addr");
Value *LSDAFieldPtr =
Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 4, "lsda_gep");
Builder.CreateStore(LSDA, LSDAFieldPtr, /*isVolatile=*/true);
return FuncCtx;
}
示例6: HandleInlinedInvoke
/// HandleInlinedInvoke - If we inlined an invoke site, we need to convert calls
/// in the body of the inlined function into invokes.
///
/// II is the invoke instruction being inlined. FirstNewBlock is the first
/// block of the inlined code (the last block is the end of the function),
/// and InlineCodeInfo is information about the code that got inlined.
static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
ClonedCodeInfo &InlinedCodeInfo) {
BasicBlock *InvokeDest = II->getUnwindDest();
Function *Caller = FirstNewBlock->getParent();
// The inlined code is currently at the end of the function, scan from the
// start of the inlined code to its end, checking for stuff we need to
// rewrite.
InvokeInliningInfo Invoke(II);
// Get all of the inlined landing pad instructions.
SmallPtrSet<LandingPadInst*, 16> InlinedLPads;
for (Function::iterator I = FirstNewBlock, E = Caller->end(); I != E; ++I)
if (InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator()))
InlinedLPads.insert(II->getLandingPadInst());
// Append the clauses from the outer landing pad instruction into the inlined
// landing pad instructions.
LandingPadInst *OuterLPad = Invoke.getLandingPadInst();
for (SmallPtrSet<LandingPadInst*, 16>::iterator I = InlinedLPads.begin(),
E = InlinedLPads.end(); I != E; ++I) {
LandingPadInst *InlinedLPad = *I;
unsigned OuterNum = OuterLPad->getNumClauses();
InlinedLPad->reserveClauses(OuterNum);
for (unsigned OuterIdx = 0; OuterIdx != OuterNum; ++OuterIdx)
InlinedLPad->addClause(OuterLPad->getClause(OuterIdx));
if (OuterLPad->isCleanup())
InlinedLPad->setCleanup(true);
}
for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB) {
if (InlinedCodeInfo.ContainsCalls)
HandleCallsInBlockInlinedThroughInvoke(BB, Invoke);
// Forward any resumes that are remaining here.
if (ResumeInst *RI = dyn_cast<ResumeInst>(BB->getTerminator()))
Invoke.forwardResume(RI, InlinedLPads);
}
// Now that everything is happy, we have one final detail. The PHI nodes in
// the exception destination block still have entries due to the original
// invoke instruction. Eliminate these entries (which might even delete the
// PHI node) now.
InvokeDest->removePredecessor(II->getParent());
}
示例7: assert
/// SplitLandingPadPredecessors - This method transforms the landing pad,
/// OrigBB, by introducing two new basic blocks into the function. One of those
/// new basic blocks gets the predecessors listed in Preds. The other basic
/// block gets the remaining predecessors of OrigBB. The landingpad instruction
/// OrigBB is clone into both of the new basic blocks. The new blocks are given
/// the suffixes 'Suffix1' and 'Suffix2', and are returned in the NewBBs vector.
///
/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree,
/// DominanceFrontier, LoopInfo, and LCCSA but no other analyses. In particular,
/// it does not preserve LoopSimplify (because it's complicated to handle the
/// case where one of the edges being split is an exit of a loop with other
/// exits).
///
void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB,
ArrayRef<BasicBlock*> Preds,
const char *Suffix1, const char *Suffix2,
Pass *P,
SmallVectorImpl<BasicBlock*> &NewBBs) {
assert(OrigBB->isLandingPad() && "Trying to split a non-landing pad!");
// Create a new basic block for OrigBB's predecessors listed in Preds. Insert
// it right before the original block.
BasicBlock *NewBB1 = BasicBlock::Create(OrigBB->getContext(),
OrigBB->getName() + Suffix1,
OrigBB->getParent(), OrigBB);
NewBBs.push_back(NewBB1);
// The new block unconditionally branches to the old block.
BranchInst *BI1 = BranchInst::Create(OrigBB, NewBB1);
// Move the edges from Preds to point to NewBB1 instead of OrigBB.
for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
// This is slightly more strict than necessary; the minimum requirement
// is that there be no more than one indirectbr branching to BB. And
// all BlockAddress uses would need to be updated.
assert(!isa<IndirectBrInst>(Preds[i]->getTerminator()) &&
"Cannot split an edge from an IndirectBrInst");
Preds[i]->getTerminator()->replaceUsesOfWith(OrigBB, NewBB1);
}
// Update DominatorTree, LoopInfo, and LCCSA analysis information.
bool HasLoopExit = false;
UpdateAnalysisInformation(OrigBB, NewBB1, Preds, P, HasLoopExit);
// Update the PHI nodes in OrigBB with the values coming from NewBB1.
UpdatePHINodes(OrigBB, NewBB1, Preds, BI1, P, HasLoopExit);
// Move the remaining edges from OrigBB to point to NewBB2.
SmallVector<BasicBlock*, 8> NewBB2Preds;
for (pred_iterator i = pred_begin(OrigBB), e = pred_end(OrigBB);
i != e; ) {
BasicBlock *Pred = *i++;
if (Pred == NewBB1) continue;
assert(!isa<IndirectBrInst>(Pred->getTerminator()) &&
"Cannot split an edge from an IndirectBrInst");
NewBB2Preds.push_back(Pred);
e = pred_end(OrigBB);
}
BasicBlock *NewBB2 = 0;
if (!NewBB2Preds.empty()) {
// Create another basic block for the rest of OrigBB's predecessors.
NewBB2 = BasicBlock::Create(OrigBB->getContext(),
OrigBB->getName() + Suffix2,
OrigBB->getParent(), OrigBB);
NewBBs.push_back(NewBB2);
// The new block unconditionally branches to the old block.
BranchInst *BI2 = BranchInst::Create(OrigBB, NewBB2);
// Move the remaining edges from OrigBB to point to NewBB2.
for (SmallVectorImpl<BasicBlock*>::iterator
i = NewBB2Preds.begin(), e = NewBB2Preds.end(); i != e; ++i)
(*i)->getTerminator()->replaceUsesOfWith(OrigBB, NewBB2);
// Update DominatorTree, LoopInfo, and LCCSA analysis information.
HasLoopExit = false;
UpdateAnalysisInformation(OrigBB, NewBB2, NewBB2Preds, P, HasLoopExit);
// Update the PHI nodes in OrigBB with the values coming from NewBB2.
UpdatePHINodes(OrigBB, NewBB2, NewBB2Preds, BI2, P, HasLoopExit);
}
LandingPadInst *LPad = OrigBB->getLandingPadInst();
Instruction *Clone1 = LPad->clone();
Clone1->setName(Twine("lpad") + Suffix1);
NewBB1->getInstList().insert(NewBB1->getFirstInsertionPt(), Clone1);
if (NewBB2) {
Instruction *Clone2 = LPad->clone();
Clone2->setName(Twine("lpad") + Suffix2);
NewBB2->getInstList().insert(NewBB2->getFirstInsertionPt(), Clone2);
// Create a PHI node for the two cloned landingpad instructions.
PHINode *PN = PHINode::Create(LPad->getType(), 2, "lpad.phi", LPad);
PN->addIncoming(Clone1, NewBB1);
PN->addIncoming(Clone2, NewBB2);
LPad->replaceAllUsesWith(PN);
LPad->eraseFromParent();
} else {
//.........这里部分代码省略.........
示例8: while
/// lowerAcrossUnwindEdges - Find all variables which are alive across an unwind
/// edge and spill them.
void SjLjEHPrepare::lowerAcrossUnwindEdges(Function &F,
ArrayRef<InvokeInst *> Invokes) {
// Finally, scan the code looking for instructions with bad live ranges.
for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) {
for (BasicBlock::iterator II = BB->begin(), IIE = BB->end(); II != IIE;
++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->user_back())->getParent() == BB &&
!isa<PHINode>(Inst->user_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.
SmallVector<Instruction *, 16> Users;
for (User *U : Inst->users()) {
Instruction *UI = cast<Instruction>(U);
if (UI->getParent() != BB || isa<PHINode>(UI))
Users.push_back(UI);
}
// Find all of the blocks that this value is live in.
SmallPtrSet<BasicBlock *, 64> 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)) {
DEBUG(dbgs() << "SJLJ Spill: " << *Inst << " around "
<< UnwindBlock->getName() << "\n");
NeedsSpill = true;
break;
}
}
// If we decided we need a spill, do it.
// FIXME: Spilling this way is overkill, as it forces all uses of
// the value to be reloaded from the stack slot, even those that aren't
// in the unwind blocks. We should be more selective.
if (NeedsSpill) {
DemoteRegToStack(*Inst, true);
++NumSpilled;
}
}
}
// Go through the landing pads and remove any PHIs there.
for (unsigned i = 0, e = Invokes.size(); i != e; ++i) {
BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest();
LandingPadInst *LPI = UnwindBlock->getLandingPadInst();
// Place PHIs into a set to avoid invalidating the iterator.
SmallPtrSet<PHINode *, 8> PHIsToDemote;
for (BasicBlock::iterator PN = UnwindBlock->begin(); isa<PHINode>(PN); ++PN)
PHIsToDemote.insert(cast<PHINode>(PN));
if (PHIsToDemote.empty())
continue;
// Demote the PHIs to the stack.
for (PHINode *PN : PHIsToDemote)
DemotePHIToStack(PN);
// Move the landingpad instruction back to the top of the landing pad block.
LPI->moveBefore(&UnwindBlock->front());
}
}
示例9: int
bool LowerEmExceptions::runOnModule(Module &M) {
TheModule = &M;
// Add functions
Type *i32 = Type::getInt32Ty(M.getContext());
Type *i8 = Type::getInt8Ty(M.getContext());
Type *i1 = Type::getInt1Ty(M.getContext());
Type *i8P = i8->getPointerTo();
Type *Void = Type::getVoidTy(M.getContext());
if (!(GetHigh = TheModule->getFunction("getHigh32"))) {
FunctionType *GetHighFunc = FunctionType::get(i32, false);
GetHigh = Function::Create(GetHighFunc, GlobalValue::ExternalLinkage,
"getHigh32", TheModule);
}
if (!(PreInvoke = TheModule->getFunction("emscripten_preinvoke"))) {
FunctionType *VoidFunc = FunctionType::get(Void, false);
PreInvoke = Function::Create(VoidFunc, GlobalValue::ExternalLinkage, "emscripten_preinvoke", TheModule);
}
if (!(PostInvoke = TheModule->getFunction("emscripten_postinvoke"))) {
FunctionType *IntFunc = FunctionType::get(i32, false);
PostInvoke = Function::Create(IntFunc, GlobalValue::ExternalLinkage, "emscripten_postinvoke", TheModule);
}
FunctionType *LandingPadFunc = FunctionType::get(i8P, true);
LandingPad = Function::Create(LandingPadFunc, GlobalValue::ExternalLinkage, "emscripten_landingpad", TheModule);
FunctionType *ResumeFunc = FunctionType::get(Void, true);
Resume = Function::Create(ResumeFunc, GlobalValue::ExternalLinkage, "emscripten_resume", TheModule);
// Process
bool HasWhitelist = Whitelist.size() > 0;
std::string WhitelistChecker;
if (HasWhitelist) WhitelistChecker = "," + Whitelist + ",";
bool Changed = false;
for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) {
Function *F = Iter++;
std::vector<Instruction*> ToErase;
std::set<LandingPadInst*> LandingPads;
bool AllowExceptionsInFunc = !HasWhitelist || int(WhitelistChecker.find(F->getName())) > 0;
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
// check terminator for invokes
if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
LandingPads.insert(II->getLandingPadInst());
bool NeedInvoke = AllowExceptionsInFunc && canThrow(II->getCalledValue());
if (NeedInvoke) {
// Insert a normal call instruction folded in between pre- and post-invoke
CallInst::Create(PreInvoke, "", II);
SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
CallInst *NewCall = CallInst::Create(II->getCalledValue(),
CallArgs, "", II);
NewCall->takeName(II);
NewCall->setCallingConv(II->getCallingConv());
NewCall->setAttributes(II->getAttributes());
NewCall->setDebugLoc(II->getDebugLoc());
II->replaceAllUsesWith(NewCall);
ToErase.push_back(II);
CallInst *Post = CallInst::Create(PostInvoke, "", II);
Instruction *Post1 = new TruncInst(Post, i1, "", II);
// Insert a branch based on the postInvoke
BranchInst::Create(II->getUnwindDest(), II->getNormalDest(), Post1, II);
} else {
// This can't throw, and we don't need this invoke, just replace it with a call+branch
SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
CallInst *NewCall = CallInst::Create(II->getCalledValue(),
CallArgs, "", II);
NewCall->takeName(II);
NewCall->setCallingConv(II->getCallingConv());
NewCall->setAttributes(II->getAttributes());
NewCall->setDebugLoc(II->getDebugLoc());
II->replaceAllUsesWith(NewCall);
ToErase.push_back(II);
BranchInst::Create(II->getNormalDest(), II);
// Remove any PHI node entries from the exception destination.
II->getUnwindDest()->removePredecessor(BB);
}
Changed = true;
}
// scan the body of the basic block for resumes
for (BasicBlock::iterator Iter = BB->begin(), E = BB->end();
Iter != E; ) {
Instruction *I = Iter++;
if (ResumeInst *R = dyn_cast<ResumeInst>(I)) {
//.........这里部分代码省略.........
示例10: setupFunctionContext
/// setupFunctionContext - Allocate the function context on the stack and fill
/// it with all of the data that we know at this point.
Value *SjLjEHPass::
setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads) {
BasicBlock *EntryBB = F.begin();
// Create an alloca for the incoming jump buffer ptr and the new jump buffer
// that needs to be restored on all exits from the function. This is an alloca
// because the value needs to be added to the global context list.
unsigned Align =
TLI->getTargetData()->getPrefTypeAlignment(FunctionContextTy);
FuncCtx =
new AllocaInst(FunctionContextTy, 0, Align, "fn_context", EntryBB->begin());
// Fill in the function context structure.
Type *Int32Ty = Type::getInt32Ty(F.getContext());
Value *Zero = ConstantInt::get(Int32Ty, 0);
Value *One = ConstantInt::get(Int32Ty, 1);
Value *Two = ConstantInt::get(Int32Ty, 2);
Value *Three = ConstantInt::get(Int32Ty, 3);
Value *Four = ConstantInt::get(Int32Ty, 4);
Value *Idxs[2] = { Zero, 0 };
for (unsigned I = 0, E = LPads.size(); I != E; ++I) {
LandingPadInst *LPI = LPads[I];
IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt());
// Reference the __data field.
Idxs[1] = Two;
Value *FCData = Builder.CreateGEP(FuncCtx, Idxs, "__data");
// The exception values come back in context->__data[0].
Idxs[1] = Zero;
Value *ExceptionAddr = Builder.CreateGEP(FCData, Idxs, "exception_gep");
Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val");
ExnVal = Builder.CreateIntToPtr(ExnVal, Type::getInt8PtrTy(F.getContext()));
Idxs[1] = One;
Value *SelectorAddr = Builder.CreateGEP(FCData, Idxs, "exn_selector_gep");
Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val");
substituteLPadValues(LPI, ExnVal, SelVal);
}
// Personality function
Idxs[1] = Three;
if (!PersonalityFn)
PersonalityFn = LPads[0]->getPersonalityFn();
Value *PersonalityFieldPtr =
GetElementPtrInst::Create(FuncCtx, Idxs, "pers_fn_gep",
EntryBB->getTerminator());
new StoreInst(PersonalityFn, PersonalityFieldPtr, true,
EntryBB->getTerminator());
// LSDA address
Value *LSDA = CallInst::Create(LSDAAddrFn, "lsda_addr",
EntryBB->getTerminator());
Idxs[1] = Four;
Value *LSDAFieldPtr = GetElementPtrInst::Create(FuncCtx, Idxs, "lsda_gep",
EntryBB->getTerminator());
new StoreInst(LSDA, LSDAFieldPtr, true, EntryBB->getTerminator());
return FuncCtx;
}
示例11: DEBUG
/// UnswitchNontrivialCondition - We determined that the loop is profitable
/// to unswitch when LIC equal Val. Split it into loop versions and test the
/// condition outside of either loop. Return the loops created as Out1/Out2.
void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
Loop *L) {
Function *F = loopHeader->getParent();
DEBUG(dbgs() << "loop-unswitch: Unswitching loop %"
<< loopHeader->getName() << " [" << L->getBlocks().size()
<< " blocks] in Function " << F->getName()
<< " when '" << *Val << "' == " << *LIC << "\n");
if (ScalarEvolution *SE = getAnalysisIfAvailable<ScalarEvolution>())
SE->forgetLoop(L);
LoopBlocks.clear();
NewBlocks.clear();
// First step, split the preheader and exit blocks, and add these blocks to
// the LoopBlocks list.
BasicBlock *NewPreheader = SplitEdge(loopPreheader, loopHeader, this);
LoopBlocks.push_back(NewPreheader);
// We want the loop to come after the preheader, but before the exit blocks.
LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end());
SmallVector<BasicBlock*, 8> ExitBlocks;
L->getUniqueExitBlocks(ExitBlocks);
// Split all of the edges from inside the loop to their exit blocks. Update
// the appropriate Phi nodes as we do so.
SplitExitEdges(L, ExitBlocks);
// The exit blocks may have been changed due to edge splitting, recompute.
ExitBlocks.clear();
L->getUniqueExitBlocks(ExitBlocks);
// Add exit blocks to the loop blocks.
LoopBlocks.insert(LoopBlocks.end(), ExitBlocks.begin(), ExitBlocks.end());
// Next step, clone all of the basic blocks that make up the loop (including
// the loop preheader and exit blocks), keeping track of the mapping between
// the instructions and blocks.
NewBlocks.reserve(LoopBlocks.size());
ValueToValueMapTy VMap;
for (unsigned i = 0, e = LoopBlocks.size(); i != e; ++i) {
BasicBlock *NewBB = CloneBasicBlock(LoopBlocks[i], VMap, ".us", F);
NewBlocks.push_back(NewBB);
VMap[LoopBlocks[i]] = NewBB; // Keep the BB mapping.
LPM->cloneBasicBlockSimpleAnalysis(LoopBlocks[i], NewBB, L);
}
// Splice the newly inserted blocks into the function right before the
// original preheader.
F->getBasicBlockList().splice(NewPreheader, F->getBasicBlockList(),
NewBlocks[0], F->end());
// Now we create the new Loop object for the versioned loop.
Loop *NewLoop = CloneLoop(L, L->getParentLoop(), VMap, LI, LPM);
// Recalculate unswitching quota, inherit simplified switches info for NewBB,
// Probably clone more loop-unswitch related loop properties.
BranchesInfo.cloneData(NewLoop, L, VMap);
Loop *ParentLoop = L->getParentLoop();
if (ParentLoop) {
// Make sure to add the cloned preheader and exit blocks to the parent loop
// as well.
ParentLoop->addBasicBlockToLoop(NewBlocks[0], LI->getBase());
}
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
BasicBlock *NewExit = cast<BasicBlock>(VMap[ExitBlocks[i]]);
// The new exit block should be in the same loop as the old one.
if (Loop *ExitBBLoop = LI->getLoopFor(ExitBlocks[i]))
ExitBBLoop->addBasicBlockToLoop(NewExit, LI->getBase());
assert(NewExit->getTerminator()->getNumSuccessors() == 1 &&
"Exit block should have been split to have one successor!");
BasicBlock *ExitSucc = NewExit->getTerminator()->getSuccessor(0);
// If the successor of the exit block had PHI nodes, add an entry for
// NewExit.
PHINode *PN;
for (BasicBlock::iterator I = ExitSucc->begin(); isa<PHINode>(I); ++I) {
PN = cast<PHINode>(I);
Value *V = PN->getIncomingValueForBlock(ExitBlocks[i]);
ValueToValueMapTy::iterator It = VMap.find(V);
if (It != VMap.end()) V = It->second;
PN->addIncoming(V, NewExit);
}
if (LandingPadInst *LPad = NewExit->getLandingPadInst()) {
PN = PHINode::Create(LPad->getType(), 0, "",
ExitSucc->getFirstInsertionPt());
for (pred_iterator I = pred_begin(ExitSucc), E = pred_end(ExitSucc);
I != E; ++I) {
BasicBlock *BB = *I;
LandingPadInst *LPI = BB->getLandingPadInst();
//.........这里部分代码省略.........
示例12: main
int main() {
InitializeNativeTarget();
LLVMContext& Context = getGlobalContext();
Module *M = new Module("test C++ exception handling ", Context);
StructType* MyStructType = StructType::create(Context, "struct.MyStruct");
Type* MyStructFields[] = {
Type::getInt32Ty(Context),
Type::getInt32Ty(Context)
};
MyStructType->setBody(MyStructFields);
GlobalValue* throwFunc = cast<GlobalValue>(M->getOrInsertFunction("throwMyStruct", Type::getVoidTy(Context), NULL));
GlobalValue* MyStructTypeInfo = cast<GlobalValue>(M->getOrInsertGlobal("MyStructTypeInfo", Type::getInt8Ty(Context)));
Function* gxx_personality = Function::Create(FunctionType::get(Type::getInt32Ty(Context), true), Function::ExternalLinkage, "__gxx_personality_v0", M);
Function* begin_catch = Function::Create(FunctionType::get(Type::getInt8PtrTy(Context), Type::getInt8PtrTy(Context), false), Function::ExternalLinkage, "__cxa_begin_catch", M);
Function* end_catch = Function::Create(FunctionType::get(Type::getVoidTy(Context), false), Function::ExternalLinkage, "__cxa_end_catch", M);
Function* testExceptions = cast<Function>(M->getOrInsertFunction("testExceptions", Type::getInt32Ty(Context), NULL));
BasicBlock* entryBB = BasicBlock::Create(Context, "", testExceptions);
BasicBlock* landPadBB = BasicBlock::Create(Context, "landPad", testExceptions);
BasicBlock* noErrorBB = BasicBlock::Create(Context, "noError", testExceptions);
IRBuilder<> builder(entryBB);
Value* invokeThrow = builder.CreateInvoke(throwFunc, noErrorBB, landPadBB);
builder.SetInsertPoint(noErrorBB);
builder.CreateRet( builder.getInt32(666) ); // should never happen
//writing landingpad! <<<<<<<
builder.SetInsertPoint(landPadBB);
Value* gxx_personality_i8 = builder.CreateBitCast(gxx_personality, Type::getInt8PtrTy(Context));
Type* caughtType = StructType::get(builder.getInt8PtrTy(), builder.getInt32Ty(), NULL);
LandingPadInst* caughtResult = builder.CreateLandingPad(caughtType, gxx_personality_i8, 1);
// we can catch any C++ exception we want
// but now we are catching MyStruct
caughtResult->addClause(MyStructTypeInfo);
//we are sure to catch MyStruct so no other checks are needed
//if throwMyStruct() throws anything but MyStruct it won't pass to the current landingpad BB
Value* thrownExctn = builder.CreateExtractValue(caughtResult, 0);
Value* thrownObject = builder.CreateCall(begin_catch, thrownExctn);
Value* object = builder.CreateBitCast(thrownObject, MyStructType->getPointerTo());
Value* resultPtr = builder.CreateStructGEP(object, 1);
Value* result = builder.CreateLoad(resultPtr);
builder.CreateCall(end_catch);
builder.CreateRet( result ); // << z.y
TargetOptions Opts;
Opts.JITExceptionHandling = true; // DO NOT FORGET THIS OPTION !!!!!!11
ExecutionEngine* EE = EngineBuilder(M)
.setEngineKind(EngineKind::JIT)
.setTargetOptions(Opts)
.create();
EE->addGlobalMapping(throwFunc, reinterpret_cast<void*>(&throwMyStruct));
EE->addGlobalMapping(MyStructTypeInfo, MyStruct::getTypeInfo());
verifyFunction(*testExceptions);
outs() << *testExceptions;
std::vector<GenericValue> noArgs;
GenericValue gv = EE->runFunction(testExceptions, noArgs);
outs() << "\ntestExceptions result: " << gv.IntVal << "\n";
delete EE;
llvm_shutdown();
return 0;
}
示例13: escapeRegNode
/// Assign every distinct landingpad a unique state number for SEH. Unlike C++
/// EH, we can use this very simple algorithm while C++ EH cannot because catch
/// handlers aren't outlined and the runtime doesn't have to figure out which
/// catch handler frame to unwind to.
/// FIXME: __finally blocks are outlined, so this approach may break down there.
void WinEHStatePass::addSEHStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
// Remember and return the index that we used. We save it in WinEHFuncInfo so
// that we can lower llvm.x86.seh.recoverfp later in filter functions without
// too much trouble.
int RegNodeEscapeIndex = escapeRegNode(F);
FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
// If this funciton uses the new EH IR, use the explicit state numbering
// algorithm and return early.
bool UsesLPads = false;
for (BasicBlock &BB : F) {
if (BB.isLandingPad()) {
UsesLPads = true;
break;
}
}
if (!UsesLPads) {
calculateSEHStateNumbers(&F, FuncInfo);
addStateStoresToFunclet(RegNode, FuncInfo, F, -1);
return;
}
// FIXME: Delete the rest of this code and clean things up when new EH is
// done.
// Iterate all the instructions and emit state number stores.
int CurState = 0;
SmallPtrSet<BasicBlock *, 4> ExceptBlocks;
for (BasicBlock &BB : F) {
for (auto I = BB.begin(), E = BB.end(); I != E; ++I) {
if (auto *CI = dyn_cast<CallInst>(I)) {
auto *Intrin = dyn_cast<IntrinsicInst>(CI);
if (Intrin) {
// Calls that "don't throw" are considered to be able to throw asynch
// exceptions, but intrinsics cannot.
continue;
}
insertStateNumberStore(RegNode, CI, -1);
} else if (auto *II = dyn_cast<InvokeInst>(I)) {
// Look up the state number of the landingpad this unwinds to.
LandingPadInst *LPI = II->getUnwindDest()->getLandingPadInst();
auto InsertionPair =
FuncInfo.EHPadStateMap.insert(std::make_pair(LPI, CurState));
auto Iter = InsertionPair.first;
int &State = Iter->second;
bool Inserted = InsertionPair.second;
if (Inserted) {
// Each action consumes a state number.
auto *EHActions = cast<IntrinsicInst>(LPI->getNextNode());
SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
parseEHActions(EHActions, ActionList);
assert(!ActionList.empty());
CurState += ActionList.size();
State += ActionList.size() - 1;
// Remember all the __except block targets.
for (auto &Handler : ActionList) {
if (auto *CH = dyn_cast<CatchHandler>(Handler.get())) {
auto *BA = cast<BlockAddress>(CH->getHandlerBlockOrFunc());
#ifndef NDEBUG
for (BasicBlock *Pred : predecessors(BA->getBasicBlock()))
assert(Pred->isLandingPad() &&
"WinEHPrepare failed to split block");
#endif
ExceptBlocks.insert(BA->getBasicBlock());
}
}
}
insertStateNumberStore(RegNode, II, State);
}
}
}
// Insert llvm.x86.seh.restoreframe() into each __except block.
Function *RestoreFrame =
Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_restoreframe);
for (BasicBlock *ExceptBB : ExceptBlocks) {
IRBuilder<> Builder(ExceptBB->begin());
Builder.CreateCall(RestoreFrame, {});
}
}