Skip to content

Commit 92fbbeb

Browse files
committed
[WinEH] Restore states after SEH scope end
1 parent e2ecad2 commit 92fbbeb

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

llvm/lib/Target/X86/X86WinEHState.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -608,10 +608,17 @@ static int getSuccState(DenseMap<BasicBlock *, int> &InitialStates, Function &F,
608608
return CommonState;
609609
}
610610

611-
static bool isSehScopeBegin(const CallBase &Call) {
611+
static bool isIntrinsic(const CallBase &Call, Intrinsic::ID ID) {
612612
const Function *CF = Call.getCalledFunction();
613-
return CF && CF->isIntrinsic() &&
614-
CF->getIntrinsicID() == Intrinsic::seh_scope_begin;
613+
return CF && CF->isIntrinsic() && CF->getIntrinsicID() == ID;
614+
}
615+
616+
static bool isSehScopeEnd(const CallBase &Call) {
617+
return isIntrinsic(Call, Intrinsic::seh_scope_end);
618+
}
619+
620+
static bool isSehScopeBegin(const CallBase &Call) {
621+
return isIntrinsic(Call, Intrinsic::seh_scope_begin);
615622
}
616623

617624
bool WinEHStatePass::isStateStoreNeeded(EHPersonality Personality,
@@ -656,6 +663,8 @@ void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
656663
DenseMap<BasicBlock *, int> InitialStates;
657664
// FinalStates yields the state of the last call-site for a BasicBlock.
658665
DenseMap<BasicBlock *, int> FinalStates;
666+
// SEH scope end target blocks
667+
SmallPtrSet<BasicBlock *, 4> ScopeEndBlocks;
659668
// Worklist used to revisit BasicBlocks with indeterminate
660669
// Initial/Final-States.
661670
std::deque<BasicBlock *> Worklist;
@@ -667,7 +676,15 @@ void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
667676
InitialState = FinalState = ParentBaseState;
668677
for (Instruction &I : *BB) {
669678
auto *Call = dyn_cast<CallBase>(&I);
670-
if (!Call || !isStateStoreNeeded(Personality, *Call))
679+
if (!Call)
680+
continue;
681+
682+
if (isSehScopeEnd(*Call)) {
683+
auto *Invoke = cast<InvokeInst>(Call);
684+
ScopeEndBlocks.insert(Invoke->getNormalDest());
685+
}
686+
687+
if (!isStateStoreNeeded(Personality, *Call))
671688
continue;
672689

673690
int State = getStateForCall(BlockColors, FuncInfo, *Call);
@@ -720,6 +737,12 @@ void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
720737
FinalStates.insert({BB, SuccState});
721738
}
722739

740+
// Insert state restores after SEH scope ends
741+
for (BasicBlock *BB : ScopeEndBlocks) {
742+
int state = getBaseStateForBB(BlockColors, FuncInfo, BB);
743+
insertStateNumberStore(BB->getFirstNonPHI(), state);
744+
}
745+
723746
// Finally, insert state stores before call-sites which transition us to a new
724747
// state.
725748
for (BasicBlock *BB : RPOT) {

0 commit comments

Comments
 (0)