Skip to content

Commit

Permalink
Merge pull request #123 from JosephTremoulet/NewRep-LLILC
Browse files Browse the repository at this point in the history
[WinEH] Update CoreCLR EH state numbering
  • Loading branch information
JosephTremoulet committed Dec 30, 2015
2 parents 9aca91d + 5fe5c2b commit 141baab
Show file tree
Hide file tree
Showing 6 changed files with 749 additions and 190 deletions.
4 changes: 3 additions & 1 deletion include/llvm/CodeGen/WinEHFuncInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ enum class ClrHandlerType { Catch, Finally, Fault, Filter };
struct ClrEHUnwindMapEntry {
MBBOrBasicBlock Handler;
uint32_t TypeToken;
int Parent;
int HandlerParentState; ///< Outer handler enclosing this entry's handler
int TryParentState; ///< Outer try region enclosing this entry's try region,
///< treating later catches on same try as "outer"
ClrHandlerType HandlerType;
};

Expand Down
43 changes: 22 additions & 21 deletions lib/CodeGen/AsmPrinter/WinException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -893,32 +893,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;
Expand Down Expand Up @@ -952,9 +952,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.
Expand Down Expand Up @@ -987,7 +987,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();
Expand Down Expand Up @@ -1017,17 +1016,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;
}
Expand All @@ -1038,7 +1038,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;
Expand Down
20 changes: 14 additions & 6 deletions lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5276,7 +5276,10 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {

std::pair<SDValue, SDValue>
SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
const BasicBlock *EHPadBB) {
const BasicBlock *EHPadBB,
const InvokeInst *Invoke) {
// TODO: upstream change to add Invoke parameter when we can also upstream
// support for lowering funclet EH statepoints and so can upstream a lit test
MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
MCSymbol *BeginLabel = nullptr;

Expand Down Expand Up @@ -5331,10 +5334,9 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,

// Inform MachineModuleInfo of range.
if (MMI.hasEHFunclets()) {
assert(CLI.CS);
assert(Invoke);
WinEHFuncInfo *EHInfo = DAG.getMachineFunction().getWinEHFuncInfo();
EHInfo->addIPToStateRange(cast<InvokeInst>(CLI.CS->getInstruction()),
BeginLabel, EndLabel);
EHInfo->addIPToStateRange(Invoke, BeginLabel, EndLabel);
} else {
MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
}
Expand Down Expand Up @@ -5384,7 +5386,10 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
CLI.setDebugLoc(getCurSDLoc()).setChain(getRoot())
.setCallee(RetTy, FTy, Callee, std::move(Args), CS)
.setTailCall(isTailCall);
std::pair<SDValue, SDValue> Result = lowerInvokable(CLI, EHPadBB);
// TODO: upstream change to add Invoke argument when we can also upstream
// support for lowering funclet EH statepoints and so can upstream a lit test
std::pair<SDValue, SDValue> Result = lowerInvokable(
CLI, EHPadBB, dyn_cast_or_null<InvokeInst>(CS.getInstruction()));

if (Result.first.getNode())
setValue(CS.getInstruction(), Result.first);
Expand Down Expand Up @@ -6716,7 +6721,10 @@ std::pair<SDValue, SDValue> SelectionDAGBuilder::lowerCallOperands(
.setCallee(CS.getCallingConv(), ReturnTy, Callee, std::move(Args), NumArgs)
.setDiscardResult(CS->use_empty()).setIsPatchPoint(IsPatchPoint);

return lowerInvokable(CLI, EHPadBB);
// TODO: upstream change to add Invoke argument when we can also upstream
// support for lowering funclet EH statepoints and so can upstream a lit test
return lowerInvokable(CLI, EHPadBB,
dyn_cast_or_null<InvokeInst>(CS.getInstruction()));
}

/// \brief Add a stack map intrinsic call's live variable operands to a stackmap
Expand Down
5 changes: 4 additions & 1 deletion lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -725,10 +725,13 @@ class SelectionDAGBuilder {
// It uniformly handles invoke and call statepoints.
void LowerStatepoint(ImmutableStatepoint Statepoint,
const BasicBlock *EHPadBB = nullptr);

private:
// TODO: upstream change to add Invoke parameter when we can also upstream
// support for lowering funclet EH statepoints and so can upstream a lit test
std::pair<SDValue, SDValue>
lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
const BasicBlock *EHPadBB = nullptr);
const BasicBlock *EHPadBB, const InvokeInst *Invoke);

// Terminator instructions.
void visitRet(const ReturnInst &I);
Expand Down
Loading

0 comments on commit 141baab

Please sign in to comment.