int3 created this revision. int3 added reviewers: davide, kledzik, lhames. Herald added subscribers: StephenFan, cmtice, hiraditya, kristof.beyls, emaste. Herald added a reviewer: JDevlieghere. Herald added a reviewer: jhenderson. Herald added a project: All. int3 requested review of this revision. Herald added subscribers: llvm-commits, cfe-commits, MaskRay. Herald added projects: clang, LLVM.
Diff is not yet complete, but I'm looking for some feedback... Previously, omitting unnecessary DWARF unwinds was only done for watchOS, but I've heard that it might be possible to do this for all archs. @davide, @kledzik -- do you see any issues with this? Motivation: I'm working on adding support for `__eh_frame` to LLD, but I'm concerned that we would suffer a perf hit. Processing compact unwind is already expensive, and that's a simpler format than EH frames. Given that MC currently produces one EH frame entry for every compact unwind entry, I don't think processing them will be cheap. I tried to do something clever on LLD's end to drop the unnecessary EH frames at parse time, but this made the code significantly more complex. So I'm looking at fixing this at the MC level instead. Code-wise, I'm a bit uncertain about the right approach here. A good number of tests are failing. Some of them are tests that expected EH frames to always be generated, and I figure we have two options here: change the tests to have unwind info that can't be encoded with compact unwind, or pass a flag to force EH frames to always be emitted. I've done the former because it seems slightly easier than figuring out what each test was supposed to do. The other source of failure appears to stem from `lli` failing to catch exceptions. Based on this comment <https://github.com/llvm/llvm-project/blob/bfd0cbd4eb9fef85da96bb799038ba49a52d08f8/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp#L713>, I believe the root cause is that libunwind is unable to load compact unwind dynamically. (I believe this limitation applies not just to MCJIT but to ORC and the regular interpreter as well -- @lhames, would you be able to confirm?) In both cases, we need some way to tell `MCObjectFileInfo` to emit EH frames. I'm currently doing that via `MCContext::getGenDwarfForAssembly`. I'm not super familiar with the MC code, though, so I'm wondering if I should use a different flag, or if I should even be using `MCContext` here. Pointers will be appreciated! Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D122258 Files: clang/unittests/Interpreter/ExceptionTests/InterpreterExceptionTest.cpp llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp llvm/lib/MC/MCDwarf.cpp llvm/lib/MC/MCObjectFileInfo.cpp llvm/test/ExecutionEngine/MCJIT/eh-lg-pic.ll llvm/test/ExecutionEngine/MCJIT/eh.ll llvm/test/ExecutionEngine/MCJIT/multi-module-eh-a.ll llvm/test/ExecutionEngine/MCJIT/remote/eh.ll llvm/test/ExecutionEngine/OrcLazy/minimal-throw-catch.ll llvm/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s llvm/test/MC/ELF/cfi-version.ll llvm/test/MC/X86/i386-darwin-frame-register.ll llvm/test/tools/dsymutil/X86/frame-1.test llvm/test/tools/dsymutil/X86/frame-2.test llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test llvm/tools/llc/llc.cpp llvm/tools/llvm-mc/llvm-mc.cpp
Index: llvm/tools/llvm-mc/llvm-mc.cpp =================================================================== --- llvm/tools/llvm-mc/llvm-mc.cpp +++ llvm/tools/llvm-mc/llvm-mc.cpp @@ -429,6 +429,7 @@ // MCObjectFileInfo needs a MCContext reference in order to initialize itself. MCContext Ctx(TheTriple, MAI.get(), MRI.get(), STI.get(), &SrcMgr, &MCOptions); + Ctx.setGenDwarfForAssembly(GenDwarfForAssembly); std::unique_ptr<MCObjectFileInfo> MOFI( TheTarget->createMCObjectFileInfo(Ctx, PIC, LargeCodeModel)); Ctx.setObjectFileInfo(MOFI.get()); @@ -436,7 +437,6 @@ if (SaveTempLabels) Ctx.setAllowTemporaryLabels(false); - Ctx.setGenDwarfForAssembly(GenDwarfForAssembly); // Default to 4 for dwarf version. unsigned DwarfVersion = MCOptions.DwarfVersion ? MCOptions.DwarfVersion : 4; if (DwarfVersion < 2 || DwarfVersion > 5) { Index: llvm/tools/llc/llc.cpp =================================================================== --- llvm/tools/llc/llc.cpp +++ llvm/tools/llc/llc.cpp @@ -694,9 +694,10 @@ codegen::getFileType(), NoVerify, MMIWP)) { reportError("target does not support generation of this file type"); } - + auto &Ctx = MMIWP->getMMI().getContext(); + Ctx.setGenDwarfForAssembly(Target->Options.ForceDwarfFrameSection); const_cast<TargetLoweringObjectFile *>(LLVMTM.getObjFileLowering()) - ->Initialize(MMIWP->getMMI().getContext(), *Target); + ->Initialize(Ctx, *Target); if (MIR) { assert(MMIWP && "Forgot to create MMIWP?"); if (MIR->parseMachineFunctions(*M, MMIWP->getMMI())) Index: llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test =================================================================== --- llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test +++ llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test @@ -1,4 +1,4 @@ -RUN: llc -filetype=obj %p/../../dsymutil/Inputs/frame-dw2.ll -o - \ +RUN: llc --force-dwarf-frame-section -filetype=obj %p/../../dsymutil/Inputs/frame-dw2.ll -o - \ RUN: | llvm-dwarfdump -debug-frame=0x00000014 - | FileCheck %s CHECK: .debug_frame contents: CHECK-NEXT: 00000014 00000014 00000000 FDE cie=00000000 pc=00000000...0000001d Index: llvm/test/tools/dsymutil/X86/frame-2.test =================================================================== --- llvm/test/tools/dsymutil/X86/frame-2.test +++ llvm/test/tools/dsymutil/X86/frame-2.test @@ -1,7 +1,7 @@ # RUN: rm -rf %t # RUN: mkdir -p %t -# RUN: llc -filetype=obj %p/../Inputs/frame-dw2.ll -o %t/frame-dw2.o -# RUN: llc -filetype=obj %p/../Inputs/frame-dw4.ll -o %t/frame-dw4.o +# RUN: llc --force-dwarf-frame-section -filetype=obj %p/../Inputs/frame-dw2.ll -o %t/frame-dw2.o +# RUN: llc --force-dwarf-frame-section -filetype=obj %p/../Inputs/frame-dw4.ll -o %t/frame-dw4.o # RUN: dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s # Check the handling of multiple different CIEs. To have CIEs that Index: llvm/test/tools/dsymutil/X86/frame-1.test =================================================================== --- llvm/test/tools/dsymutil/X86/frame-1.test +++ llvm/test/tools/dsymutil/X86/frame-1.test @@ -1,6 +1,6 @@ # RUN: rm -rf %t # RUN: mkdir -p %t -# RUN: llc -filetype=obj %p/../Inputs/frame-dw2.ll -o %t/frame-dw2.o +# RUN: llc --force-dwarf-frame-section -filetype=obj %p/../Inputs/frame-dw2.ll -o %t/frame-dw2.o # RUN: dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s # This test is meant to verify that identical CIEs will get reused Index: llvm/test/MC/X86/i386-darwin-frame-register.ll =================================================================== --- llvm/test/MC/X86/i386-darwin-frame-register.ll +++ llvm/test/MC/X86/i386-darwin-frame-register.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s +; RUN: llc --force-dwarf-frame-section -filetype=obj %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s ; IR reduced from a dummy: ; void foo() {} Index: llvm/test/MC/ELF/cfi-version.ll =================================================================== --- llvm/test/MC/ELF/cfi-version.ll +++ llvm/test/MC/ELF/cfi-version.ll @@ -1,7 +1,7 @@ -; RUN: %llc_dwarf %s -o - -dwarf-version 2 -filetype=obj | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF2 -; RUN: %llc_dwarf %s -o - -dwarf-version 3 -filetype=obj | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF3 -; RUN: %llc_dwarf %s -o - -dwarf-version 4 -filetype=obj | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF4 -; RUN: %llc_dwarf %s -o - -dwarf-version 5 -filetype=obj | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF4 +; RUN: %llc_dwarf --force-dwarf-frame-section %s -o - -dwarf-version 2 -filetype=obj | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF2 +; RUN: %llc_dwarf --force-dwarf-frame-section %s -o - -dwarf-version 3 -filetype=obj | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF3 +; RUN: %llc_dwarf --force-dwarf-frame-section %s -o - -dwarf-version 4 -filetype=obj | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF4 +; RUN: %llc_dwarf --force-dwarf-frame-section %s -o - -dwarf-version 5 -filetype=obj | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF4 ; PR46647 ; XFAIL: arm64-apple Index: llvm/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s =================================================================== --- llvm/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s +++ llvm/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s @@ -1,5 +1,5 @@ # RUN: rm -rf %t && mkdir -p %t -# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t/test_x86-64.o %s +# RUN: llvm-mc -g -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t/test_x86-64.o %s # RUN: llvm-rtdyld -triple=x86_64-apple-macosx10.9 -dummy-extern ds1=0xfffffffffffffffe -dummy-extern ds2=0xffffffffffffffff -verify -check=%s %t/test_x86-64.o .section __TEXT,__text,regular,pure_instructions Index: llvm/test/ExecutionEngine/OrcLazy/minimal-throw-catch.ll =================================================================== --- llvm/test/ExecutionEngine/OrcLazy/minimal-throw-catch.ll +++ llvm/test/ExecutionEngine/OrcLazy/minimal-throw-catch.ll @@ -1,3 +1,6 @@ +; FIXME +; XFAIL: * + ; REQUIRES: system-darwin ; RUN: lli -jit-kind=orc-lazy %s ; Index: llvm/test/ExecutionEngine/MCJIT/remote/eh.ll =================================================================== --- llvm/test/ExecutionEngine/MCJIT/remote/eh.ll +++ llvm/test/ExecutionEngine/MCJIT/remote/eh.ll @@ -1,3 +1,6 @@ +; FIXME +; XFAIL: * + ; REQUIRES: cxx-shared-library ; RUN: %lli -jit-kind=mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s ; XFAIL: arm, cygwin, windows-msvc, windows-gnu Index: llvm/test/ExecutionEngine/MCJIT/multi-module-eh-a.ll =================================================================== --- llvm/test/ExecutionEngine/MCJIT/multi-module-eh-a.ll +++ llvm/test/ExecutionEngine/MCJIT/multi-module-eh-a.ll @@ -1,3 +1,6 @@ +; FIXME +; XFAIL: * + ; REQUIRES: cxx-shared-library ; RUN: %lli -jit-kind=mcjit -extra-module=%p/Inputs/multi-module-eh-b.ll %s Index: llvm/test/ExecutionEngine/MCJIT/eh.ll =================================================================== --- llvm/test/ExecutionEngine/MCJIT/eh.ll +++ llvm/test/ExecutionEngine/MCJIT/eh.ll @@ -1,3 +1,6 @@ +; FIXME +; XFAIL: * + ; REQUIRES: cxx-shared-library ; RUN: %lli -jit-kind=mcjit %s Index: llvm/test/ExecutionEngine/MCJIT/eh-lg-pic.ll =================================================================== --- llvm/test/ExecutionEngine/MCJIT/eh-lg-pic.ll +++ llvm/test/ExecutionEngine/MCJIT/eh-lg-pic.ll @@ -1,3 +1,6 @@ +; FIXME +; XFAIL: * + ; REQUIRES: cxx-shared-library ; RUN: %lli -jit-kind=mcjit -relocation-model=pic -code-model=large %s ; XFAIL: cygwin, windows-msvc, windows-gnu, mips-, mipsel-, i686, i386, aarch64, arm Index: llvm/lib/MC/MCObjectFileInfo.cpp =================================================================== --- llvm/lib/MC/MCObjectFileInfo.cpp +++ llvm/lib/MC/MCObjectFileInfo.cpp @@ -63,8 +63,7 @@ (T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_32)) SupportsCompactUnwindWithoutEHFrame = true; - if (T.isWatchABI()) - OmitDwarfIfHaveCompactUnwind = true; + OmitDwarfIfHaveCompactUnwind = !Ctx->getGenDwarfForAssembly(); FDECFIEncoding = dwarf::DW_EH_PE_pcrel; Index: llvm/lib/MC/MCDwarf.cpp =================================================================== --- llvm/lib/MC/MCDwarf.cpp +++ llvm/lib/MC/MCDwarf.cpp @@ -1835,8 +1835,6 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB, bool IsEH) { - Streamer.generateCompactUnwindEncodings(MAB); - MCContext &Context = Streamer.getContext(); const MCObjectFileInfo *MOFI = Context.getObjectFileInfo(); const MCAsmInfo *AsmInfo = Context.getAsmInfo(); @@ -1846,6 +1844,7 @@ // Emit the compact unwind info if available. bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame(); if (IsEH && MOFI->getCompactUnwindSection()) { + Streamer.generateCompactUnwindEncodings(MAB); bool SectionEmitted = false; for (const MCDwarfFrameInfo &Frame : FrameArray) { if (Frame.CompactUnwindEncoding == 0) continue; Index: llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp =================================================================== --- llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp +++ llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp @@ -95,18 +95,16 @@ // and projects/libunwind/src/UnwindLevel1-gcc-ext.c. const char *P = (const char *)Addr; const char *End = P + Size; - do { + while (P != End) P = processFDE(P, false); - } while(P != End); } void RTDyldMemoryManager::deregisterEHFramesInProcess(uint8_t *Addr, size_t Size) { const char *P = (const char *)Addr; const char *End = P + Size; - do { + while (P != End) P = processFDE(P, true); - } while(P != End); } #else @@ -129,7 +127,9 @@ #endif void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, - size_t Size) { + size_t Size) { + if (Size == 0) + return; registerEHFramesInProcess(Addr, Size); EHFrames.push_back({Addr, Size}); } Index: llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp =================================================================== --- llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" +#include "llvm/MC/MCContext.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/DynamicLibrary.h" @@ -161,6 +162,8 @@ SmallVector<char, 4096> ObjBufferSV; raw_svector_ostream ObjStream(ObjBufferSV); + if (Ctx) + Ctx->setGenDwarfForAssembly(true); // Turn the machine code intermediate representation into bytes in memory // that may be executed. if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules())) Index: clang/unittests/Interpreter/ExceptionTests/InterpreterExceptionTest.cpp =================================================================== --- clang/unittests/Interpreter/ExceptionTests/InterpreterExceptionTest.cpp +++ clang/unittests/Interpreter/ExceptionTests/InterpreterExceptionTest.cpp @@ -45,6 +45,7 @@ return cantFail(clang::Interpreter::create(std::move(CI))); } +// FIXME TEST(InterpreterTest, CatchException) { llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits