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

Reply via email to