diff options
author | Reid Kleckner <rnk@google.com> | 2015-09-08 23:28:38 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-09-08 23:28:38 +0000 |
commit | 51189f0a1d0b8b6d1490a4e42df4971916fb9235 (patch) | |
tree | 804c110f1c9172e760631974831c8fd1dd52a950 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | |
parent | a195adde001abe1b337a4455b8b8c80f340f8a2e (diff) | |
download | bcm5719-llvm-51189f0a1d0b8b6d1490a4e42df4971916fb9235.tar.gz bcm5719-llvm-51189f0a1d0b8b6d1490a4e42df4971916fb9235.zip |
[WinEH] Avoid creating MBBs for LLVM BBs that cannot contain code
Typically these are catchpads, which hold data used to decide whether to
catch the exception or continue unwinding. We also shouldn't create MBBs
for catchendpads, cleanupendpads, or terminatepads, since no real code
can live in them.
This fixes a problem where MI passes (like the register allocator) would
try to put code into catchpad blocks, which are not executed by the
runtime. In the new world, blocks ending in invokes now have many
possible successors.
llvm-svn: 247102
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 96 |
1 files changed, 52 insertions, 44 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 9aa9755796d..1df4245bf0b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1160,16 +1160,7 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) { } void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) { - // Update machine-CFG edges. - MachineBasicBlock *PadMBB = FuncInfo.MBB; - MachineBasicBlock *CatchingMBB = FuncInfo.MBBMap[I.getNormalDest()]; - MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()]; - PadMBB->addSuccessor(CatchingMBB); - PadMBB->addSuccessor(UnwindMBB); - - CatchingMBB->setIsEHFuncletEntry(); - MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI(); - MMI.setHasEHFunclets(true); + llvm_unreachable("should never codegen catchpads"); } void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) { @@ -1185,19 +1176,10 @@ void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) { } void SelectionDAGBuilder::visitCatchEndPad(const CatchEndPadInst &I) { - // If this unwinds to caller, we don't need a DAG node hanging around. - if (!I.hasUnwindDest()) - return; - - // Update machine-CFG edge. - MachineBasicBlock *PadMBB = FuncInfo.MBB; - MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()]; - PadMBB->addSuccessor(UnwindMBB); + llvm_unreachable("should never codegen catchendpads"); } void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) { - MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI(); - MMI.setHasEHFunclets(true); report_fatal_error("visitCleanupPad not yet implemented!"); } @@ -2003,9 +1985,11 @@ void SelectionDAGBuilder::visitBitTestCase(BitTestBlock &BB, void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { MachineBasicBlock *InvokeMBB = FuncInfo.MBB; - // Retrieve successors. + // Retrieve successors. Look through artificial IR level blocks like catchpads + // and catchendpads for successors. MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)]; - MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)]; + const BasicBlock *EHPadBB = I.getSuccessor(1); + bool IsLandingPad = EHPadBB->isLandingPad(); const Value *Callee(I.getCalledValue()); const Function *Fn = dyn_cast<Function>(Callee); @@ -2020,14 +2004,14 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { break; case Intrinsic::experimental_patchpoint_void: case Intrinsic::experimental_patchpoint_i64: - visitPatchpoint(&I, LandingPad); + visitPatchpoint(&I, EHPadBB); break; case Intrinsic::experimental_gc_statepoint: - LowerStatepoint(ImmutableStatepoint(&I), LandingPad); + LowerStatepoint(ImmutableStatepoint(&I), EHPadBB); break; } } else - LowerCallTo(&I, getValue(Callee), false, LandingPad); + LowerCallTo(&I, getValue(Callee), false, EHPadBB); // If the value of the invoke is used outside of its defining block, make it // available as a virtual register. @@ -2037,9 +2021,37 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { CopyToExportRegsIfNeeded(&I); } + // Stop when we hit a pad that generates real code or we unwind to caller. + // Catchpads are conditional branches that add real MBB destinations and + // continue the loop. EH "end" pads are not real BBs and simply continue. + SmallVector<MachineBasicBlock *, 1> UnwindDests; + while (EHPadBB) { + const Instruction *Pad = EHPadBB->getFirstNonPHI(); + if (isa<CleanupPadInst>(Pad) || isa<LandingPadInst>(Pad)) { + assert(FuncInfo.MBBMap[EHPadBB]); + // Stop on cleanup pads and landingpads. + UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); + break; + } else if (const auto *CPI = dyn_cast<CatchPadInst>(Pad)) { + // Add the catchpad handler to the possible destinations. + UnwindDests.push_back(FuncInfo.MBBMap[CPI->getNormalDest()]); + EHPadBB = CPI->getUnwindDest(); + } else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(Pad)) { + EHPadBB = CEPI->getUnwindDest(); + } else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(Pad)) { + EHPadBB = CEPI->getUnwindDest(); + } + } + // Update successor info + // FIXME: The weights for catchpads will be wrong. addSuccessorWithWeight(InvokeMBB, Return); - addSuccessorWithWeight(InvokeMBB, LandingPad); + for (auto *UnwindDest : UnwindDests) { + UnwindDest->setIsEHPad(); + if (!IsLandingPad) + UnwindDest->setIsEHFuncletEntry(); + addSuccessorWithWeight(InvokeMBB, UnwindDest); + } // Drop into normal successor. DAG.setRoot(DAG.getNode(ISD::BR, getCurSDLoc(), @@ -5145,11 +5157,11 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { std::pair<SDValue, SDValue> SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI, - MachineBasicBlock *LandingPad) { + const BasicBlock *EHPadBB) { MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI(); MCSymbol *BeginLabel = nullptr; - if (LandingPad) { + if (EHPadBB) { // Insert a label before the invoke call to mark the try range. This can be // used to detect deletion of the invoke via the MachineModuleInfo. BeginLabel = MMI.getContext().createTempSymbol(); @@ -5159,7 +5171,7 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI, unsigned CallSiteIndex = MMI.getCurrentCallSite(); if (CallSiteIndex) { MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex); - LPadToCallSiteMap[LandingPad].push_back(CallSiteIndex); + LPadToCallSiteMap[FuncInfo.MBBMap[EHPadBB]].push_back(CallSiteIndex); // Now that the call site is handled, stop tracking it. MMI.setCurrentCallSite(0); @@ -5192,14 +5204,14 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI, DAG.setRoot(Result.second); } - if (LandingPad) { + if (EHPadBB) { // Insert a label at the end of the invoke call to mark the try range. This // can be used to detect deletion of the invoke via the MachineModuleInfo. MCSymbol *EndLabel = MMI.getContext().createTempSymbol(); DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getRoot(), EndLabel)); // Inform MachineModuleInfo of range. - MMI.addInvoke(LandingPad, BeginLabel, EndLabel); + MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel); } return Result; @@ -5207,7 +5219,7 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI, void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, bool isTailCall, - MachineBasicBlock *LandingPad) { + const BasicBlock *EHPadBB) { PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType()); FunctionType *FTy = cast<FunctionType>(PT->getElementType()); Type *RetTy = FTy->getReturnType(); @@ -5246,7 +5258,7 @@ 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, LandingPad); + std::pair<SDValue, SDValue> Result = lowerInvokable(CLI, EHPadBB); if (Result.first.getNode()) setValue(CS.getInstruction(), Result.first); @@ -6552,12 +6564,9 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) { /// This is a helper for lowering intrinsics that follow a target calling /// convention or require stack pointer adjustment. Only a subset of the /// intrinsic's operands need to participate in the calling convention. -std::pair<SDValue, SDValue> -SelectionDAGBuilder::lowerCallOperands(ImmutableCallSite CS, unsigned ArgIdx, - unsigned NumArgs, SDValue Callee, - Type *ReturnTy, - MachineBasicBlock *LandingPad, - bool IsPatchPoint) { +std::pair<SDValue, SDValue> SelectionDAGBuilder::lowerCallOperands( + ImmutableCallSite CS, unsigned ArgIdx, unsigned NumArgs, SDValue Callee, + Type *ReturnTy, const BasicBlock *EHPadBB, bool IsPatchPoint) { TargetLowering::ArgListTy Args; Args.reserve(NumArgs); @@ -6581,7 +6590,7 @@ SelectionDAGBuilder::lowerCallOperands(ImmutableCallSite CS, unsigned ArgIdx, .setCallee(CS.getCallingConv(), ReturnTy, Callee, std::move(Args), NumArgs) .setDiscardResult(CS->use_empty()).setIsPatchPoint(IsPatchPoint); - return lowerInvokable(CLI, LandingPad); + return lowerInvokable(CLI, EHPadBB); } /// \brief Add a stack map intrinsic call's live variable operands to a stackmap @@ -6685,7 +6694,7 @@ void SelectionDAGBuilder::visitStackmap(const CallInst &CI) { /// \brief Lower llvm.experimental.patchpoint directly to its target opcode. void SelectionDAGBuilder::visitPatchpoint(ImmutableCallSite CS, - MachineBasicBlock *LandingPad) { + const BasicBlock *EHPadBB) { // void|i64 @llvm.experimental.patchpoint.void|i64(i64 <id>, // i32 <numBytes>, // i8* <target>, @@ -6722,9 +6731,8 @@ void SelectionDAGBuilder::visitPatchpoint(ImmutableCallSite CS, unsigned NumCallArgs = IsAnyRegCC ? 0 : NumArgs; Type *ReturnTy = IsAnyRegCC ? Type::getVoidTy(*DAG.getContext()) : CS->getType(); - std::pair<SDValue, SDValue> Result = - lowerCallOperands(CS, NumMetaOpers, NumCallArgs, Callee, ReturnTy, - LandingPad, true); + std::pair<SDValue, SDValue> Result = lowerCallOperands( + CS, NumMetaOpers, NumCallArgs, Callee, ReturnTy, EHPadBB, true); SDNode *CallEnd = Result.second.getNode(); if (HasDef && (CallEnd->getOpcode() == ISD::CopyFromReg)) |