llvm.org GIT mirror llvm / 5f50442
[WinEH] Start inserting state number stores for C++ EH This moves all the state numbering code for C++ EH to WinEHPrepare so that we can call it from the X86 state numbering IR pass that runs before isel. Now we just call the same state numbering machinery and insert a bunch of stores. It also populates MachineModuleInfo with information about the current function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238514 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 5 years ago
6 changed file(s) with 661 addition(s) and 417 deletion(s). Raw diff Collapse all Expand all
2222 class Constant;
2323 class Function;
2424 class GlobalVariable;
25 class InvokeInst;
2526 class IntrinsicInst;
2627 class LandingPadInst;
2728 class MCSymbol;
152153 NumIPToStateFuncsVisited(0) {}
153154 };
154155
156 /// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which
157 /// describes the state numbers and tables used by __CxxFrameHandler3. This
158 /// analysis assumes that WinEHPrepare has already been run.
159 void calculateWinCXXEHStateNumbers(const Function *ParentFn,
160 WinEHFuncInfo &FuncInfo);
161
155162 }
156163 #endif // LLVM_CODEGEN_WINEHFUNCINFO_H
7979 return ExtendKind;
8080 }
8181
82 namespace {
83 struct WinEHNumbering {
84 WinEHNumbering(WinEHFuncInfo &FuncInfo) : FuncInfo(FuncInfo),
85 CurrentBaseState(-1), NextState(0) {}
86
87 WinEHFuncInfo &FuncInfo;
88 int CurrentBaseState;
89 int NextState;
90
91 SmallVector, 4> HandlerStack;
92 SmallPtrSet VisitedHandlers;
93
94 int currentEHNumber() const {
95 return HandlerStack.empty() ? CurrentBaseState : HandlerStack.back()->getEHState();
96 }
97
98 void createUnwindMapEntry(int ToState, ActionHandler *AH);
99 void createTryBlockMapEntry(int TryLow, int TryHigh,
100 ArrayRef Handlers);
101 void processCallSite(MutableArrayRef> Actions,
102 ImmutableCallSite CS);
103 void popUnmatchedActions(int FirstMismatch);
104 void calculateStateNumbers(const Function &F);
105 void findActionRootLPads(const Function &F);
106 };
107 }
108
10982 void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
11083 SelectionDAG *DAG) {
11184 Fn = &fn;
290263 if (!isMSVCEHPersonality(Personality))
291264 return;
292265
293 WinEHFuncInfo *EHInfo = nullptr;
294266 if (Personality == EHPersonality::MSVC_Win64SEH) {
295267 addSEHHandlersForLPads(LPads);
296268 } else if (Personality == EHPersonality::MSVC_CXX) {
297269 const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
298 EHInfo = &MMI.getWinEHFuncInfo(WinEHParentFn);
299 if (EHInfo->LandingPadStateMap.empty()) {
300 WinEHNumbering Num(*EHInfo);
301 Num.findActionRootLPads(*WinEHParentFn);
302 // The VisitedHandlers list is used by both findActionRootLPads and
303 // calculateStateNumbers, but both functions need to visit all handlers.
304 Num.VisitedHandlers.clear();
305 Num.calculateStateNumbers(*WinEHParentFn);
306 // Pop everything on the handler stack.
307 // It may be necessary to call this more than once because a handler can
308 // be pushed on the stack as a result of clearing the stack.
309 while (!Num.HandlerStack.empty())
310 Num.processCallSite(None, ImmutableCallSite());
311 }
270 WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(WinEHParentFn);
271 calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo);
312272
313273 // Copy the state numbers to LandingPadInfo for the current function, which
314274 // could be a handler or the parent.
315275 for (const LandingPadInst *LP : LPads) {
316276 MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
317 MMI.addWinEHState(LPadMBB, EHInfo->LandingPadStateMap[LP]);
277 MMI.addWinEHState(LPadMBB, EHInfo.LandingPadStateMap[LP]);
318278 }
319279 }
320280 }
354314 MMI.addSEHCleanupHandler(LPadMBB, Fini);
355315 }
356316 }
357 }
358 }
359
360 void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) {
361 WinEHUnwindMapEntry UME;
362 UME.ToState = ToState;
363 if (auto *CH = dyn_cast_or_null(AH))
364 UME.Cleanup = cast(CH->getHandlerBlockOrFunc());
365 else
366 UME.Cleanup = nullptr;
367 FuncInfo.UnwindMap.push_back(UME);
368 }
369
370 void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh,
371 ArrayRef Handlers) {
372 // See if we already have an entry for this set of handlers.
373 // This is using iterators rather than a range-based for loop because
374 // if we find the entry we're looking for we'll need the iterator to erase it.
375 int NumHandlers = Handlers.size();
376 auto I = FuncInfo.TryBlockMap.begin();
377 auto E = FuncInfo.TryBlockMap.end();
378 for ( ; I != E; ++I) {
379 auto &Entry = *I;
380 if (Entry.HandlerArray.size() != (size_t)NumHandlers)
381 continue;
382 int N;
383 for (N = 0; N < NumHandlers; ++N) {
384 if (Entry.HandlerArray[N].Handler != Handlers[N]->getHandlerBlockOrFunc())
385 break; // breaks out of inner loop
386 }
387 // If all the handlers match, this is what we were looking for.
388 if (N == NumHandlers) {
389 break;
390 }
391 }
392
393 // If we found an existing entry for this set of handlers, extend the range
394 // but move the entry to the end of the map vector. The order of entries
395 // in the map is critical to the way that the runtime finds handlers.
396 // FIXME: Depending on what has happened with block ordering, this may
397 // incorrectly combine entries that should remain separate.
398 if (I != E) {
399 // Copy the existing entry.
400 WinEHTryBlockMapEntry Entry = *I;
401 Entry.TryLow = std::min(TryLow, Entry.TryLow);
402 Entry.TryHigh = std::max(TryHigh, Entry.TryHigh);
403 assert(Entry.TryLow <= Entry.TryHigh);
404 // Erase the old entry and add this one to the back.
405 FuncInfo.TryBlockMap.erase(I);
406 FuncInfo.TryBlockMap.push_back(Entry);
407 return;
408 }
409
410 // If we didn't find an entry, create a new one.
411 WinEHTryBlockMapEntry TBME;
412 TBME.TryLow = TryLow;
413 TBME.TryHigh = TryHigh;
414 assert(TBME.TryLow <= TBME.TryHigh);
415 for (CatchHandler *CH : Handlers) {
416 WinEHHandlerType HT;
417 if (CH->getSelector()->isNullValue()) {
418 HT.Adjectives = 0x40;
419 HT.TypeDescriptor = nullptr;
420 } else {
421 auto *GV = cast(CH->getSelector()->stripPointerCasts());
422 // Selectors are always pointers to GlobalVariables with 'struct' type.
423 // The struct has two fields, adjectives and a type descriptor.
424 auto *CS = cast(GV->getInitializer());
425 HT.Adjectives =
426 cast(CS->getAggregateElement(0U))->getZExtValue();
427 HT.TypeDescriptor =
428 cast(CS->getAggregateElement(1)->stripPointerCasts());
429 }
430 HT.Handler = cast(CH->getHandlerBlockOrFunc());
431 HT.CatchObjRecoverIdx = CH->getExceptionVarIndex();
432 TBME.HandlerArray.push_back(HT);
433 }
434 FuncInfo.TryBlockMap.push_back(TBME);
435 }
436
437 static void print_name(const Value *V) {
438 #ifndef NDEBUG
439 if (!V) {
440 DEBUG(dbgs() << "null");
441 return;
442 }
443
444 if (const auto *F = dyn_cast(V))
445 DEBUG(dbgs() << F->getName());
446 else
447 DEBUG(V->dump());
448 #endif
449 }
450
451 void WinEHNumbering::processCallSite(
452 MutableArrayRef> Actions,
453 ImmutableCallSite CS) {
454 DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber()
455 << ") for: ");
456 print_name(CS ? CS.getCalledValue() : nullptr);
457 DEBUG(dbgs() << '\n');
458
459 DEBUG(dbgs() << "HandlerStack: \n");
460 for (int I = 0, E = HandlerStack.size(); I < E; ++I) {
461 DEBUG(dbgs() << " ");
462 print_name(HandlerStack[I]->getHandlerBlockOrFunc());
463 DEBUG(dbgs() << '\n');
464 }
465 DEBUG(dbgs() << "Actions: \n");
466 for (int I = 0, E = Actions.size(); I < E; ++I) {
467 DEBUG(dbgs() << " ");
468 print_name(Actions[I]->getHandlerBlockOrFunc());
469 DEBUG(dbgs() << '\n');
470 }
471 int FirstMismatch = 0;
472 for (int E = std::min(HandlerStack.size(), Actions.size()); FirstMismatch < E;
473 ++FirstMismatch) {
474 if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
475 Actions[FirstMismatch]->getHandlerBlockOrFunc())
476 break;
477 }
478
479 // Remove unmatched actions from the stack and process their EH states.
480 popUnmatchedActions(FirstMismatch);
481
482 DEBUG(dbgs() << "Pushing actions for CallSite: ");
483 print_name(CS ? CS.getCalledValue() : nullptr);
484 DEBUG(dbgs() << '\n');
485
486 bool LastActionWasCatch = false;
487 const LandingPadInst *LastRootLPad = nullptr;
488 for (size_t I = FirstMismatch; I != Actions.size(); ++I) {
489 // We can reuse eh states when pushing two catches for the same invoke.
490 bool CurrActionIsCatch = isa(Actions[I].get());
491 auto *Handler = cast(Actions[I]->getHandlerBlockOrFunc());
492 // Various conditions can lead to a handler being popped from the
493 // stack and re-pushed later. That shouldn't create a new state.
494 // FIXME: Can code optimization lead to re-used handlers?
495 if (FuncInfo.HandlerEnclosedState.count(Handler)) {
496 // If we already assigned the state enclosed by this handler re-use it.
497 Actions[I]->setEHState(FuncInfo.HandlerEnclosedState[Handler]);
498 continue;
499 }
500 const LandingPadInst* RootLPad = FuncInfo.RootLPad[Handler];
501 if (CurrActionIsCatch && LastActionWasCatch && RootLPad == LastRootLPad) {
502 DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber() << "\n");
503 Actions[I]->setEHState(currentEHNumber());
504 } else {
505 DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", ");
506 print_name(Actions[I]->getHandlerBlockOrFunc());
507 DEBUG(dbgs() << ") with EH state " << NextState << "\n");
508 createUnwindMapEntry(currentEHNumber(), Actions[I].get());
509 DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n");
510 Actions[I]->setEHState(NextState);
511 NextState++;
512 }
513 HandlerStack.push_back(std::move(Actions[I]));
514 LastActionWasCatch = CurrActionIsCatch;
515 LastRootLPad = RootLPad;
516 }
517
518 // This is used to defer numbering states for a handler until after the
519 // last time it appears in an invoke action list.
520 if (CS.isInvoke()) {
521 for (int I = 0, E = HandlerStack.size(); I < E; ++I) {
522 auto *Handler = cast(HandlerStack[I]->getHandlerBlockOrFunc());
523 if (FuncInfo.LastInvoke[Handler] != cast(CS.getInstruction()))
524 continue;
525 FuncInfo.LastInvokeVisited[Handler] = true;
526 DEBUG(dbgs() << "Last invoke of ");
527 print_name(Handler);
528 DEBUG(dbgs() << " has been visited.\n");
529 }
530 }
531
532 DEBUG(dbgs() << "In EHState " << currentEHNumber() << " for CallSite: ");
533 print_name(CS ? CS.getCalledValue() : nullptr);
534 DEBUG(dbgs() << '\n');
535 }
536
537 void WinEHNumbering::popUnmatchedActions(int FirstMismatch) {
538 // Don't recurse while we are looping over the handler stack. Instead, defer
539 // the numbering of the catch handlers until we are done popping.
540 SmallVector PoppedCatches;
541 for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) {
542 std::unique_ptr Handler = HandlerStack.pop_back_val();
543 if (isa(Handler.get()))
544 PoppedCatches.push_back(cast(Handler.release()));
545 }
546
547 int TryHigh = NextState - 1;
548 int LastTryLowIdx = 0;
549 for (int I = 0, E = PoppedCatches.size(); I != E; ++I) {
550 CatchHandler *CH = PoppedCatches[I];
551 DEBUG(dbgs() << "Popped handler with state " << CH->getEHState() << "\n");
552 if (I + 1 == E || CH->getEHState() != PoppedCatches[I + 1]->getEHState()) {
553 int TryLow = CH->getEHState();
554 auto Handlers =
555 makeArrayRef(&PoppedCatches[LastTryLowIdx], I - LastTryLowIdx + 1);
556 DEBUG(dbgs() << "createTryBlockMapEntry(" << TryLow << ", " << TryHigh);
557 for (size_t J = 0; J < Handlers.size(); ++J) {
558 DEBUG(dbgs() << ", ");
559 print_name(Handlers[J]->getHandlerBlockOrFunc());
560 }
561 DEBUG(dbgs() << ")\n");
562 createTryBlockMapEntry(TryLow, TryHigh, Handlers);
563 LastTryLowIdx = I + 1;
564 }
565 }
566
567 for (CatchHandler *CH : PoppedCatches) {
568 if (auto *F = dyn_cast(CH->getHandlerBlockOrFunc())) {
569 if (FuncInfo.LastInvokeVisited[F]) {
570 DEBUG(dbgs() << "Assigning base state " << NextState << " to ");
571 print_name(F);
572 DEBUG(dbgs() << '\n');
573 FuncInfo.HandlerBaseState[F] = NextState;
574 DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber()
575 << ", null)\n");
576 createUnwindMapEntry(currentEHNumber(), nullptr);
577 ++NextState;
578 calculateStateNumbers(*F);
579 }
580 else {
581 DEBUG(dbgs() << "Deferring handling of ");
582 print_name(F);
583 DEBUG(dbgs() << " until last invoke visited.\n");
584 }
585 }
586 delete CH;
587 }
588 }
589
590 void WinEHNumbering::calculateStateNumbers(const Function &F) {
591 auto I = VisitedHandlers.insert(&F);
592 if (!I.second)
593 return; // We've already visited this handler, don't renumber it.
594
595 int OldBaseState = CurrentBaseState;
596 if (FuncInfo.HandlerBaseState.count(&F)) {
597 CurrentBaseState = FuncInfo.HandlerBaseState[&F];
598 }
599
600 size_t SavedHandlerStackSize = HandlerStack.size();
601
602 DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n');
603 SmallVector, 4> ActionList;
604 for (const BasicBlock &BB : F) {
605 for (const Instruction &I : BB) {
606 const auto *CI = dyn_cast(&I);
607 if (!CI || CI->doesNotThrow())
608 continue;
609 processCallSite(None, CI);
610 }
611 const auto *II = dyn_cast(BB.getTerminator());
612 if (!II)
613 continue;
614 const LandingPadInst *LPI = II->getLandingPadInst();
615 auto *ActionsCall = dyn_cast(LPI->getNextNode());
616 if (!ActionsCall)
617 continue;
618 assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions);
619 parseEHActions(ActionsCall, ActionList);
620 if (ActionList.empty())
621 continue;
622 processCallSite(ActionList, II);
623 ActionList.clear();
624 FuncInfo.LandingPadStateMap[LPI] = currentEHNumber();
625 DEBUG(dbgs() << "Assigning state " << currentEHNumber()
626 << " to landing pad at " << LPI->getParent()->getName()
627 << '\n');
628 }
629
630 // Pop any actions that were pushed on the stack for this function.
631 popUnmatchedActions(SavedHandlerStackSize);
632
633 DEBUG(dbgs() << "Assigning max state " << NextState - 1
634 << " to " << F.getName() << '\n');
635 FuncInfo.CatchHandlerMaxState[&F] = NextState - 1;
636
637 CurrentBaseState = OldBaseState;
638 }
639
640 // This function follows the same basic traversal as calculateStateNumbers
641 // but it is necessary to identify the root landing pad associated
642 // with each action before we start assigning state numbers.
643 void WinEHNumbering::findActionRootLPads(const Function &F) {
644 auto I = VisitedHandlers.insert(&F);
645 if (!I.second)
646 return; // We've already visited this handler, don't revisit it.
647
648 SmallVector, 4> ActionList;
649 for (const BasicBlock &BB : F) {
650 const auto *II = dyn_cast(BB.getTerminator());
651 if (!II)
652 continue;
653 const LandingPadInst *LPI = II->getLandingPadInst();
654 auto *ActionsCall = dyn_cast(LPI->getNextNode());
655 if (!ActionsCall)
656 continue;
657
658 assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions);
659 parseEHActions(ActionsCall, ActionList);
660 if (ActionList.empty())
661 continue;
662 for (int I = 0, E = ActionList.size(); I < E; ++I) {
663 if (auto *Handler
664 = dyn_cast(ActionList[I]->getHandlerBlockOrFunc())) {
665 FuncInfo.LastInvoke[Handler] = II;
666 // Don't replace the root landing pad if we previously saw this
667 // handler in a different function.
668 if (FuncInfo.RootLPad.count(Handler) &&
669 FuncInfo.RootLPad[Handler]->getParent()->getParent() != &F)
670 continue;
671 DEBUG(dbgs() << "Setting root lpad for ");
672 print_name(Handler);
673 DEBUG(dbgs() << " to " << LPI->getParent()->getName() << '\n');
674 FuncInfo.RootLPad[Handler] = LPI;
675 }
676 }
677 // Walk the actions again and look for nested handlers. This has to
678 // happen after all of the actions have been processed in the current
679 // function.
680 for (int I = 0, E = ActionList.size(); I < E; ++I)
681 if (auto *Handler
682 = dyn_cast(ActionList[I]->getHandlerBlockOrFunc()))
683 findActionRootLPads(*Handler);
684 ActionList.clear();
685317 }
686318 }
687319
24792479 }
24802480 std::reverse(Actions.begin(), Actions.end());
24812481 }
2482
2483 namespace {
2484 struct WinEHNumbering {
2485 WinEHNumbering(WinEHFuncInfo &FuncInfo) : FuncInfo(FuncInfo),
2486 CurrentBaseState(-1), NextState(0) {}
2487
2488 WinEHFuncInfo &FuncInfo;
2489 int CurrentBaseState;
2490 int NextState;
2491
2492 SmallVector, 4> HandlerStack;
2493 SmallPtrSet VisitedHandlers;
2494
2495 int currentEHNumber() const {
2496 return HandlerStack.empty() ? CurrentBaseState : HandlerStack.back()->getEHState();
2497 }
2498
2499 void createUnwindMapEntry(int ToState, ActionHandler *AH);
2500 void createTryBlockMapEntry(int TryLow, int TryHigh,
2501 ArrayRef Handlers);
2502 void processCallSite(MutableArrayRef> Actions,
2503 ImmutableCallSite CS);
2504 void popUnmatchedActions(int FirstMismatch);
2505 void calculateStateNumbers(const Function &F);
2506 void findActionRootLPads(const Function &F);
2507 };
2508 }
2509
2510 void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) {
2511 WinEHUnwindMapEntry UME;
2512 UME.ToState = ToState;
2513 if (auto *CH = dyn_cast_or_null(AH))
2514 UME.Cleanup = cast(CH->getHandlerBlockOrFunc());
2515 else
2516 UME.Cleanup = nullptr;
2517 FuncInfo.UnwindMap.push_back(UME);
2518 }
2519
2520 void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh,
2521 ArrayRef Handlers) {
2522 // See if we already have an entry for this set of handlers.
2523 // This is using iterators rather than a range-based for loop because
2524 // if we find the entry we're looking for we'll need the iterator to erase it.
2525 int NumHandlers = Handlers.size();
2526 auto I = FuncInfo.TryBlockMap.begin();
2527 auto E = FuncInfo.TryBlockMap.end();
2528 for ( ; I != E; ++I) {
2529 auto &Entry = *I;
2530 if (Entry.HandlerArray.size() != (size_t)NumHandlers)
2531 continue;
2532 int N;
2533 for (N = 0; N < NumHandlers; ++N) {
2534 if (Entry.HandlerArray[N].Handler != Handlers[N]->getHandlerBlockOrFunc())
2535 break; // breaks out of inner loop
2536 }
2537 // If all the handlers match, this is what we were looking for.
2538 if (N == NumHandlers) {
2539 break;
2540 }
2541 }
2542
2543 // If we found an existing entry for this set of handlers, extend the range
2544 // but move the entry to the end of the map vector. The order of entries
2545 // in the map is critical to the way that the runtime finds handlers.
2546 // FIXME: Depending on what has happened with block ordering, this may
2547 // incorrectly combine entries that should remain separate.
2548 if (I != E) {
2549 // Copy the existing entry.
2550 WinEHTryBlockMapEntry Entry = *I;
2551 Entry.TryLow = std::min(TryLow, Entry.TryLow);
2552 Entry.TryHigh = std::max(TryHigh, Entry.TryHigh);
2553 assert(Entry.TryLow <= Entry.TryHigh);
2554 // Erase the old entry and add this one to the back.
2555 FuncInfo.TryBlockMap.erase(I);
2556 FuncInfo.TryBlockMap.push_back(Entry);
2557 return;
2558 }
2559
2560 // If we didn't find an entry, create a new one.
2561 WinEHTryBlockMapEntry TBME;
2562 TBME.TryLow = TryLow;
2563 TBME.TryHigh = TryHigh;
2564 assert(TBME.TryLow <= TBME.TryHigh);
2565 for (CatchHandler *CH : Handlers) {
2566 WinEHHandlerType HT;
2567 if (CH->getSelector()->isNullValue()) {
2568 HT.Adjectives = 0x40;
2569 HT.TypeDescriptor = nullptr;
2570 } else {
2571 auto *GV = cast(CH->getSelector()->stripPointerCasts());
2572 // Selectors are always pointers to GlobalVariables with 'struct' type.
2573 // The struct has two fields, adjectives and a type descriptor.
2574 auto *CS = cast(GV->getInitializer());
2575 HT.Adjectives =
2576 cast(CS->getAggregateElement(0U))->getZExtValue();
2577 HT.TypeDescriptor =
2578 cast(CS->getAggregateElement(1)->stripPointerCasts());
2579 }
2580 HT.Handler = cast(CH->getHandlerBlockOrFunc());
2581 HT.CatchObjRecoverIdx = CH->getExceptionVarIndex();
2582 TBME.HandlerArray.push_back(HT);
2583 }
2584 FuncInfo.TryBlockMap.push_back(TBME);
2585 }
2586
2587 static void print_name(const Value *V) {
2588 #ifndef NDEBUG
2589 if (!V) {
2590 DEBUG(dbgs() << "null");
2591 return;
2592 }
2593
2594 if (const auto *F = dyn_cast(V))
2595 DEBUG(dbgs() << F->getName());
2596 else
2597 DEBUG(V->dump());
2598 #endif
2599 }
2600
2601 void WinEHNumbering::processCallSite(
2602 MutableArrayRef> Actions,
2603 ImmutableCallSite CS) {
2604 DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber()
2605 << ") for: ");
2606 print_name(CS ? CS.getCalledValue() : nullptr);
2607 DEBUG(dbgs() << '\n');
2608
2609 DEBUG(dbgs() << "HandlerStack: \n");
2610 for (int I = 0, E = HandlerStack.size(); I < E; ++I) {
2611 DEBUG(dbgs() << " ");
2612 print_name(HandlerStack[I]->getHandlerBlockOrFunc());
2613 DEBUG(dbgs() << '\n');
2614 }
2615 DEBUG(dbgs() << "Actions: \n");
2616 for (int I = 0, E = Actions.size(); I < E; ++I) {
2617 DEBUG(dbgs() << " ");
2618 print_name(Actions[I]->getHandlerBlockOrFunc());
2619 DEBUG(dbgs() << '\n');
2620 }
2621 int FirstMismatch = 0;
2622 for (int E = std::min(HandlerStack.size(), Actions.size()); FirstMismatch < E;
2623 ++FirstMismatch) {
2624 if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
2625 Actions[FirstMismatch]->getHandlerBlockOrFunc())
2626 break;
2627 }
2628
2629 // Remove unmatched actions from the stack and process their EH states.
2630 popUnmatchedActions(FirstMismatch);
2631
2632 DEBUG(dbgs() << "Pushing actions for CallSite: ");
2633 print_name(CS ? CS.getCalledValue() : nullptr);
2634 DEBUG(dbgs() << '\n');
2635
2636 bool LastActionWasCatch = false;
2637 const LandingPadInst *LastRootLPad = nullptr;
2638 for (size_t I = FirstMismatch; I != Actions.size(); ++I) {
2639 // We can reuse eh states when pushing two catches for the same invoke.
2640 bool CurrActionIsCatch = isa(Actions[I].get());
2641 auto *Handler = cast(Actions[I]->getHandlerBlockOrFunc());
2642 // Various conditions can lead to a handler being popped from the
2643 // stack and re-pushed later. That shouldn't create a new state.
2644 // FIXME: Can code optimization lead to re-used handlers?
2645 if (FuncInfo.HandlerEnclosedState.count(Handler)) {
2646 // If we already assigned the state enclosed by this handler re-use it.
2647 Actions[I]->setEHState(FuncInfo.HandlerEnclosedState[Handler]);
2648 continue;
2649 }
2650 const LandingPadInst* RootLPad = FuncInfo.RootLPad[Handler];
2651 if (CurrActionIsCatch && LastActionWasCatch && RootLPad == LastRootLPad) {
2652 DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber() << "\n");
2653 Actions[I]->setEHState(currentEHNumber());
2654 } else {
2655 DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", ");
2656 print_name(Actions[I]->getHandlerBlockOrFunc());
2657 DEBUG(dbgs() << ") with EH state " << NextState << "\n");
2658 createUnwindMapEntry(currentEHNumber(), Actions[I].get());
2659 DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n");
2660 Actions[I]->setEHState(NextState);
2661 NextState++;
2662 }
2663 HandlerStack.push_back(std::move(Actions[I]));
2664 LastActionWasCatch = CurrActionIsCatch;
2665 LastRootLPad = RootLPad;
2666 }
2667
2668 // This is used to defer numbering states for a handler until after the
2669 // last time it appears in an invoke action list.
2670 if (CS.isInvoke()) {
2671 for (int I = 0, E = HandlerStack.size(); I < E; ++I) {
2672 auto *Handler = cast(HandlerStack[I]->getHandlerBlockOrFunc());
2673 if (FuncInfo.LastInvoke[Handler] != cast(CS.getInstruction()))
2674 continue;
2675 FuncInfo.LastInvokeVisited[Handler] = true;
2676 DEBUG(dbgs() << "Last invoke of ");
2677 print_name(Handler);
2678 DEBUG(dbgs() << " has been visited.\n");
2679 }
2680 }
2681
2682 DEBUG(dbgs() << "In EHState " << currentEHNumber() << " for CallSite: ");
2683 print_name(CS ? CS.getCalledValue() : nullptr);
2684 DEBUG(dbgs() << '\n');
2685 }
2686
2687 void WinEHNumbering::popUnmatchedActions(int FirstMismatch) {
2688 // Don't recurse while we are looping over the handler stack. Instead, defer
2689 // the numbering of the catch handlers until we are done popping.
2690 SmallVector PoppedCatches;
2691 for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) {
2692 std::unique_ptr Handler = HandlerStack.pop_back_val();
2693 if (isa(Handler.get()))
2694 PoppedCatches.push_back(cast(Handler.release()));
2695 }
2696
2697 int TryHigh = NextState - 1;
2698 int LastTryLowIdx = 0;
2699 for (int I = 0, E = PoppedCatches.size(); I != E; ++I) {
2700 CatchHandler *CH = PoppedCatches[I];
2701 DEBUG(dbgs() << "Popped handler with state " << CH->getEHState() << "\n");
2702 if (I + 1 == E || CH->getEHState() != PoppedCatches[I + 1]->getEHState()) {
2703 int TryLow = CH->getEHState();
2704 auto Handlers =
2705 makeArrayRef(&PoppedCatches[LastTryLowIdx], I - LastTryLowIdx + 1);
2706 DEBUG(dbgs() << "createTryBlockMapEntry(" << TryLow << ", " << TryHigh);
2707 for (size_t J = 0; J < Handlers.size(); ++J) {
2708 DEBUG(dbgs() << ", ");
2709 print_name(Handlers[J]->getHandlerBlockOrFunc());
2710 }
2711 DEBUG(dbgs() << ")\n");
2712 createTryBlockMapEntry(TryLow, TryHigh, Handlers);
2713 LastTryLowIdx = I + 1;
2714 }
2715 }
2716
2717 for (CatchHandler *CH : PoppedCatches) {
2718 if (auto *F = dyn_cast(CH->getHandlerBlockOrFunc())) {
2719 if (FuncInfo.LastInvokeVisited[F]) {
2720 DEBUG(dbgs() << "Assigning base state " << NextState << " to ");
2721 print_name(F);
2722 DEBUG(dbgs() << '\n');
2723 FuncInfo.HandlerBaseState[F] = NextState;
2724 DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber()
2725 << ", null)\n");
2726 createUnwindMapEntry(currentEHNumber(), nullptr);
2727 ++NextState;
2728 calculateStateNumbers(*F);
2729 }
2730 else {
2731 DEBUG(dbgs() << "Deferring handling of ");
2732 print_name(F);
2733 DEBUG(dbgs() << " until last invoke visited.\n");
2734 }
2735 }
2736 delete CH;
2737 }
2738 }
2739
2740 void WinEHNumbering::calculateStateNumbers(const Function &F) {
2741 auto I = VisitedHandlers.insert(&F);
2742 if (!I.second)
2743 return; // We've already visited this handler, don't renumber it.
2744
2745 int OldBaseState = CurrentBaseState;
2746 if (FuncInfo.HandlerBaseState.count(&F)) {
2747 CurrentBaseState = FuncInfo.HandlerBaseState[&F];
2748 }
2749
2750 size_t SavedHandlerStackSize = HandlerStack.size();
2751
2752 DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n');
2753 SmallVector, 4> ActionList;
2754 for (const BasicBlock &BB : F) {
2755 for (const Instruction &I : BB) {
2756 const auto *CI = dyn_cast(&I);
2757 if (!CI || CI->doesNotThrow())
2758 continue;
2759 processCallSite(None, CI);
2760 }
2761 const auto *II = dyn_cast(BB.getTerminator());
2762 if (!II)
2763 continue;
2764 const LandingPadInst *LPI = II->getLandingPadInst();
2765 auto *ActionsCall = dyn_cast(LPI->getNextNode());
2766 if (!ActionsCall)
2767 continue;
2768 assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions);
2769 parseEHActions(ActionsCall, ActionList);
2770 if (ActionList.empty())
2771 continue;
2772 processCallSite(ActionList, II);
2773 ActionList.clear();
2774 FuncInfo.LandingPadStateMap[LPI] = currentEHNumber();
2775 DEBUG(dbgs() << "Assigning state " << currentEHNumber()
2776 << " to landing pad at " << LPI->getParent()->getName()
2777 << '\n');
2778 }
2779
2780 // Pop any actions that were pushed on the stack for this function.
2781 popUnmatchedActions(SavedHandlerStackSize);
2782
2783 DEBUG(dbgs() << "Assigning max state " << NextState - 1
2784 << " to " << F.getName() << '\n');
2785 FuncInfo.CatchHandlerMaxState[&F] = NextState - 1;
2786
2787 CurrentBaseState = OldBaseState;
2788 }
2789
2790 // This function follows the same basic traversal as calculateStateNumbers
2791 // but it is necessary to identify the root landing pad associated
2792 // with each action before we start assigning state numbers.
2793 void WinEHNumbering::findActionRootLPads(const Function &F) {
2794 auto I = VisitedHandlers.insert(&F);
2795 if (!I.second)
2796 return; // We've already visited this handler, don't revisit it.
2797
2798 SmallVector, 4> ActionList;
2799 for (const BasicBlock &BB : F) {
2800 const auto *II = dyn_cast(BB.getTerminator());
2801 if (!II)
2802 continue;
2803 const LandingPadInst *LPI = II->getLandingPadInst();
2804 auto *ActionsCall = dyn_cast(LPI->getNextNode());
2805 if (!ActionsCall)
2806 continue;
2807
2808 assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions);
2809 parseEHActions(ActionsCall, ActionList);
2810 if (ActionList.empty())
2811 continue;
2812 for (int I = 0, E = ActionList.size(); I < E; ++I) {
2813 if (auto *Handler
2814 = dyn_cast(ActionList[I]->getHandlerBlockOrFunc())) {
2815 FuncInfo.LastInvoke[Handler] = II;
2816 // Don't replace the root landing pad if we previously saw this
2817 // handler in a different function.
2818 if (FuncInfo.RootLPad.count(Handler) &&
2819 FuncInfo.RootLPad[Handler]->getParent()->getParent() != &F)
2820 continue;
2821 DEBUG(dbgs() << "Setting root lpad for ");
2822 print_name(Handler);
2823 DEBUG(dbgs() << " to " << LPI->getParent()->getName() << '\n');
2824 FuncInfo.RootLPad[Handler] = LPI;
2825 }
2826 }
2827 // Walk the actions again and look for nested handlers. This has to
2828 // happen after all of the actions have been processed in the current
2829 // function.
2830 for (int I = 0, E = ActionList.size(); I < E; ++I)
2831 if (auto *Handler
2832 = dyn_cast(ActionList[I]->getHandlerBlockOrFunc()))
2833 findActionRootLPads(*Handler);
2834 ActionList.clear();
2835 }
2836 }
2837
2838 void llvm::calculateWinCXXEHStateNumbers(const Function *ParentFn,
2839 WinEHFuncInfo &FuncInfo) {
2840 // Return if it's already been done.
2841 if (!FuncInfo.LandingPadStateMap.empty())
2842 return;
2843
2844 WinEHNumbering Num(FuncInfo);
2845 Num.findActionRootLPads(*ParentFn);
2846 // The VisitedHandlers list is used by both findActionRootLPads and
2847 // calculateStateNumbers, but both functions need to visit all handlers.
2848 Num.VisitedHandlers.clear();
2849 Num.calculateStateNumbers(*ParentFn);
2850 // Pop everything on the handler stack.
2851 // It may be necessary to call this more than once because a handler can
2852 // be pushed on the stack as a result of clearing the stack.
2853 while (!Num.HandlerStack.empty())
2854 Num.processCallSite(None, ImmutableCallSite());
2855 }
1515
1616 #include "X86.h"
1717 #include "llvm/Analysis/LibCallSemantics.h"
18 #include "llvm/CodeGen/MachineModuleInfo.h"
1819 #include "llvm/CodeGen/Passes.h"
1920 #include "llvm/CodeGen/WinEHFuncInfo.h"
2021 #include "llvm/IR/Dominators.h"
5859 private:
5960 void emitExceptionRegistrationRecord(Function *F);
6061
61 void linkExceptionRegistration(IRBuilder<> &Builder, Value *RegNode,
62 Value *Handler);
63 void unlinkExceptionRegistration(IRBuilder<> &Builder, Value *RegNode);
62 void linkExceptionRegistration(IRBuilder<> &Builder, Value *Handler);
63 void unlinkExceptionRegistration(IRBuilder<> &Builder);
64 void addCXXStateStores(Function &F, MachineModuleInfo &MMI);
65 void addCXXStateStoresToFunclet(Value *ParentRegNode, WinEHFuncInfo &FuncInfo,
66 Function &F, int BaseState);
67 void insertStateNumberStore(Value *ParentRegNode, Instruction *IP, int State);
6468
6569 Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
6670
6771 Function *generateLSDAInEAXThunk(Function *ParentFunc);
72
73 int escapeRegNode(Function &F);
6874
6975 // Module-level type getters.
7076 Type *getEHRegistrationType();
8288 // Per-function state
8389 EHPersonality Personality = EHPersonality::Unknown;
8490 Function *PersonalityFn = nullptr;
91
92 /// The stack allocation containing all EH data, including the link in the
93 /// fs:00 chain and the current state.
94 AllocaInst *RegNode = nullptr;
95
96 /// Struct type of RegNode. Used for GEPing.
97 Type *RegNodeTy = nullptr;
98
99 /// The index of the state field of RegNode.
100 int StateFieldIndex = ~0U;
101
102 /// The linked list node subobject inside of RegNode.
103 Value *Link = nullptr;
85104 };
86105 }
87106
136155 return false;
137156
138157 emitExceptionRegistrationRecord(&F);
139 // FIXME: State insertion.
158
159 auto *MMIPtr = getAnalysisIfAvailable();
160 assert(MMIPtr && "MachineModuleInfo should always be available");
161 MachineModuleInfo &MMI = *MMIPtr;
162 if (Personality == EHPersonality::MSVC_CXX) {
163 addCXXStateStores(F, MMI);
164 }
140165
141166 // Reset per-function state.
142167 PersonalityFn = nullptr;
237262 StringRef PersonalityName = PersonalityFn->getName();
238263 IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
239264 Type *Int8PtrType = Builder.getInt8PtrTy();
240 Value *SubRecord = nullptr;
241265 if (PersonalityName == "__CxxFrameHandler3") {
242 Type *RegNodeTy = getCXXEH3RegistrationType();
243 Value *RegNode = Builder.CreateAlloca(RegNodeTy);
266 RegNodeTy = getCXXEH3RegistrationType();
267 RegNode = Builder.CreateAlloca(RegNodeTy);
244268 // FIXME: We can skip this in -GS- mode, when we figure that out.
245269 // SavedESP = llvm.stacksave()
246270 Value *SP = Builder.CreateCall(
247271 Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
248272 Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
249273 // TryLevel = -1
250 Builder.CreateStore(Builder.getInt32(-1),
251 Builder.CreateStructGEP(RegNodeTy, RegNode, 2));
274 StateFieldIndex = 2;
275 insertStateNumberStore(RegNode, Builder.GetInsertPoint(), -1);
252276 // Handler = __ehhandler$F
253277 Function *Trampoline = generateLSDAInEAXThunk(F);
254 SubRecord = Builder.CreateStructGEP(RegNodeTy, RegNode, 1);
255 linkExceptionRegistration(Builder, SubRecord, Trampoline);
278 Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 1);
279 linkExceptionRegistration(Builder, Trampoline);
256280 } else if (PersonalityName == "_except_handler3") {
257 Type *RegNodeTy = getSEH3RegistrationType();
258 Value *RegNode = Builder.CreateAlloca(RegNodeTy);
281 RegNodeTy = getSEH3RegistrationType();
282 RegNode = Builder.CreateAlloca(RegNodeTy);
259283 // TryLevel = -1
260 Builder.CreateStore(Builder.getInt32(-1),
261 Builder.CreateStructGEP(RegNodeTy, RegNode, 2));
284 StateFieldIndex = 2;
285 insertStateNumberStore(RegNode, Builder.GetInsertPoint(), -1);
262286 // ScopeTable = llvm.x86.seh.lsda(F)
263287 Value *LSDA = emitEHLSDA(Builder, F);
264288 Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 1));
265 SubRecord = Builder.CreateStructGEP(RegNodeTy, RegNode, 0);
266 linkExceptionRegistration(Builder, SubRecord, PersonalityFn);
289 Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 0);
290 linkExceptionRegistration(Builder, PersonalityFn);
267291 } else if (PersonalityName == "_except_handler4") {
268 Type *RegNodeTy = getSEH4RegistrationType();
269 Value *RegNode = Builder.CreateAlloca(RegNodeTy);
292 RegNodeTy = getSEH4RegistrationType();
293 RegNode = Builder.CreateAlloca(RegNodeTy);
270294 // SavedESP = llvm.stacksave()
271295 Value *SP = Builder.CreateCall(
272296 Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
273297 Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
274 // TryLevel = -2
275 Builder.CreateStore(Builder.getInt32(-2),
276 Builder.CreateStructGEP(RegNodeTy, RegNode, 4));
298 // TryLevel = -1
299 StateFieldIndex = 4;
300 insertStateNumberStore(RegNode, Builder.GetInsertPoint(), -1);
277301 // FIXME: XOR the LSDA with __security_cookie.
278302 // ScopeTable = llvm.x86.seh.lsda(F)
279303 Value *FI8 = Builder.CreateBitCast(F, Int8PtrType);
280304 Value *LSDA = Builder.CreateCall(
281305 Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_lsda), FI8);
282306 Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 1));
283 SubRecord = Builder.CreateStructGEP(RegNodeTy, RegNode, 2);
284 linkExceptionRegistration(Builder, SubRecord, PersonalityFn);
307 Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 2);
308 linkExceptionRegistration(Builder, PersonalityFn);
285309 } else {
286310 llvm_unreachable("unexpected personality function");
287311 }
288312
289 // FIXME: Insert an unlink before all returns.
313 // Insert an unlink before all returns.
290314 for (BasicBlock &BB : *F) {
291315 TerminatorInst *T = BB.getTerminator();
292316 if (!isa(T))
293317 continue;
294318 Builder.SetInsertPoint(T);
295 unlinkExceptionRegistration(Builder, SubRecord);
319 unlinkExceptionRegistration(Builder);
296320 }
297321 }
298322
341365 }
342366
343367 void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
344 Value *RegNode, Value *Handler) {
345 Type *RegNodeTy = getEHRegistrationType();
368 Value *Handler) {
369 Type *LinkTy = getEHRegistrationType();
346370 // Handler = Handler
347371 Handler = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
348 Builder.CreateStore(Handler, Builder.CreateStructGEP(RegNodeTy, RegNode, 1));
372 Builder.CreateStore(Handler, Builder.CreateStructGEP(LinkTy, Link, 1));
349373 // Next = [fs:00]
350374 Constant *FSZero =
351 Constant::getNullValue(RegNodeTy->getPointerTo()->getPointerTo(257));
375 Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
352376 Value *Next = Builder.CreateLoad(FSZero);
353 Builder.CreateStore(Next, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
354 // [fs:00] = RegNode
355 Builder.CreateStore(RegNode, FSZero);
356 }
357
358 void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder,
359 Value *RegNode) {
360 // Clone RegNode into the current BB for better address mode folding.
361 if (auto *GEP = dyn_cast(RegNode)) {
377 Builder.CreateStore(Next, Builder.CreateStructGEP(LinkTy, Link, 0));
378 // [fs:00] = Link
379 Builder.CreateStore(Link, FSZero);
380 }
381
382 void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
383 // Clone Link into the current BB for better address mode folding.
384 if (auto *GEP = dyn_cast(Link)) {
362385 GEP = cast(GEP->clone());
363386 Builder.Insert(GEP);
364 RegNode = GEP;
365 }
366 Type *RegNodeTy = getEHRegistrationType();
367 // [fs:00] = RegNode->Next
387 Link = GEP;
388 }
389 Type *LinkTy = getEHRegistrationType();
390 // [fs:00] = Link->Next
368391 Value *Next =
369 Builder.CreateLoad(Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
392 Builder.CreateLoad(Builder.CreateStructGEP(LinkTy, Link, 0));
370393 Constant *FSZero =
371 Constant::getNullValue(RegNodeTy->getPointerTo()->getPointerTo(257));
394 Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
372395 Builder.CreateStore(Next, FSZero);
373396 }
397
398 void WinEHStatePass::addCXXStateStores(Function &F, MachineModuleInfo &MMI) {
399 WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(&F);
400 calculateWinCXXEHStateNumbers(&F, FuncInfo);
401
402 // The base state for the parent is -1.
403 addCXXStateStoresToFunclet(RegNode, FuncInfo, F, -1);
404
405 // Set up RegNodeEscapeIndex
406 int RegNodeEscapeIndex = escapeRegNode(F);
407
408 // Only insert stores in catch handlers.
409 Function *FrameRecover =
410 Intrinsic::getDeclaration(TheModule, Intrinsic::framerecover);
411 Function *FrameAddress =
412 Intrinsic::getDeclaration(TheModule, Intrinsic::frameaddress);
413 Constant *FI8 =
414 ConstantExpr::getBitCast(&F, Type::getInt8PtrTy(TheModule->getContext()));
415 for (auto P : FuncInfo.HandlerBaseState) {
416 Function *Handler = const_cast(P.first);
417 int BaseState = P.second;
418 IRBuilder<> Builder(&Handler->getEntryBlock(),
419 Handler->getEntryBlock().begin());
420 // FIXME: Find and reuse such a call if present.
421 Value *ParentFP = Builder.CreateCall(FrameAddress, {Builder.getInt32(1)});
422 Value *RecoveredRegNode = Builder.CreateCall(
423 FrameRecover, {FI8, ParentFP, Builder.getInt32(RegNodeEscapeIndex)});
424 RecoveredRegNode =
425 Builder.CreateBitCast(RecoveredRegNode, RegNodeTy->getPointerTo(0));
426 addCXXStateStoresToFunclet(RecoveredRegNode, FuncInfo, *Handler, BaseState);
427 }
428 }
429
430 /// Escape RegNode so that we can access it from child handlers. Find the call
431 /// to frameescape, if any, in the entry block and append RegNode to the list
432 /// of arguments.
433 int WinEHStatePass::escapeRegNode(Function &F) {
434 // Find the call to frameescape and extract its arguments.
435 IntrinsicInst *EscapeCall = nullptr;
436 for (Instruction &I : F.getEntryBlock()) {
437 IntrinsicInst *II = dyn_cast(&I);
438 if (II && II->getIntrinsicID() == Intrinsic::frameescape) {
439 EscapeCall = II;
440 break;
441 }
442 }
443 SmallVector Args;
444 if (EscapeCall) {
445 auto Ops = EscapeCall->arg_operands();
446 Args.append(Ops.begin(), Ops.end());
447 }
448 Args.push_back(RegNode);
449
450 // Replace the call (if it exists) with new one. Otherwise, insert at the end
451 // of the entry block.
452 IRBuilder<> Builder(&F.getEntryBlock(),
453 EscapeCall ? EscapeCall : F.getEntryBlock().end());
454 Builder.CreateCall(
455 Intrinsic::getDeclaration(TheModule, Intrinsic::frameescape), Args);
456 if (EscapeCall)
457 EscapeCall->eraseFromParent();
458 return Args.size() - 1;
459 }
460
461 void WinEHStatePass::addCXXStateStoresToFunclet(Value *ParentRegNode,
462 WinEHFuncInfo &FuncInfo,
463 Function &F, int BaseState) {
464 // Iterate all the instructions and emit state number stores.
465 for (BasicBlock &BB : F) {
466 for (Instruction &I : BB) {
467 if (auto *CI = dyn_cast(&I)) {
468 // Possibly throwing call instructions have no actions to take after
469 // an unwind. Ensure they are in the -1 state.
470 if (CI->doesNotThrow())
471 continue;
472 insertStateNumberStore(ParentRegNode, CI, BaseState);
473 } else if (auto *II = dyn_cast(&I)) {
474 // Look up the state number of the landingpad this unwinds to.
475 LandingPadInst *LPI = II->getUnwindDest()->getLandingPadInst();
476 // FIXME: Why does this assertion fail?
477 //assert(FuncInfo.LandingPadStateMap.count(LPI) && "LP has no state!");
478 int State = FuncInfo.LandingPadStateMap[LPI];
479 insertStateNumberStore(ParentRegNode, II, State);
480 }
481 }
482 }
483 }
484
485 void WinEHStatePass::insertStateNumberStore(Value *ParentRegNode,
486 Instruction *IP, int State) {
487 IRBuilder<> Builder(IP);
488 Value *StateField =
489 Builder.CreateStructGEP(RegNodeTy, ParentRegNode, StateFieldIndex);
490 Builder.CreateStore(Builder.getInt32(State), StateField);
491 }
0 ; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck %s
1
2 ; Based on this source:
3 ; extern "C" void may_throw(int);
4 ; void f() {
5 ; try {
6 ; may_throw(1);
7 ; try {
8 ; may_throw(2);
9 ; } catch (int) {
10 ; may_throw(3);
11 ; }
12 ; } catch (int) {
13 ; may_throw(4);
14 ; }
15 ; }
16
17 %rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
18 %eh.CatchHandlerType = type { i32, i8* }
19
20 declare void @may_throw(i32)
21 declare i32 @__CxxFrameHandler3(...)
22 declare void @llvm.eh.begincatch(i8*, i8*)
23 declare void @llvm.eh.endcatch()
24 declare i32 @llvm.eh.typeid.for(i8*)
25
26 $"\01??_R0H@8" = comdat any
27
28 @"\01??_7type_info@@6B@" = external constant i8*
29 @"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
30 @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"
31
32 define void @f() #0 {
33 entry:
34 invoke void @may_throw(i32 1)
35 to label %invoke.cont unwind label %lpad
36
37 invoke.cont: ; preds = %entry
38 invoke void @may_throw(i32 2)
39 to label %try.cont.9 unwind label %lpad.1
40
41 try.cont.9: ; preds = %invoke.cont.3, %invoke.cont, %catch.7
42 ; FIXME: Something about our CFG breaks TailDuplication. This empy asm blocks
43 ; it so we can focus on testing the state numbering.
44 call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"()
45 ret void
46
47 lpad: ; preds = %catch, %entry
48 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
49 catch %eh.CatchHandlerType* @llvm.eh.handlertype.H.0
50 %1 = extractvalue { i8*, i32 } %0, 0
51 %2 = extractvalue { i8*, i32 } %0, 1
52 br label %catch.dispatch.4
53
54 lpad.1: ; preds = %invoke.cont
55 %3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
56 catch i8* bitcast (%eh.CatchHandlerType* @llvm.eh.handlertype.H.0 to i8*)
57 %4 = extractvalue { i8*, i32 } %3, 0
58 %5 = extractvalue { i8*, i32 } %3, 1
59 %6 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%eh.CatchHandlerType* @llvm.eh.handlertype.H.0 to i8*)) #3
60 %matches = icmp eq i32 %5, %6
61 br i1 %matches, label %catch, label %catch.dispatch.4
62
63 catch.dispatch.4: ; preds = %lpad.1, %lpad
64 %exn.slot.0 = phi i8* [ %4, %lpad.1 ], [ %1, %lpad ]
65 %ehselector.slot.0 = phi i32 [ %5, %lpad.1 ], [ %2, %lpad ]
66 %.pre = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%eh.CatchHandlerType* @llvm.eh.handlertype.H.0 to i8*)) #3
67 %matches6 = icmp eq i32 %ehselector.slot.0, %.pre
68 br i1 %matches6, label %catch.7, label %eh.resume
69
70 catch.7: ; preds = %catch.dispatch.4
71 tail call void @llvm.eh.begincatch(i8* %exn.slot.0, i8* null) #3
72 tail call void @may_throw(i32 4)
73 tail call void @llvm.eh.endcatch() #3
74 br label %try.cont.9
75
76 catch: ; preds = %lpad.1
77 tail call void @llvm.eh.begincatch(i8* %4, i8* null) #3
78 invoke void @may_throw(i32 3)
79 to label %invoke.cont.3 unwind label %lpad
80
81 invoke.cont.3: ; preds = %catch
82 tail call void @llvm.eh.endcatch() #3
83 br label %try.cont.9
84
85 eh.resume: ; preds = %catch.dispatch.4
86 %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn.slot.0, 0
87 %lpad.val.12 = insertvalue { i8*, i32 } %lpad.val, i32 %ehselector.slot.0, 1
88 resume { i8*, i32 } %lpad.val.12
89 }
90
91 ; CHECK-LABEL: _f:
92 ; CHECK: movl $-1, [[state:[0-9]+]](%esp)
93 ; CHECK: movl $___ehhandler$f, {{.*}}
94 ;
95 ; CHECK: movl $0, [[state]](%esp)
96 ; CHECK: movl $1, (%esp)
97 ; CHECK: calll _may_throw
98 ;
99 ; CHECK: movl $1, [[state]](%esp)
100 ; CHECK: movl $2, (%esp)
101 ; CHECK: calll _may_throw
102
103 ; CHECK-LABEL: _f.catch:
104 ; CHECK: movl $4, Lf$frame_escape_{{[0-9]+.*}}
105 ; CHECK: movl $4, (%esp)
106 ; CHECK: calll _may_throw
107
108 ; CHECK-LABEL: _f.catch.1:
109 ; CHECK: movl $3, Lf$frame_escape_{{[0-9]+.*}}
110 ; CHECK: movl $3, (%esp)
111 ; CHECK: calll _may_throw
4545 ; CHECK-LABEL: _use_except_handler4:
4646 ; CHECK: subl ${{[0-9]+}}, %esp
4747 ; CHECK: movl %esp, (%esp)
48 ; CHECK: movl $-2, 20(%esp)
48 ; CHECK: movl $-1, 20(%esp)
4949 ; CHECK: movl $L__ehtable$use_except_handler4, 4(%esp)
5050 ; CHECK: leal 8(%esp), %[[node:[^ ,]*]]
5151 ; CHECK: movl $__except_handler4, 12(%esp)
8080 ; CHECK: movl %fs:0, %[[next:[^ ,]*]]
8181 ; CHECK: movl %[[next]], 4(%esp)
8282 ; CHECK: movl %[[node]], %fs:0
83 ; CHECK: movl $0, 12(%esp)
8384 ; CHECK: calll _may_throw_or_crash
8485 ; CHECK: movl 4(%esp), %[[next:[^ ,]*]]
8586 ; CHECK: movl %[[next]], %fs:0