diff options
| author | Joseph Tremoulet <jotrem@microsoft.com> | 2016-01-04 16:16:01 +0000 |
|---|---|---|
| committer | Joseph Tremoulet <jotrem@microsoft.com> | 2016-01-04 16:16:01 +0000 |
| commit | 52f729a613910f0b03420e1912d301c17e975a22 (patch) | |
| tree | 3c7b6af49f4605c02ced420e3495fb56f630297d /llvm/lib/CodeGen/AsmPrinter/WinException.cpp | |
| parent | 5e27146df780271143355b82ab05fb8baac88b95 (diff) | |
| download | bcm5719-llvm-52f729a613910f0b03420e1912d301c17e975a22.tar.gz bcm5719-llvm-52f729a613910f0b03420e1912d301c17e975a22.zip | |
[WinEH] Update CoreCLR EH state numbering
Summary:
Fix the CLR state numbering to generate correct tables, and update the lit
test to verify them.
The CLR numbering assigns one state number to each catchpad and
cleanuppad.
It also computes two tree-like relations over states:
1) Each state has a "HandlerParentState", which is the state of the next
outer handler enclosing this state's handler (same as nearest ancestor
per the ParentPad linkage on EH pads, but skipping over catchswitches).
2) Each state has a "TryParentState", which:
a) for a catchpad that's not the last handler on its catchswitch, is
the state of the next catchpad on that catchswitch.
b) for all other pads, is the state of the pad whose try region is the
next outer try region enclosing this state's try region. The "try
regions are not present as such in the IR, but will be inferred
based on the placement of invokes and pads which reach each other
by exceptional exits.
Catchswitches do not get their own states, but each gets mapped to the
state of its first catchpad.
Table generation requires each state's "unwind dest" state to have a lower
state number than the given state.
Since HandlerParentState can be computed as a function of a pad's
ParentPad, and TryParentState can be computed as a function of its unwind
dest and the TryParentStates of its children, the CLR state numbering
algorithm first computes HandlerParentState in a top-down pass, then
computes TryParentState in a bottom-up pass.
Also reword some comments/names in the CLR EH table generation to make the
distinction between the different kinds of "parent" clear.
Reviewers: rnk, andrew.w.kaylor, majnemer
Subscribers: AndyAyers, llvm-commits
Differential Revision: http://reviews.llvm.org/D15325
llvm-svn: 256760
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/WinException.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 48b7104f24c..4da5b580fcd 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -976,32 +976,32 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) { } } -static int getRank(const WinEHFuncInfo &FuncInfo, int State) { +static int getTryRank(const WinEHFuncInfo &FuncInfo, int State) { int Rank = 0; while (State != -1) { ++Rank; - State = FuncInfo.ClrEHUnwindMap[State].Parent; + State = FuncInfo.ClrEHUnwindMap[State].TryParentState; } return Rank; } -static int getAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right) { - int LeftRank = getRank(FuncInfo, Left); - int RightRank = getRank(FuncInfo, Right); +static int getTryAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right) { + int LeftRank = getTryRank(FuncInfo, Left); + int RightRank = getTryRank(FuncInfo, Right); while (LeftRank < RightRank) { - Right = FuncInfo.ClrEHUnwindMap[Right].Parent; + Right = FuncInfo.ClrEHUnwindMap[Right].TryParentState; --RightRank; } while (RightRank < LeftRank) { - Left = FuncInfo.ClrEHUnwindMap[Left].Parent; + Left = FuncInfo.ClrEHUnwindMap[Left].TryParentState; --LeftRank; } while (Left != Right) { - Left = FuncInfo.ClrEHUnwindMap[Left].Parent; - Right = FuncInfo.ClrEHUnwindMap[Right].Parent; + Left = FuncInfo.ClrEHUnwindMap[Left].TryParentState; + Right = FuncInfo.ClrEHUnwindMap[Right].TryParentState; } return Left; @@ -1035,9 +1035,9 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) { FuncInfo.ClrEHUnwindMap[State].Handler.get<MachineBasicBlock *>(); HandlerStates[HandlerBlock] = State; // Use this loop through all handlers to verify our assumption (used in - // the MinEnclosingState computation) that ancestors have lower state - // numbers than their descendants. - assert(FuncInfo.ClrEHUnwindMap[State].Parent < State && + // the MinEnclosingState computation) that enclosing funclets have lower + // state numbers than their enclosed funclets. + assert(FuncInfo.ClrEHUnwindMap[State].HandlerParentState < State && "ill-formed state numbering"); } // Map the main function to the NullState. @@ -1070,7 +1070,6 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) { SmallVector<int, 4> MinClauseMap((size_t)NumStates, NumStates); // Visit the root function and each funclet. - for (MachineFunction::const_iterator FuncletStart = MF->begin(), FuncletEnd = MF->begin(), End = MF->end(); @@ -1100,17 +1099,18 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) { for (const auto &StateChange : InvokeStateChangeIterator::range(FuncInfo, FuncletStart, FuncletEnd)) { // Close any try regions we're not still under - int AncestorState = - getAncestor(FuncInfo, CurrentState, StateChange.NewState); - while (CurrentState != AncestorState) { - assert(CurrentState != NullState && "Failed to find ancestor!"); + int StillPendingState = + getTryAncestor(FuncInfo, CurrentState, StateChange.NewState); + while (CurrentState != StillPendingState) { + assert(CurrentState != NullState && + "Failed to find still-pending state!"); // Close the pending clause Clauses.push_back({CurrentStartLabel, StateChange.PreviousEndLabel, CurrentState, FuncletState}); - // Now the parent handler is current - CurrentState = FuncInfo.ClrEHUnwindMap[CurrentState].Parent; + // Now the next-outer try region is current + CurrentState = FuncInfo.ClrEHUnwindMap[CurrentState].TryParentState; // Pop the new start label from the handler stack if we've exited all - // descendants of the corresponding handler. + // inner try regions of the corresponding try region. if (HandlerStack.back().second == CurrentState) CurrentStartLabel = HandlerStack.pop_back_val().first; } @@ -1121,7 +1121,8 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) { // it. for (int EnteredState = StateChange.NewState; EnteredState != CurrentState; - EnteredState = FuncInfo.ClrEHUnwindMap[EnteredState].Parent) { + EnteredState = + FuncInfo.ClrEHUnwindMap[EnteredState].TryParentState) { int &MinEnclosingState = MinClauseMap[EnteredState]; if (FuncletState < MinEnclosingState) MinEnclosingState = FuncletState; |

