llvm.org GIT mirror llvm / c0e64ad
[WinEH] Add some support for code generating catchpad We can now run 32-bit programs with empty catch bodies. The next step is to change PEI so that we get funclet prologues and epilogues. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246235 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 4 years ago
38 changed file(s) with 362 addition(s) and 95 deletion(s). Raw diff Collapse all Expand all
164164 unsigned CreateRegs(Type *Ty);
165165
166166 unsigned InitializeRegForValue(const Value *V) {
167 // Tokens never live in vregs.
168 if (V->getType()->isTokenTy())
169 return 0;
167170 unsigned &R = ValueMap[V];
168171 assert(R == 0 && "Already initialized this value register!");
169172 return R = CreateRegs(V->getType());
589589 /// locations needed for debug and exception handling tables. These nodes
590590 /// take a chain as input and return a chain.
591591 EH_LABEL,
592
593 CATCHRET,
594
595 CLEANUPRET,
592596
593597 /// STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
594598 /// value, the same type as the pointer type for the system, and an output
8484
8585 /// Alignment of the basic block. Zero if the basic block does not need to be
8686 /// aligned. The alignment is specified as log2(bytes).
87 unsigned Alignment;
87 unsigned Alignment = 0;
8888
8989 /// Indicate that this basic block is entered via an exception handler.
90 bool IsLandingPad;
90 bool IsEHPad = false;
9191
9292 /// Indicate that this basic block is potentially the target of an indirect
9393 /// branch.
94 bool AddressTaken;
94 bool AddressTaken = false;
95
96 /// Indicate that this basic block is the entry block of an EH funclet.
97 bool IsEHFuncletEntry = false;
9598
9699 /// \brief since getSymbol is a relatively heavy-weight operation, the symbol
97100 /// is only computed once and is cached.
98 mutable MCSymbol *CachedMCSymbol;
101 mutable MCSymbol *CachedMCSymbol = nullptr;
99102
100103 // Intrusive list support
101104 MachineBasicBlock() {}
351354
352355 /// Returns true if the block is a landing pad. That is this basic block is
353356 /// entered via an exception handler.
354 bool isLandingPad() const { return IsLandingPad; }
357 bool isEHPad() const { return IsEHPad; }
355358
356359 /// Indicates the block is a landing pad. That is this basic block is entered
357360 /// via an exception handler.
358 void setIsLandingPad(bool V = true) { IsLandingPad = V; }
361 void setIsEHPad(bool V = true) { IsEHPad = V; }
359362
360363 /// If this block has a successor that is a landing pad, return it. Otherwise
361364 /// return NULL.
362365 const MachineBasicBlock *getLandingPadSuccessor() const;
366
367 /// Returns true if this is the entry block of an EH funclet.
368 bool isEHFuncletEntry() const { return IsEHFuncletEntry; }
369
370 /// Indicates if this is the entry block of an EH funclet.
371 void setIsEHFuncletEntry(bool V = true) { IsEHFuncletEntry = V; }
363372
364373 // Code Layout methods.
365374
162162
163163 bool CallsEHReturn;
164164 bool CallsUnwindInit;
165 bool HasEHFunclets;
165166
166167 /// DbgInfoAvailable - True if debugging information is available
167168 /// in this module.
370371 return LandingPads;
371372 }
372373
374 bool hasEHFunclets() const {
375 return HasEHFunclets;
376 }
377
378 void setHasEHFunclets(bool V) { HasEHFunclets = true; }
379
373380 /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call
374381 /// site indexes.
375382 void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef Sites);
263263 /// personality specific tasks. Returns true if the block should be
264264 /// instruction selected, false if no code should be emitted for it.
265265 bool PrepareEHLandingPad();
266 bool PrepareEHPad();
266267
267268 /// \brief Perform instruction selection on all basic blocks in the function.
268269 void SelectAllBasicBlocks(const Function &Fn);
2626 class IntrinsicInst;
2727 class LandingPadInst;
2828 class MCSymbol;
29 class MachineBasicBlock;
2930 class Value;
3031
3132 enum ActionType { Catch, Cleanup };
122123 GlobalVariable *TypeDescriptor;
123124 int CatchObjRecoverIdx;
124125 const Value *Handler;
126 MachineBasicBlock *HandlerMBB;
125127 };
126128
127129 struct WinEHTryBlockMapEntry {
450450 def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>;
451451 def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>;
452452 def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
453 def catchret : SDNode<"ISD::CATCHRET" , SDTBr, [SDNPHasChain]>;
454
453455 def trap : SDNode<"ISD::TRAP" , SDTNone,
454456 [SDNPHasChain, SDNPSideEffect]>;
455457 def debugtrap : SDNode<"ISD::DEBUGTRAP" , SDTNone,
24842484 }
24852485
24862486 // Print the main label for the block.
2487 if (MBB.pred_empty() || isBlockOnlyReachableByFallthrough(&MBB)) {
2487 if (MBB.pred_empty() ||
2488 (isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry())) {
24882489 if (isVerbose()) {
24892490 // NOTE: Want this comment at start of line, don't emit with AddComment.
24902491 OutStreamer->emitRawComment(" BB#" + Twine(MBB.getNumber()) + ":", false);
25222523 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
25232524 // If this is a landing pad, it isn't a fall through. If it has no preds,
25242525 // then nothing falls through to it.
2525 if (MBB->isLandingPad() || MBB->pred_empty())
2526 if (MBB->isEHPad() || MBB->pred_empty())
25262527 return false;
25272528
25282529 // If there isn't exactly one predecessor, it can't be a fall through.
6161
6262 // If any landing pads survive, we need an EH table.
6363 bool hasLandingPads = !MMI->getLandingPads().empty();
64 bool hasEHFunclets = MMI->hasEHFunclets();
6465
6566 const Function *F = MF->getFunction();
6667 const Function *ParentF = MMI->getWinEHParent(F);
7778 F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
7879 F->needsUnwindTableEntry();
7980
80 shouldEmitPersonality = forceEmitPersonality || (hasLandingPads &&
81 PerEncoding != dwarf::DW_EH_PE_omit && Per);
81 shouldEmitPersonality =
82 forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
83 PerEncoding != dwarf::DW_EH_PE_omit && Per);
8284
8385 unsigned LSDAEncoding = TLOF.getLSDAEncoding();
8486 shouldEmitLSDA = shouldEmitPersonality &&
8587 LSDAEncoding != dwarf::DW_EH_PE_omit;
8688
87 // If we're not using CFI, we don't want the CFI or the personality. If
88 // WinEHPrepare outlined something, we should emit the LSDA.
89 // If we're not using CFI, we don't want the CFI or the personality, but we
90 // might want EH tables if we had EH pads.
91 // FIXME: If WinEHPrepare outlined something, we should emit the LSDA. Remove
92 // this once WinEHPrepare stops doing that.
8993 if (!Asm->MAI->usesWindowsCFI()) {
90 bool HasOutlinedChildren =
91 F->hasFnAttribute("wineh-parent") && F == ParentF;
92 shouldEmitLSDA = HasOutlinedChildren;
94 shouldEmitLSDA =
95 hasEHFunclets || (F->hasFnAttribute("wineh-parent") && F == ParentF);
9396 shouldEmitPersonality = false;
9497 return;
9598 }
184187 const MCExpr *WinException::create32bitRef(const Value *V) {
185188 if (!V)
186189 return MCConstantExpr::create(0, Asm->OutContext);
187 return create32bitRef(Asm->getSymbol(cast(V)));
190 // FIXME: Delete the GlobalValue case once the new IR is fully functional.
191 if (const auto *GV = dyn_cast(V))
192 return create32bitRef(Asm->getSymbol(GV));
193 return create32bitRef(MMI->getAddrLabelSymbol(cast(V)));
188194 }
189195
190196 /// Emit the language-specific data that __C_specific_handler expects. This
319325
320326 extendIP2StateTable(MF, ParentF, FuncInfo);
321327
322 // Defer emission until we've visited the parent function and all the catch
323 // handlers. Cleanups don't contribute to the ip2state table, so don't count
324 // them.
325 if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
326 return;
327 ++FuncInfo.NumIPToStateFuncsVisited;
328 if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size())
329 return;
328 if (!MMI->hasEHFunclets()) {
329 // Defer emission until we've visited the parent function and all the
330 // catch handlers. Cleanups don't contribute to the ip2state table, so
331 // don't count them.
332 if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
333 return;
334 ++FuncInfo.NumIPToStateFuncsVisited;
335 if (FuncInfo.NumIPToStateFuncsVisited !=
336 FuncInfo.CatchHandlerMaxState.size())
337 return;
338 }
330339 } else {
331340 FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName);
332341 emitEHRegistrationOffsetLabel(FuncInfo, ParentLinkageName);
409418
410419 HandlerMaps.push_back(HandlerMapXData);
411420
412 int CatchHigh = -1;
413 for (WinEHHandlerType &HT : TBME.HandlerArray)
414 CatchHigh =
415 std::max(CatchHigh,
416 FuncInfo.CatchHandlerMaxState[cast(HT.Handler)]);
421 int CatchHigh = TBME.CatchHigh;
422 if (CatchHigh == -1) {
423 for (WinEHHandlerType &HT : TBME.HandlerArray)
424 CatchHigh = std::max(
425 CatchHigh,
426 FuncInfo.CatchHandlerMaxState[cast(HT.Handler)]);
427 }
417428
418429 assert(TBME.TryLow <= TBME.TryHigh);
419430 OS.EmitIntValue(TBME.TryLow, 4); // TryLow
455466 OS.EmitIntValue(HT.Adjectives, 4); // Adjectives
456467 OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type
457468 OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset
458 OS.EmitValue(create32bitRef(HT.Handler), 4); // Handler
469 if (HT.HandlerMBB) // Handler
470 OS.EmitValue(create32bitRef(HT.HandlerMBB->getSymbol()), 4);
471 else
472 OS.EmitValue(create32bitRef(HT.Handler), 4);
459473
460474 if (shouldEmitPersonality) {
461475 MCSymbol *ParentFrameOffset =
10001000 // Failing case: the only way IBB can be reached from PBB is via
10011001 // exception handling. Happens for landing pads. Would be nice to have
10021002 // a bit in the edge so we didn't have to do all this.
1003 if (IBB->isLandingPad()) {
1003 if (IBB->isEHPad()) {
10041004 MachineFunction::iterator IP = PBB; IP++;
10051005 MachineBasicBlock *PredNextBB = nullptr;
10061006 if (IP != MF.end())
11771177 // explicitly. Landing pads should not do this since the landing-pad table
11781178 // points to this block. Blocks with their addresses taken shouldn't be
11791179 // optimized away.
1180 if (IsEmptyBlock(MBB) && !MBB->isLandingPad() && !MBB->hasAddressTaken()) {
1180 if (IsEmptyBlock(MBB) && !MBB->isEHPad() && !MBB->hasAddressTaken()) {
11811181 // Dead block? Leave for cleanup later.
11821182 if (MBB->pred_empty()) return MadeChange;
11831183
11841184 if (FallThrough == MF.end()) {
11851185 // TODO: Simplify preds to not branch here if possible!
1186 } else if (FallThrough->isLandingPad()) {
1186 } else if (FallThrough->isEHPad()) {
11871187 // Don't rewrite to a landing pad fallthough. That could lead to the case
11881188 // where a BB jumps to more than one landing pad.
11891189 // TODO: Is it ever worth rewriting predecessors which don't already
12401240 // AnalyzeBranch.
12411241 if (PriorCond.empty() && !PriorTBB && MBB->pred_size() == 1 &&
12421242 PrevBB.succ_size() == 1 &&
1243 !MBB->hasAddressTaken() && !MBB->isLandingPad()) {
1243 !MBB->hasAddressTaken() && !MBB->isEHPad()) {
12441244 DEBUG(dbgs() << "\nMerging into block: " << PrevBB
12451245 << "From MBB: " << *MBB);
12461246 // Remove redundant DBG_VALUEs first.
14711471 // see if it has a fall-through into its successor.
14721472 bool CurFallsThru = MBB->canFallThrough();
14731473
1474 if (!MBB->isLandingPad()) {
1474 if (!MBB->isEHPad()) {
14751475 // Check all the predecessors of this block. If one of them has no fall
14761476 // throughs, move this block right after it.
14771477 for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
15221522 // fallthrough to happen.
15231523 if (SuccBB != MBB && &*SuccPrev != MBB &&
15241524 !SuccPrev->canFallThrough() && !CurUnAnalyzable &&
1525 !SuccBB->isLandingPad()) {
1525 !SuccBB->isEHPad()) {
15261526 MBB->moveBefore(SuccBB);
15271527 MadeChange = true;
15281528 goto ReoptimizeBlock;
298298 const MachineBasicBlock *MBB = MFI;
299299
300300 // We only care about ABI blocks: Entry + landing pads.
301 if ((MFI != MF->begin() && !MBB->isLandingPad()) || MBB->livein_empty())
301 if ((MFI != MF->begin() && !MBB->isEHPad()) || MBB->livein_empty())
302302 continue;
303303
304304 // Create phi-defs at Begin for all live-in registers.
597597 for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
598598 SE = MBB->succ_end(); SI != SE; ++SI) {
599599 MachineBasicBlock *SuccMBB = *SI;
600 if (SuccMBB->isLandingPad())
600 if (SuccMBB->isEHPad())
601601 continue;
602602 for (unsigned LI : SuccMBB->liveins()) {
603603 if (!TRI->isInAllocatableClass(LI))
367367 MBB->setAlignment(Alignment);
368368 if (HasAddressTaken)
369369 MBB->setHasAddressTaken();
370 MBB->setIsLandingPad(IsLandingPad);
370 MBB->setIsEHPad(IsLandingPad);
371371 return false;
372372 }
373373
438438 OS << "address-taken";
439439 HasAttributes = true;
440440 }
441 if (MBB.isLandingPad()) {
441 if (MBB.isEHPad()) {
442442 OS << (HasAttributes ? ", " : " (");
443443 OS << "landing-pad";
444444 HasAttributes = true;
3838 #define DEBUG_TYPE "codegen"
3939
4040 MachineBasicBlock::MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb)
41 : BB(bb), Number(-1), xParent(&mf), Alignment(0), IsLandingPad(false),
42 AddressTaken(false), CachedMCSymbol(nullptr) {
41 : BB(bb), Number(-1), xParent(&mf) {
4342 Insts.Parent = this;
4443 }
4544
202201 if (succ_size() > 2)
203202 return nullptr;
204203 for (const_succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
205 if ((*I)->isLandingPad())
204 if ((*I)->isEHPad())
206205 return *I;
207206 return nullptr;
208207 }
265264 LBB->printAsOperand(OS, /*PrintType=*/false, MST);
266265 Comma = ", ";
267266 }
268 if (isLandingPad()) { OS << Comma << "EH LANDING PAD"; Comma = ", "; }
267 if (isEHPad()) { OS << Comma << "EH LANDING PAD"; Comma = ", "; }
269268 if (hasAddressTaken()) { OS << Comma << "ADDRESS TAKEN"; Comma = ", "; }
270269 if (Alignment)
271270 OS << Comma << "Align " << Alignment << " (" << (1u << Alignment)
337336 assert(getParent() && "MBB must be inserted in function");
338337 assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) && "Expected physreg");
339338 assert(RC && "Register class is required");
340 assert((isLandingPad() || this == &getParent()->front()) &&
339 assert((isEHPad() || this == &getParent()->front()) &&
341340 "Only the entry block and landing pads can have physreg live ins");
342341
343342 bool LiveIn = isLiveIn(PhysReg);
395394 // its layout successor, insert a branch. First we have to locate the
396395 // only non-landing-pad successor, as that is the fallthrough block.
397396 for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) {
398 if ((*SI)->isLandingPad())
397 if ((*SI)->isEHPad())
399398 continue;
400399 assert(!TBB && "Found more than one non-landing-pad successor!");
401400 TBB = *SI;
431430 // as the fallthrough successor.
432431 MachineBasicBlock *FallthroughBB = nullptr;
433432 for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) {
434 if ((*SI)->isLandingPad() || *SI == TBB)
433 if ((*SI)->isEHPad() || *SI == TBB)
435434 continue;
436435 assert(!FallthroughBB && "Found more than one fallthrough successor.");
437436 FallthroughBB = *SI;
661660 MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
662661 // Splitting the critical edge to a landing pad block is non-trivial. Don't do
663662 // it in this generic function.
664 if (Succ->isLandingPad())
663 if (Succ->isEHPad())
665664 return nullptr;
666665
667666 MachineFunction *MF = getParent();
10451044 while (SI != succ_end()) {
10461045 const MachineBasicBlock *MBB = *SI;
10471046 if (!SeenMBBs.insert(MBB).second ||
1048 (MBB != DestA && MBB != DestB && !MBB->isLandingPad())) {
1047 (MBB != DestA && MBB != DestB && !MBB->isEHPad())) {
10491048 // This is a superfluous edge, remove it.
10501049 SI = removeSuccessor(SI);
10511050 Changed = true;
677677 uint32_t WeightScale = 0;
678678 uint32_t SumWeight = MBPI->getSumForBlock(MBB, WeightScale);
679679 for (MachineBasicBlock *Succ : MBB->successors()) {
680 if (Succ->isLandingPad())
680 if (Succ->isEHPad())
681681 continue;
682682 if (Succ == MBB)
683683 continue;
528528 // If the header of the loop containing this basic block is a landing pad,
529529 // then don't try to hoist instructions out of this loop.
530530 const MachineLoop *ML = MLI->getLoopFor(BB);
531 if (ML && ML->getHeader()->isLandingPad()) continue;
531 if (ML && ML->getHeader()->isEHPad()) continue;
532532
533533 // Conservatively treat live-in's as an external def.
534534 // FIXME: That means a reload that're reused in successor block(s) will not
724724 // If the header of the loop containing this basic block is a landing pad,
725725 // then don't try to hoist instructions out of this loop.
726726 const MachineLoop *ML = MLI->getLoopFor(BB);
727 if (ML && ML->getHeader()->isLandingPad())
727 if (ML && ML->getHeader()->isEHPad())
728728 continue;
729729
730730 // If this subregion is not in the top level loop at all, exit.
208208 CurCallSite = 0;
209209 CallsEHReturn = false;
210210 CallsUnwindInit = false;
211 HasEHFunclets = false;
211212 DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
212213 // Always emit some info, by default "no personality" info.
213214 Personalities.push_back(nullptr);
248249 FilterEnds.clear();
249250 CallsEHReturn = false;
250251 CallsUnwindInit = false;
252 HasEHFunclets = false;
251253 VariableDbgInfos.clear();
252254 }
253255
666666
667667 // It's not safe to sink instructions to EH landing pad. Control flow into
668668 // landing pad is implicitly defined.
669 if (SuccToSinkTo && SuccToSinkTo->isLandingPad())
669 if (SuccToSinkTo && SuccToSinkTo->isEHPad())
670670 return nullptr;
671671
672672 return SuccToSinkTo;
507507 // If this block has allocatable physical registers live-in, check that
508508 // it is an entry block or landing pad.
509509 for (unsigned LI : MBB->liveins()) {
510 if (isAllocatable(LI) && !MBB->isLandingPad() &&
510 if (isAllocatable(LI) && !MBB->isEHPad() &&
511511 MBB != MBB->getParent()->begin()) {
512512 report("MBB has allocable live-in, but isn't entry or landing-pad.", MBB);
513513 }
518518 SmallPtrSet LandingPadSuccs;
519519 for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
520520 E = MBB->succ_end(); I != E; ++I) {
521 if ((*I)->isLandingPad())
521 if ((*I)->isEHPad())
522522 LandingPadSuccs.insert(*I);
523523 if (!FunctionBlocks.count(*I))
524524 report("MBB has successor that isn't part of the function.", MBB);
16051605 assert(LiveInts->isLiveInToMBB(LR, MFI));
16061606 // We don't know how to track physregs into a landing pad.
16071607 if (!TargetRegisterInfo::isVirtualRegister(Reg) &&
1608 MFI->isLandingPad()) {
1608 MFI->isEHPad()) {
16091609 if (&*MFI == EndMBB)
16101610 break;
16111611 ++MFI;
547547 bool PHIElimination::SplitPHIEdges(MachineFunction &MF,
548548 MachineBasicBlock &MBB,
549549 MachineLoopInfo *MLI) {
550 if (MBB.empty() || !MBB.front().isPHI() || MBB.isLandingPad())
550 if (MBB.empty() || !MBB.front().isPHI() || MBB.isEHPad())
551551 return false; // Quick exit for basic blocks without PHIs.
552552
553553 const MachineLoop *CurLoop = MLI ? MLI->getLoopFor(&MBB) : nullptr;
2727 // Usually, we just want to insert the copy before the first terminator
2828 // instruction. However, for the edge going to a landing pad, we must insert
2929 // the copy before the call/invoke instruction.
30 if (!SuccMBB->isLandingPad())
30 if (!SuccMBB->isEHPad())
3131 return MBB->getFirstTerminator();
3232
3333 // Discover any defs/uses in this basic block.
251251 // Mark landing pad blocks.
252252 SmallVector LPads;
253253 for (BB = Fn->begin(); BB != EB; ++BB) {
254 if (const auto *Invoke = dyn_cast(BB->getTerminator()))
255 MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
256 if (BB->isLandingPad())
257 LPads.push_back(BB->getLandingPadInst());
254 if (BB->isEHPad())
255 MBBMap[BB]->setIsEHPad();
256 const Instruction *FNP = BB->getFirstNonPHI();
257 if (const auto *LPI = dyn_cast(FNP))
258 LPads.push_back(LPI);
258259 }
259260
260261 // If this is an MSVC EH personality, we need to do a bit more work.
261 EHPersonality Personality = EHPersonality::Unknown;
262 if (Fn->hasPersonalityFn())
263 Personality = classifyEHPersonality(Fn->getPersonalityFn());
262 if (!Fn->hasPersonalityFn())
263 return;
264 EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
264265 if (!isMSVCEHPersonality(Personality))
265266 return;
266267
271272
272273 WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn);
273274 if (Personality == EHPersonality::MSVC_CXX) {
275 // Calculate state numbers and then map from funclet BBs to MBBs.
274276 const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
275277 calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo);
278 for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap)
279 for (WinEHHandlerType &H : TBME.HandlerArray)
280 if (const auto *BB = dyn_cast(H.Handler))
281 H.HandlerMBB = MBBMap[BB];
276282 }
277283
278284 // Copy the state numbers to LandingPadInfo for the current function, which
11571157 llvm_unreachable("Can't get register for value!");
11581158 }
11591159
1160 void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
1161 // Update machine-CFG edges.
1162 MachineBasicBlock *PadMBB = FuncInfo.MBB;
1163 MachineBasicBlock *CatchingMBB = FuncInfo.MBBMap[I.getNormalDest()];
1164 MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()];
1165 PadMBB->addSuccessor(CatchingMBB);
1166 PadMBB->addSuccessor(UnwindMBB);
1167
1168 CatchingMBB->setIsEHFuncletEntry();
1169 MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
1170 MMI.setHasEHFunclets(true);
1171 }
1172
1173 void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
1174 // Update machine-CFG edge.
1175 MachineBasicBlock *PadMBB = FuncInfo.MBB;
1176 MachineBasicBlock *TargetMBB = FuncInfo.MBBMap[I.getSuccessor()];
1177 PadMBB->addSuccessor(TargetMBB);
1178
1179 // Create the terminator node.
1180 SDValue Ret = DAG.getNode(ISD::CATCHRET, getCurSDLoc(), MVT::Other,
1181 getControlRoot(), DAG.getBasicBlock(TargetMBB));
1182 DAG.setRoot(Ret);
1183 }
1184
1185 void SelectionDAGBuilder::visitCatchEndPad(const CatchEndPadInst &I) {
1186 // If this unwinds to caller, we don't need a DAG node hanging around.
1187 if (!I.hasUnwindDest())
1188 return;
1189
1190 // Update machine-CFG edge.
1191 MachineBasicBlock *PadMBB = FuncInfo.MBB;
1192 MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()];
1193 PadMBB->addSuccessor(UnwindMBB);
1194 }
1195
1196 void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) {
1197 MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
1198 MMI.setHasEHFunclets(true);
1199 report_fatal_error("visitCleanupPad not yet implemented!");
1200 }
1201
11601202 void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) {
11611203 report_fatal_error("visitCleanupRet not yet implemented!");
11621204 }
11631205
1164 void SelectionDAGBuilder::visitCatchEndPad(const CatchEndPadInst &I) {
1165 report_fatal_error("visitCatchEndPad not yet implemented!");
1166 }
1167
1168 void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
1169 report_fatal_error("visitCatchRet not yet implemented!");
1170 }
1171
1172 void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
1173 report_fatal_error("visitCatchPad not yet implemented!");
1174 }
1175
11761206 void SelectionDAGBuilder::visitTerminatePad(const TerminatePadInst &TPI) {
11771207 report_fatal_error("visitTerminatePad not yet implemented!");
1178 }
1179
1180 void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) {
1181 report_fatal_error("visitCleanupPad not yet implemented!");
11821208 }
11831209
11841210 void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
20202046 }
20212047
20222048 void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
2023 assert(FuncInfo.MBB->isLandingPad() &&
2049 assert(FuncInfo.MBB->isEHPad() &&
20242050 "Call to landingpad not in landing pad!");
20252051
20262052 MachineBasicBlock *MBB = FuncInfo.MBB;
50935119 assert(Reg && "cannot get exception code on this platform");
50945120 MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
50955121 const TargetRegisterClass *PtrRC = TLI.getRegClassFor(PtrVT);
5096 assert(FuncInfo.MBB->isLandingPad() && "eh.exceptioncode in non-lpad");
5122 assert(FuncInfo.MBB->isEHPad() && "eh.exceptioncode in non-lpad");
50975123 unsigned VReg = FuncInfo.MBB->addLiveIn(Reg, PtrRC);
50985124 SDValue N =
50995125 DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), VReg, PtrVT);
277277 case ISD::CALLSEQ_START: return "callseq_start";
278278 case ISD::CALLSEQ_END: return "callseq_end";
279279
280 // EH instructions
281 case ISD::CATCHRET: return "catchret";
282 case ISD::CLEANUPRET: return "cleanupret";
283
280284 // Other operators
281285 case ISD::LOAD: return "load";
282286 case ISD::STORE: return "store";
1818 #include "llvm/Analysis/AliasAnalysis.h"
1919 #include "llvm/Analysis/BranchProbabilityInfo.h"
2020 #include "llvm/Analysis/CFG.h"
21 #include "llvm/Analysis/LibCallSemantics.h"
2122 #include "llvm/Analysis/TargetLibraryInfo.h"
2223 #include "llvm/CodeGen/Analysis.h"
2324 #include "llvm/CodeGen/FastISel.h"
968969 InvokeBB->addSuccessor(ClauseBB);
969970
970971 // Mark the clause as a landing pad or MI passes will delete it.
971 ClauseBB->setIsLandingPad();
972 ClauseBB->setIsEHPad();
972973 }
973974 }
974975
997998 static bool isFoldedOrDeadInstruction(const Instruction *I,
998999 FunctionLoweringInfo *FuncInfo) {
9991000 return !I->mayWriteToMemory() && // Side-effecting instructions aren't folded.
1000 !isa(I) && // Terminators aren't folded.
1001 !isa(I) && // Terminators aren't folded.
10011002 !isa(I) && // Debug instructions aren't folded.
1002 !isa(I) && // Landingpad instructions aren't folded.
1003 !I->isEHPad() && // EH pad instructions aren't folded.
10031004 !FuncInfo->isExportedInst(I); // Exported instrs must be computed.
10041005 }
10051006
11621163 if (!PrepareEHLandingPad())
11631164 continue;
11641165
1166
11651167 // Before doing SelectionDAG ISel, see if FastISel has been requested.
11661168 if (FastIS) {
11671169 FastIS->startNewBlock();
12501252 // For the purpose of debugging, just abort.
12511253 report_fatal_error("FastISel didn't select the entire block");
12521254
1253 if (!Inst->getType()->isVoidTy() && !Inst->use_empty()) {
1255 if (!Inst->getType()->isVoidTy() && !Inst->getType()->isTokenTy() &&
1256 !Inst->use_empty()) {
12541257 unsigned &R = FuncInfo->ValueMap[Inst];
12551258 if (!R)
12561259 R = FuncInfo->CreateRegs(Inst->getType());
26072607 HT.TypeDescriptor =
26082608 cast(CS->getAggregateElement(1)->stripPointerCasts());
26092609 }
2610 HT.Handler = CPI->getParent();
2610 HT.Handler = CPI->getNormalDest();
2611 HT.HandlerMBB = nullptr;
26112612 // FIXME: Pass CPI->getArgOperand(1).
26122613 HT.CatchObjRecoverIdx = -1;
26132614 TBME.HandlerArray.push_back(HT);
26832684 cast(CS->getAggregateElement(1)->stripPointerCasts());
26842685 }
26852686 HT.Handler = cast(CH->getHandlerBlockOrFunc());
2687 HT.HandlerMBB = nullptr;
26862688 HT.CatchObjRecoverIdx = CH->getExceptionVarIndex();
26872689 TBME.HandlerArray.push_back(HT);
26882690 }
69306930 MachineModuleInfo &MMI = MF->getMMI();
69316931 for (MachineFunction::iterator BB = MF->begin(), E = MF->end(); BB != E;
69326932 ++BB) {
6933 if (!BB->isLandingPad()) continue;
6933 if (!BB->isEHPad()) continue;
69346934
69356935 // FIXME: We should assert that the EH_LABEL is the first MI in the landing
69366936 // pad.
69786978
69796979 // Shove the dispatch's address into the return slot in the function context.
69806980 MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
6981 DispatchBB->setIsLandingPad();
6981 DispatchBB->setIsEHPad();
69826982
69836983 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
69846984 unsigned trap_opcode;
72447244 BB->succ_end());
72457245 while (!Successors.empty()) {
72467246 MachineBasicBlock *SMBB = Successors.pop_back_val();
7247 if (SMBB->isLandingPad()) {
7247 if (SMBB->isEHPad()) {
72487248 BB->removeSuccessor(SMBB);
72497249 MBBLPads.push_back(SMBB);
72507250 }
72927292 // landing pad now.
72937293 for (SmallVectorImpl::iterator
72947294 I = MBBLPads.begin(), E = MBBLPads.end(); I != E; ++I)
7295 (*I)->setIsLandingPad(false);
7295 (*I)->setIsEHPad(false);
72967296
72977297 // The instruction is gone now.
72987298 MI->eraseFromParent();
950950 // be processed.
951951 for (succ_iterator I = B.succ_begin(), E = B.succ_end(); I != E; ++I) {
952952 const MachineBasicBlock *SB = *I;
953 if (SB->isLandingPad())
953 if (SB->isEHPad())
954954 Targets.insert(SB);
955955 }
956956 if (FallsThrough) {
404404
405405 // If this is a landing pad, it isn't a fall through. If it has no preds,
406406 // then nothing falls through to it.
407 if (MBB->isLandingPad() || MBB->pred_empty())
407 if (MBB->isEHPad() || MBB->pred_empty())
408408 return false;
409409
410410 // If there isn't exactly one predecessor, it can't be a fall through.
805805 const MachineBasicBlock *Dst1) {
806806 return Prob.getEdgeWeight(&B, Dst0) < Prob.getEdgeWeight(&B, Dst1);
807807 });
808 return S->isLandingPad() ? nullptr : S;
808 return S->isEHPad() ? nullptr : S;
809809 }
810810
811811 std::pair
406406 setOperationAction(ISD::SETCC , MVT::i64 , Custom);
407407 }
408408 setOperationAction(ISD::EH_RETURN , MVT::Other, Custom);
409 setOperationAction(ISD::CATCHRET , MVT::Other, Custom);
409410 // NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intended to support
410411 // SjLj exception handling but a light-weight setjmp/longjmp replacement to
411412 // support continuation, user-level threading, and etc.. As a result, no
1666316664 DAG.getRegister(StoreAddrReg, PtrVT));
1666416665 }
1666516666
16667 SDValue X86TargetLowering::LowerCATCHRET(SDValue Op, SelectionDAG &DAG) const {
16668 SDValue Chain = Op.getOperand(0);
16669 SDValue Dest = Op.getOperand(1);
16670 SDLoc DL(Op);
16671
16672 MVT PtrVT = getPointerTy(DAG.getDataLayout());
16673 unsigned ReturnReg = (PtrVT == MVT::i64 ? X86::RAX : X86::EAX);
16674
16675 // Load the address of the destination block.
16676 MachineBasicBlock *DestMBB = cast(Dest)->getBasicBlock();
16677 SDValue BlockPtr = DAG.getMCSymbol(DestMBB->getSymbol(), PtrVT);
16678 unsigned WrapperKind =
16679 Subtarget->isPICStyleRIPRel() ? X86ISD::WrapperRIP : X86ISD::Wrapper;
16680 SDValue WrappedPtr = DAG.getNode(WrapperKind, DL, PtrVT, BlockPtr);
16681 Chain = DAG.getCopyToReg(Chain, DL, ReturnReg, WrappedPtr);
16682 return DAG.getNode(X86ISD::CATCHRET, DL, MVT::Other, Chain,
16683 DAG.getRegister(ReturnReg, PtrVT));
16684 }
16685
1666616686 SDValue X86TargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
1666716687 SelectionDAG &DAG) const {
1666816688 SDLoc DL(Op);
1890218922 return LowerFRAME_TO_ARGS_OFFSET(Op, DAG);
1890318923 case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
1890418924 case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
18925 case ISD::CATCHRET: return LowerCATCHRET(Op, DAG);
1890518926 case ISD::EH_SJLJ_SETJMP: return lowerEH_SJLJ_SETJMP(Op, DAG);
1890618927 case ISD::EH_SJLJ_LONGJMP: return lowerEH_SJLJ_LONGJMP(Op, DAG);
1890718928 case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG);
1923719258 case X86ISD::EH_SJLJ_SETJMP: return "X86ISD::EH_SJLJ_SETJMP";
1923819259 case X86ISD::EH_SJLJ_LONGJMP: return "X86ISD::EH_SJLJ_LONGJMP";
1923919260 case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN";
19261 case X86ISD::CATCHRET: return "X86ISD::CATCHRET";
1924019262 case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN";
1924119263 case X86ISD::FNSTCW16m: return "X86ISD::FNSTCW16m";
1924219264 case X86ISD::FNSTSW16r: return "X86ISD::FNSTSW16r";
259259
260260 // Exception Handling helpers.
261261 EH_RETURN,
262
263 CATCHRET,
262264
263265 // SjLj exception handling setjmp.
264266 EH_SJLJ_SETJMP,
997999 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
9981000 SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const;
9991001 SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
1002 SDValue LowerCATCHRET(SDValue Op, SelectionDAG &DAG) const;
10001003 SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
10011004 SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
10021005 SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
149149 "ret\t#eh_return, addr: $addr",
150150 [(X86ehret GR64:$addr)], IIC_RET>, Sched<[WriteJumpLd]>;
151151
152 }
153
154 let isTerminator = 1, isBarrier = 1, hasCtrlDep = 1, isCodeGenOnly = 1 in {
155 def CATCHRET : I<0xC3, RawFrm, (outs), (ins GR32:$addr),
156 "ret{l}\t# CATCHRET",
157 [(X86catchret GR32:$addr)], IIC_RET>, Sched<[WriteJumpLd]>;
158 def CATCHRET64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
159 "ret{q}\t# CATCHRET",
160 [(X86catchret GR64:$addr)], IIC_RET>, Sched<[WriteJumpLd]>;
152161 }
153162
154163 let hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
203203
204204 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
205205 [SDNPHasChain]>;
206
207 def X86catchret : SDNode<"X86ISD::CATCHRET", SDT_X86EHRET, [SDNPHasChain]>;
206208
207209 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
208210 SDTypeProfile<1, 1, [SDTCisInt<0>,
525525
526526 case X86::EH_RETURN:
527527 case X86::EH_RETURN64: {
528 OutMI = MCInst();
529 OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
530 break;
531 }
532
533 case X86::CATCHRET: {
528534 OutMI = MCInst();
529535 OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
530536 break;
470470 void WinEHStatePass::addCXXStateStoresToFunclet(Value *ParentRegNode,
471471 WinEHFuncInfo &FuncInfo,
472472 Function &F, int BaseState) {
473 Function *RestoreFrame =
474 Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_restoreframe);
473475 // Iterate all the instructions and emit state number stores.
474476 for (BasicBlock &BB : F) {
475477 for (Instruction &I : BB) {
487489 int State = FuncInfo.EHPadStateMap[PadInst];
488490 insertStateNumberStore(ParentRegNode, II, State);
489491 }
492 }
493
494 // Insert calls to llvm.x86.seh.restoreframe at catchret destinations.
495 if (auto *CR = dyn_cast(BB.getTerminator())) {
496 //llvm::errs() << "BB: " << BB << '\n';
497 //llvm::errs() << "CR->getSuccessor(): " << *CR->getSuccessor() << '\n';
498 IRBuilder<> Builder(CR->getSuccessor()->begin());
499 Builder.CreateCall(RestoreFrame, {});
490500 }
491501 }
492502 }
0 ; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck --check-prefix=X86 %s
1 ; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck --check-prefix=X64 %s
2
3 ; Loosely based on IR for this C++ source code:
4 ; void f(int p);
5 ; int main() {
6 ; try {
7 ; f(1);
8 ; } catch (int) {
9 ; f(2);
10 ; } catch (...) {
11 ; f(3);
12 ; }
13 ; }
14
15 %rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
16 %eh.CatchableType = type { i32, i8*, i32, i32, i32, i32, i8* }
17 %eh.CatchableTypeArray.1 = type { i32, [1 x %eh.CatchableType*] }
18 %eh.ThrowInfo = type { i32, i8*, i8*, i8* }
19 %eh.CatchHandlerType = type { i32, i8* }
20
21 $"\01??_R0H@8" = comdat any
22
23 @"\01??_7type_info@@6B@" = external constant i8*
24 @"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
25
26 @llvm.eh.handlertype.H.0 = private unnamed_addr constant %eh.CatchHandlerType { i32 0, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*) }, section "llvm.metadata"
27 @llvm.eh.handlertype.H.1 = private unnamed_addr constant %eh.CatchHandlerType { i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*) }, section "llvm.metadata"
28
29 declare void @f(i32 %p)
30 declare i32 @__CxxFrameHandler3(...)
31
32 define i32 @try_catch_catch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
33 entry:
34 invoke void @f(i32 1)
35 to label %try.cont unwind label %catch.dispatch
36
37 catch.dispatch: ; preds = %entry
38 %0 = catchpad [%eh.CatchHandlerType* @llvm.eh.handlertype.H.0, i8* null]
39 to label %catch unwind label %catch.dispatch.2
40
41 catch: ; preds = %catch.dispatch
42 invoke void @f(i32 2)
43 to label %invoke.cont.2 unwind label %catchendblock
44
45 invoke.cont.2: ; preds = %catch
46 catchret %0 to label %try.cont
47
48 catch.dispatch.2: ; preds = %catch.dispatch
49 %1 = catchpad [%eh.CatchHandlerType* @llvm.eh.handlertype.H.0, i8* null]
50 to label %catch.2 unwind label %catchendblock
51
52 catch.2: ; preds = %catch.dispatch.2
53 invoke void @f(i32 3)
54 to label %invoke.cont.3 unwind label %catchendblock
55
56 invoke.cont.3: ; preds = %catch.2
57 catchret %1 to label %try.cont
58
59 try.cont: ; preds = %entry, %invoke.cont.2, %invoke.cont.3
60 ret i32 0
61
62 catchendblock: ; preds = %catch, %catch.2, %catch.dispatch.2
63 catchendpad unwind to caller
64 }
65
66 ; X86-LABEL: _try_catch_catch:
67 ; X86: movl $0, -{{[0-9]+}}(%ebp)
68 ; X86: movl $1, (%esp)
69 ; X86: calll _f
70 ; X86: [[contbb:LBB0_[0-9]+]]:
71 ; X86: movl -{{[0-9]+}}(%ebp), %esp
72 ; X86: retl
73
74 ; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
75 ; X86: movl $1, -{{[0-9]+}}(%ebp)
76 ; X86: movl $2, (%esp)
77 ; X86: calll _f
78 ; X86: movl $[[contbb]], %eax
79 ; X86-NEXT: retl
80
81 ; X86: [[catch2bb:LBB0_[0-9]+]]: # %catch.2{{$}}
82 ; X86: movl $1, -{{[0-9]+}}(%ebp)
83 ; X86: movl $3, (%esp)
84 ; X86: calll _f
85 ; X86: movl $[[contbb]], %eax
86 ; X86-NEXT: retl
87
88 ; X86: L__ehtable$try_catch_catch:
89 ; X86: $handlerMap$0$try_catch_catch:
90 ; X86: .long 0
91 ; X86: .long "??_R0H@8"
92 ; X86: .long 0
93 ; X86: .long [[catch1bb]]
94 ; X86: .long 0
95 ; X86: .long "??_R0H@8"
96 ; X86: .long 0
97 ; X86: .long [[catch2bb]]
98
99 ; X64-LABEL: try_catch_catch:
100 ; X64: movl $1, %ecx
101 ; X64: callq f
102 ; X64: [[contbb:\.LBB0_[0-9]+]]:
103 ; X64: retq
104
105 ; X64: [[catch1bb:\.LBB0_[0-9]+]]: # %catch{{$}}
106 ; X64: movl $2, %ecx
107 ; X64: callq f
108 ; X64: leaq [[contbb]](%rip), %rax
109 ; X64: retq
110
111 ; X64: [[catch2bb:\.LBB0_[0-9]+]]: # %catch.2{{$}}
112 ; X64: movl $3, %ecx
113 ; X64: callq f
114 ; X64: leaq [[contbb]](%rip), %rax
115 ; X64: retq
116
117 ; FIXME: Get rid of these parent_frame_offset things below. They are leftover
118 ; from our IR outlining strategy.
119 ; X64: $handlerMap$0$try_catch_catch:
120 ; X64: .long 0
121 ; X64: .long "??_R0H@8"@IMGREL
122 ; X64: .long 0
123 ; X64: .long [[catch1bb]]@IMGREL
124 ; X64 .long .Lcatch$parent_frame_offset
125 ; X64: .long 0
126 ; X64: .long "??_R0H@8"@IMGREL
127 ; X64: .long 0
128 ; X64: .long [[catch2bb]]@IMGREL
129 ; X64 .long .Lcatch.2$parent_frame_offset