diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h --- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h +++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h @@ -162,6 +162,9 @@ /// Indicate that this basic block is the entry block of a cleanup funclet. bool IsCleanupFuncletEntry = false; + /// Indicates that this block is an EHCont target. + bool IsEHContTarget = false; + /// With basic block sections, this stores the Section ID of the basic block. MBBSectionID SectionID{0}; @@ -178,6 +181,9 @@ /// is only computed once and is cached. mutable MCSymbol *CachedMCSymbol = nullptr; + /// Cached MCSymbol for this block (used if IsEHContTarget). + mutable MCSymbol *CachedEHContMCSymbol = nullptr; + /// Marks the end of the basic block. Used during basic block sections to /// calculate the size of the basic block, or the BB section ending with it. mutable MCSymbol *CachedEndMCSymbol = nullptr; @@ -466,6 +472,12 @@ /// Indicates if this is the entry block of a cleanup funclet. void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; } + /// Returns true if this block is an EHCont target. + bool isEHContTarget() const { return IsEHContTarget; } + + /// Indicates if this is an EHCont target. + void setIsEHContTarget(bool V = true) { IsEHContTarget = V; } + /// Returns true if this block begins any section. bool isBeginSection() const { return IsBeginSection; } @@ -919,6 +931,9 @@ /// Return the MCSymbol for this basic block. MCSymbol *getSymbol() const; + /// Return the EHCont Symbol for this basic block. + MCSymbol *getEHContSymbol() const; + Optional getIrrLoopHeaderWeight() const { return IrrLoopHeaderWeight; } diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -3201,6 +3201,10 @@ } } + if (MBB.isEHContTarget()) { + OutStreamer->emitLabel(MBB.getEHContSymbol()); + } + // With BB sections, each basic block must handle CFI information on its own // if it begins a section (Entry block is handled separately by // AsmPrinterHandler::beginFunction). diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -231,10 +231,6 @@ Asm->OutStreamer->EmitWinCFIStartProc(Sym); } - // Add 'Sym' as an ehcont target - if (CurrentFuncletEntry->isEHFuncletEntry()) - EHContTargets.push_back(Sym); - if (shouldEmitPersonality) { const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); const Function *PerFn = nullptr; diff --git a/llvm/lib/CodeGen/EHContGuardCatchret.cpp b/llvm/lib/CodeGen/EHContGuardCatchret.cpp --- a/llvm/lib/CodeGen/EHContGuardCatchret.cpp +++ b/llvm/lib/CodeGen/EHContGuardCatchret.cpp @@ -70,21 +70,16 @@ if (!MF.hasEHCatchRet()) return false; - bool result = false; + bool Result = false; for (MachineBasicBlock &MBB : MF) { if (MBB.isEHCatchRetTarget() && !MBB.isEHFuncletEntry()) { - auto MBBI = MBB.begin(); - SmallString<128> SymbolName; - raw_svector_ostream(SymbolName) - << "$ehgcr_" << MF.getName() << MBB.getNumber(); - MCSymbol *CrSymbol = MF.getContext().getOrCreateSymbol(SymbolName); - MBBI->setPreInstrSymbol(MF, CrSymbol); - MF.addCatchretTarget(CrSymbol); + MBB.setIsEHContTarget(); + MF.addCatchretTarget(MBB.getEHContSymbol()); EHContGuardCatchretTargets++; - result = true; + Result = true; } } - return result; + return Result; } diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -87,6 +87,17 @@ return CachedMCSymbol; } +MCSymbol *MachineBasicBlock::getEHContSymbol() const { + if (!CachedEHContMCSymbol) { + const MachineFunction *MF = getParent(); + SmallString<128> SymbolName; + raw_svector_ostream(SymbolName) + << "$ehgcr_" << MF->getFunctionNumber() << '_' << getNumber(); + CachedEHContMCSymbol = MF->getContext().getOrCreateSymbol(SymbolName); + } + return CachedEHContMCSymbol; +} + MCSymbol *MachineBasicBlock::getEndSymbol() const { if (!CachedEndMCSymbol) { const MachineFunction *MF = getParent(); diff --git a/llvm/test/CodeGen/AArch64/ehcontguard.ll b/llvm/test/CodeGen/AArch64/ehcontguard.ll --- a/llvm/test/CodeGen/AArch64/ehcontguard.ll +++ b/llvm/test/CodeGen/AArch64/ehcontguard.ll @@ -5,44 +5,25 @@ ; CHECK: .section .gehcont$y -; // struct with dtor -; struct A -; { -; ~A(); -; }; -; -; // function we call that might raise an exception -; void func2(); -; -; // function which has to call the dtor on unwind -; void func1() -; { -; A a; -; func2(); -; } - -%struct.A = type { [4 x i32], [16 x i8] } -declare dso_local %struct.A* @"??0A@@QEAA@XZ"(%struct.A* returned %0) -declare dso_local void @"??1A@@QEAA@XZ"(%struct.A* %0) -declare dso_local i32 @__CxxFrameHandler3(...) -declare dso_local void @"?func2@@YAXXZ"() - -; Function Attrs: noinline optnone uwtable define dso_local void @"?func1@@YAXXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { - %1 = alloca %struct.A - %2 = call %struct.A* @"??0A@@QEAA@XZ"(%struct.A* %1) #3 +entry: invoke void @"?func2@@YAXXZ"() - to label %3 unwind label %4 - -3: ; preds = %0 - call void @"??1A@@QEAA@XZ"(%struct.A* %1) #3 + to label %invoke.cont unwind label %catch.dispatch +catch.dispatch: ; preds = %entry + %0 = catchswitch within none [label %catch] unwind to caller +catch: ; preds = %catch.dispatch + %1 = catchpad within %0 [i8* null, i32 64, i8* null] + catchret from %1 to label %catchret.dest +catchret.dest: ; preds = %catch + br label %try.cont +try.cont: ; preds = %catchret.dest, %invoke.cont ret void - -4: ; preds = %0 - %5 = cleanuppad within none [] - call void @"??1A@@QEAA@XZ"(%struct.A* %1) #3 [ "funclet"(token %5) ] - cleanupret from %5 unwind to caller +invoke.cont: ; preds = %entry + br label %try.cont } +declare dso_local void @"?func2@@YAXXZ"() #1 +declare dso_local i32 @__CxxFrameHandler3(...) + !llvm.module.flags = !{!0} -!0 = !{i32 1, !"ehcontguard", i32 1} \ No newline at end of file +!0 = !{i32 1, !"ehcontguard", i32 1} diff --git a/llvm/test/CodeGen/X86/ehcontguard.ll b/llvm/test/CodeGen/X86/ehcontguard.ll --- a/llvm/test/CodeGen/X86/ehcontguard.ll +++ b/llvm/test/CodeGen/X86/ehcontguard.ll @@ -5,44 +5,25 @@ ; CHECK: .section .gehcont$y -; // struct with dtor -; struct A -; { -; ~A(); -; }; -; -; // function we call that might raise an exception -; void func2(); -; -; // function which has to call the dtor on unwind -; void func1() -; { -; A a; -; func2(); -; } - -%struct.A = type { [4 x i32], [16 x i8] } -declare dso_local %struct.A* @"??0A@@QEAA@XZ"(%struct.A* returned %0) -declare dso_local void @"??1A@@QEAA@XZ"(%struct.A* %0) -declare dso_local i32 @__CxxFrameHandler3(...) -declare dso_local void @"?func2@@YAXXZ"() - -; Function Attrs: noinline optnone uwtable define dso_local void @"?func1@@YAXXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { - %1 = alloca %struct.A - %2 = call %struct.A* @"??0A@@QEAA@XZ"(%struct.A* %1) #3 +entry: invoke void @"?func2@@YAXXZ"() - to label %3 unwind label %4 - -3: ; preds = %0 - call void @"??1A@@QEAA@XZ"(%struct.A* %1) #3 + to label %invoke.cont unwind label %catch.dispatch +catch.dispatch: ; preds = %entry + %0 = catchswitch within none [label %catch] unwind to caller +catch: ; preds = %catch.dispatch + %1 = catchpad within %0 [i8* null, i32 64, i8* null] + catchret from %1 to label %catchret.dest +catchret.dest: ; preds = %catch + br label %try.cont +try.cont: ; preds = %catchret.dest, %invoke.cont ret void - -4: ; preds = %0 - %5 = cleanuppad within none [] - call void @"??1A@@QEAA@XZ"(%struct.A* %1) #3 [ "funclet"(token %5) ] - cleanupret from %5 unwind to caller +invoke.cont: ; preds = %entry + br label %try.cont } +declare dso_local void @"?func2@@YAXXZ"() #1 +declare dso_local i32 @__CxxFrameHandler3(...) + !llvm.module.flags = !{!0} -!0 = !{i32 1, !"ehcontguard", i32 1} \ No newline at end of file +!0 = !{i32 1, !"ehcontguard", i32 1}