[llvm] r235768 - [SEH] Implement GetExceptionCode in __except blocks
Aditya Nandakumar
aditya_nandakumar at apple.com
Fri Apr 24 16:53:19 PDT 2015
Hi Reid,
You have an unused variable Context in processSEHCatchHandler and this is breaking our Werror builders.
Could you please fix that.
Thanks
Aditya
> On Apr 24, 2015, at 1:25 PM, Reid Kleckner <reid at kleckner.net> wrote:
>
> Author: rnk
> Date: Fri Apr 24 15:25:05 2015
> New Revision: 235768
>
> URL: http://llvm.org/viewvc/llvm-project?rev=235768&view=rev
> Log:
> [SEH] Implement GetExceptionCode in __except blocks
>
> This introduces an intrinsic called llvm.eh.exceptioncode. It is lowered
> by copying the EAX value live into whatever basic block it is called
> from. Obviously, this only works if you insert it late during codegen,
> because otherwise mid-level passes might reschedule it.
>
> Modified:
> llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h
> llvm/trunk/include/llvm/IR/Intrinsics.td
> llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
> llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll
> llvm/trunk/test/CodeGen/X86/seh-catch-all.ll
>
> Modified: llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h?rev=235768&r1=235767&r2=235768&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h Fri Apr 24 15:25:05 2015
> @@ -221,7 +221,7 @@ public:
> int getArgumentFrameIndex(const Argument *A);
>
> private:
> - void addSEHHandlersForLPads();
> + void addSEHHandlersForLPads(ArrayRef<const LandingPadInst *> LPads);
>
> /// LiveOutRegInfo - Information about live out vregs.
> IndexedMap<LiveOutInfo, VirtReg2IndexFunctor> LiveOutRegInfo;
>
> Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=235768&r1=235767&r2=235768&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
> +++ llvm/trunk/include/llvm/IR/Intrinsics.td Fri Apr 24 15:25:05 2015
> @@ -421,6 +421,8 @@ def int_eh_endcatch : Intrinsic<[], []>;
> // Represents the list of actions to take when an exception is thrown.
> def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;
>
> +def int_eh_exceptioncode : Intrinsic<[llvm_i32_ty], []>;
> +
> // __builtin_unwind_init is an undocumented GCC intrinsic that causes all
> // callee-saved registers to be saved and restored (regardless of whether they
> // are used) in the calling function. It is used by libgcc_eh.
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=235768&r1=235767&r2=235768&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Fri Apr 24 15:25:05 2015
> @@ -271,40 +271,49 @@ void FunctionLoweringInfo::set(const Fun
> }
>
> // Mark landing pad blocks.
> - const LandingPadInst *LP = nullptr;
> + SmallVector<const LandingPadInst *, 4> LPads;
> for (BB = Fn->begin(); BB != EB; ++BB) {
> if (const auto *Invoke = dyn_cast<InvokeInst>(BB->getTerminator()))
> MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
> if (BB->isLandingPad())
> - LP = BB->getLandingPadInst();
> + LPads.push_back(BB->getLandingPadInst());
> }
>
> - // Calculate EH numbers for MSVC C++ EH and save SEH handlers if necessary.
> + // If this is an MSVC EH personality, we need to do a bit more work.
> EHPersonality Personality = EHPersonality::Unknown;
> - if (LP)
> - Personality = classifyEHPersonality(LP->getPersonalityFn());
> + if (!LPads.empty())
> + Personality = classifyEHPersonality(LPads.back()->getPersonalityFn());
> + if (!isMSVCEHPersonality(Personality))
> + return;
> +
> + WinEHFuncInfo *EHInfo = nullptr;
> if (Personality == EHPersonality::MSVC_Win64SEH) {
> - addSEHHandlersForLPads();
> + addSEHHandlersForLPads(LPads);
> } else if (Personality == EHPersonality::MSVC_CXX) {
> const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
> - WinEHFuncInfo &FI = MMI.getWinEHFuncInfo(WinEHParentFn);
> - if (FI.LandingPadStateMap.empty()) {
> - WinEHNumbering Num(FI);
> + EHInfo = &MMI.getWinEHFuncInfo(WinEHParentFn);
> + if (EHInfo->LandingPadStateMap.empty()) {
> + WinEHNumbering Num(*EHInfo);
> Num.calculateStateNumbers(*WinEHParentFn);
> // Pop everything on the handler stack.
> Num.processCallSite(None, ImmutableCallSite());
> }
> +
> + // Copy the state numbers to LandingPadInfo for the current function, which
> + // could be a handler or the parent.
> + for (const LandingPadInst *LP : LPads) {
> + MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
> + MMI.addWinEHState(LPadMBB, EHInfo->LandingPadStateMap[LP]);
> + }
> }
> }
>
> -void FunctionLoweringInfo::addSEHHandlersForLPads() {
> +void FunctionLoweringInfo::addSEHHandlersForLPads(
> + ArrayRef<const LandingPadInst *> LPads) {
> MachineModuleInfo &MMI = MF->getMMI();
>
> // Iterate over all landing pads with llvm.eh.actions calls.
> - for (const BasicBlock &BB : *Fn) {
> - const LandingPadInst *LP = BB.getLandingPadInst();
> - if (!LP)
> - continue;
> + for (const LandingPadInst *LP : LPads) {
> const IntrinsicInst *ActionsCall =
> dyn_cast<IntrinsicInst>(LP->getNextNode());
> if (!ActionsCall ||
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=235768&r1=235767&r2=235768&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Apr 24 15:25:05 2015
> @@ -4817,6 +4817,18 @@ SelectionDAGBuilder::visitIntrinsicCall(
> case Intrinsic::eh_begincatch:
> case Intrinsic::eh_endcatch:
> llvm_unreachable("begin/end catch intrinsics not lowered in codegen");
> + case Intrinsic::eh_exceptioncode: {
> + unsigned Reg = TLI.getExceptionPointerRegister();
> + assert(Reg && "cannot get exception code on this platform");
> + MVT PtrVT = TLI.getPointerTy();
> + const TargetRegisterClass *PtrRC = TLI.getRegClassFor(PtrVT);
> + unsigned VReg = FuncInfo.MBB->addLiveIn(Reg, PtrRC);
> + SDValue N =
> + DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), VReg, PtrVT);
> + N = DAG.getZExtOrTrunc(N, getCurSDLoc(), MVT::i32);
> + setValue(&I, N);
> + return nullptr;
> + }
> }
> }
>
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=235768&r1=235767&r2=235768&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Apr 24 15:25:05 2015
> @@ -961,12 +961,6 @@ bool SelectionDAGISel::PrepareEHLandingP
> for (MachineBasicBlock *InvokeBB : InvokeBBs)
> InvokeBB->removeSuccessor(MBB);
>
> - // Transfer EH state number assigned to the IR block to the MBB.
> - if (Personality == EHPersonality::MSVC_CXX) {
> - WinEHFuncInfo &FI = MF->getMMI().getWinEHFuncInfo(MF->getFunction());
> - MF->getMMI().addWinEHState(MBB, FI.LandingPadStateMap[LPadInst]);
> - }
> -
> // Don't select instructions for the landingpad.
> return false;
> }
>
> Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=235768&r1=235767&r2=235768&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
> +++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Fri Apr 24 15:25:05 2015
> @@ -71,7 +71,7 @@ class WinEHPrepare : public FunctionPass
> public:
> static char ID; // Pass identification, replacement for typeid.
> WinEHPrepare(const TargetMachine *TM = nullptr)
> - : FunctionPass(ID), DT(nullptr) {}
> + : FunctionPass(ID), DT(nullptr), SEHExceptionCodeSlot(nullptr) {}
>
> bool runOnFunction(Function &Fn) override;
>
> @@ -133,6 +133,8 @@ private:
> // outlined into a handler. This is done after all handlers have been
> // outlined but before the outlined code is pruned from the parent function.
> DenseMap<const BasicBlock *, BasicBlock *> LPadTargetBlocks;
> +
> + AllocaInst *SEHExceptionCodeSlot;
> };
>
> class WinEHFrameVariableMaterializer : public ValueMaterializer {
> @@ -628,6 +630,13 @@ bool WinEHPrepare::prepareExceptionHandl
> Type *Int32Type = Type::getInt32Ty(Context);
> Function *ActionIntrin = Intrinsic::getDeclaration(M, Intrinsic::eh_actions);
>
> + if (isAsynchronousEHPersonality(Personality)) {
> + // FIXME: Switch the ehptr type to i32 and then switch this.
> + SEHExceptionCodeSlot =
> + new AllocaInst(Int8PtrType, nullptr, "seh_exception_code",
> + F.getEntryBlock().getFirstInsertionPt());
> + }
> +
> for (LandingPadInst *LPad : LPads) {
> // Look for evidence that this landingpad has already been processed.
> bool LPadHasActionList = false;
> @@ -680,23 +689,48 @@ bool WinEHPrepare::prepareExceptionHandl
>
> // Replace all extracted values with undef and ultimately replace the
> // landingpad with undef.
> - // FIXME: This doesn't handle SEH GetExceptionCode(). For now, we just give
> - // out undef until we figure out the codegen support.
> - SmallVector<Instruction *, 4> Extracts;
> + SmallVector<Instruction *, 4> SEHCodeUses;
> + SmallVector<Instruction *, 4> EHUndefs;
> for (User *U : LPad->users()) {
> auto *E = dyn_cast<ExtractValueInst>(U);
> if (!E)
> continue;
> assert(E->getNumIndices() == 1 &&
> "Unexpected operation: extracting both landing pad values");
> - Extracts.push_back(E);
> + unsigned Idx = *E->idx_begin();
> + assert((Idx == 0 || Idx == 1) && "unexpected index");
> + if (Idx == 0 && isAsynchronousEHPersonality(Personality))
> + SEHCodeUses.push_back(E);
> + else
> + EHUndefs.push_back(E);
> }
> - for (Instruction *E : Extracts) {
> + for (Instruction *E : EHUndefs) {
> E->replaceAllUsesWith(UndefValue::get(E->getType()));
> E->eraseFromParent();
> }
> LPad->replaceAllUsesWith(UndefValue::get(LPad->getType()));
>
> + // Rewrite uses of the exception pointer to loads of an alloca.
> + for (Instruction *E : SEHCodeUses) {
> + SmallVector<Use *, 4> Uses;
> + for (Use &U : E->uses())
> + Uses.push_back(&U);
> + for (Use *U : Uses) {
> + auto *I = cast<Instruction>(U->getUser());
> + if (isa<ResumeInst>(I))
> + continue;
> + LoadInst *LI;
> + if (auto *Phi = dyn_cast<PHINode>(I))
> + LI = new LoadInst(SEHExceptionCodeSlot, "sehcode", false,
> + Phi->getIncomingBlock(*U));
> + else
> + LI = new LoadInst(SEHExceptionCodeSlot, "sehcode", false, I);
> + U->set(LI);
> + }
> + E->replaceAllUsesWith(UndefValue::get(E->getType()));
> + E->eraseFromParent();
> + }
> +
> // Add a call to describe the actions for this landing pad.
> std::vector<Value *> ActionArgs;
> for (ActionHandler *Action : Actions) {
> @@ -820,6 +854,13 @@ bool WinEHPrepare::prepareExceptionHandl
> Builder.SetInsertPoint(&F.getEntryBlock().back());
> Builder.CreateCall(FrameEscapeFn, AllocasToEscape);
>
> + if (SEHExceptionCodeSlot) {
> + if (SEHExceptionCodeSlot->hasNUses(0))
> + SEHExceptionCodeSlot->eraseFromParent();
> + else
> + PromoteMemToReg(SEHExceptionCodeSlot, *DT);
> + }
> +
> // Clean up the handler action maps we created for this function
> DeleteContainerSeconds(CatchHandlerMap);
> CatchHandlerMap.clear();
> @@ -1193,6 +1234,7 @@ bool WinEHPrepare::outlineHandler(Action
> /// target.
> void WinEHPrepare::processSEHCatchHandler(CatchHandler *CatchAction,
> BasicBlock *StartBB) {
> + LLVMContext &Context = StartBB->getContext();
> BasicBlock *HandlerBB;
> BasicBlock *NextBB;
> Constant *Selector;
> @@ -1210,6 +1252,12 @@ void WinEHPrepare::processSEHCatchHandle
> HandlerBB =
> StartBB->splitBasicBlock(StartBB->getFirstInsertionPt(), "catch.all");
> }
> + IRBuilder<> Builder(HandlerBB->getFirstInsertionPt());
> + Function *EHCodeFn = Intrinsic::getDeclaration(
> + StartBB->getParent()->getParent(), Intrinsic::eh_exceptioncode);
> + Value *Code = Builder.CreateCall(EHCodeFn, "sehcode");
> + Code = Builder.CreateIntToPtr(Code, SEHExceptionCodeSlot->getAllocatedType());
> + Builder.CreateStore(Code, SEHExceptionCodeSlot);
> CatchAction->setHandlerBlockOrFunc(BlockAddress::get(HandlerBB));
> TinyPtrVector<BasicBlock *> Targets(HandlerBB);
> CatchAction->setReturnTargets(Targets);
>
> Modified: llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll?rev=235768&r1=235767&r2=235768&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll (original)
> +++ llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll Fri Apr 24 15:25:05 2015
> @@ -55,9 +55,8 @@ eh.resume:
> ; CHECK-NEXT: indirectbr {{.*}} [label %__except]
> ;
> ; CHECK: __except:
> -; FIXME: This should not be undef, it should be the new landingpad value, which
> -; should ultimately lower down to eax.
> -; CHECK: invoke void @might_crash(i8* undef)
> +; CHECK: call i32 @llvm.eh.exceptioncode()
> +; CHECK: invoke void @might_crash(i8* %{{.*}})
> ; CHECK: landingpad { i8*, i32 }
> ; CHECK-NEXT: cleanup
> ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 0, void (i8*, i8*)* @resume_phi.cleanup)
>
> Modified: llvm/trunk/test/CodeGen/X86/seh-catch-all.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-catch-all.ll?rev=235768&r1=235767&r2=235768&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/seh-catch-all.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/seh-catch-all.ll Fri Apr 24 15:25:05 2015
> @@ -1,10 +1,10 @@
> ; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
>
> - at str = internal unnamed_addr constant [10 x i8] c"recovered\00", align 1
> + at str = linkonce_odr unnamed_addr constant [27 x i8] c"GetExceptionCode(): 0x%lx\0A\00", align 1
>
> declare i32 @__C_specific_handler(...)
> declare void @crash()
> -declare i32 @puts(i8*)
> +declare i32 @printf(i8* nocapture readonly, ...) nounwind
>
> define i32 @main() {
> entry:
> @@ -14,7 +14,10 @@ entry:
> lpad:
> %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
> catch i8* null
> - call i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str, i64 0, i64 0))
> + %1 = extractvalue { i8*, i32 } %0, 0
> + %2 = ptrtoint i8* %1 to i64
> + %3 = trunc i64 %2 to i32
> + call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i64 0, i64 0), i32 %3)
> br label %__try.cont
>
> __try.cont:
> @@ -24,7 +27,15 @@ eh.resume:
> resume { i8*, i32 } %0
> }
>
> +; Check that we can get the exception code from eax to the printf.
> +
> ; CHECK-LABEL: main:
> +; CHECK: retq
> +; CHECK: # Block address taken
> +; CHECK: leaq str(%rip), %rcx
> +; CHECK: movl %eax, %edx
> +; CHECK: callq printf
> +
> ; CHECK: .seh_handlerdata
> ; CHECK-NEXT: .long 1
> ; CHECK-NEXT: .Ltmp{{[0-9]+}}@IMGREL
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list