Use .cfi_sections to put the unwind info in .debug_frame when possible. With
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 10 May 2011 18:39:09 +0000 (18:39 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 10 May 2011 18:39:09 +0000 (18:39 +0000)
this clang will use .debug_frame in, for example,
clang -g -c -m32 test.c
This matches gcc's behaviour. It looks like .debug_frame is a bit bigger
than .eh_frame, but has the big advantage of not being allocated.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131140 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
lib/CodeGen/AsmPrinter/DwarfException.h
test/DebugInfo/debug_frame.ll [new file with mode: 0644]

index 336166a3fc9d784aa10872f01ca96cde74787df9..33224121bf1db65e0fd62e46f85550558a0b8ebe 100644 (file)
@@ -185,7 +185,12 @@ namespace llvm {
 
     void emitPrologLabel(const MachineInstr &MI);
 
-    bool needsCFIMoves();
+    enum CFIMoveType {
+      CFI_M_None,
+      CFI_M_EH,
+      CFI_M_Debug
+    };
+    CFIMoveType needsCFIMoves();
 
     /// EmitConstantPool - Print to the current output stream assembly
     /// representations of the constants in the constant pool MCP. This is
index d88f05b7ccdc4a8d81832913c18b2665191d29c3..7f39cef3f9efe1d2faf05575a672a3ea8c79fb44 100644 (file)
@@ -592,17 +592,17 @@ static bool EmitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
   return true;
 }
 
-bool AsmPrinter::needsCFIMoves() {
+AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() {
   if (UnwindTablesMandatory)
-    return true;
+    return CFI_M_EH;
 
-  if (MMI->hasDebugInfo())
-    return true;
+  if (!MF->getFunction()->doesNotThrow())
+    return CFI_M_EH;
 
-  if (MF->getFunction()->doesNotThrow())
-    return false;
+  if (MMI->hasDebugInfo())
+    return CFI_M_Debug;
 
-  return true;
+  return CFI_M_None;
 }
 
 void AsmPrinter::emitPrologLabel(const MachineInstr &MI) {
@@ -611,7 +611,7 @@ void AsmPrinter::emitPrologLabel(const MachineInstr &MI) {
   if (MAI->getExceptionHandlingType() != ExceptionHandling::DwarfCFI)
     return;
 
-  if (!needsCFIMoves())
+  if (needsCFIMoves() == CFI_M_None)
     return;
 
   MachineModuleInfo &MMI = MF->getMMI();
index dbd52c4981b3f10f0f79bfa6b56c8847d8d114a4..e7a7593be3b3aa9f19506b52f6ceab098cc74084 100644 (file)
@@ -49,6 +49,9 @@ DwarfCFIException::~DwarfCFIException() {}
 /// EndModule - Emit all exception information that should come after the
 /// content.
 void DwarfCFIException::EndModule() {
+  if (moveTypeModule == AsmPrinter::CFI_M_Debug)
+    Asm->OutStreamer.EmitCFISections(false, true);
+
   if (!Asm->MAI->isExceptionHandlingDwarf())
     return;
 
@@ -87,7 +90,13 @@ void DwarfCFIException::BeginFunction(const MachineFunction *MF) {
   bool hasLandingPads = !MMI->getLandingPads().empty();
 
   // See if we need frame move info.
-  shouldEmitMoves = Asm->needsCFIMoves();
+  AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
+  if (MoveType == AsmPrinter::CFI_M_EH ||
+      (MoveType == AsmPrinter::CFI_M_Debug &&
+       moveTypeModule == AsmPrinter::CFI_M_None))
+    moveTypeModule = MoveType;
+
+  shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None;
 
   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
   unsigned PerEncoding = TLOF.getPersonalityEncoding();
index de5fc90cd3b52465666631a8c8716b649e617386..68079bb655a73df710604d3dbb69be574ff6a87f 100644 (file)
@@ -15,6 +15,7 @@
 #define LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/AsmPrinter.h"
 #include <vector>
 
 namespace llvm {
@@ -152,6 +153,8 @@ class DwarfCFIException : public DwarfException {
   /// should be emitted.
   bool shouldEmitMoves;
 
+  AsmPrinter::CFIMoveType moveTypeModule;
+
 public:
   //===--------------------------------------------------------------------===//
   // Main entry points.
diff --git a/test/DebugInfo/debug_frame.ll b/test/DebugInfo/debug_frame.ll
new file mode 100644 (file)
index 0000000..d267ad6
--- /dev/null
@@ -0,0 +1,18 @@
+; RUN: llc %s -o - | FileCheck %s
+
+; Test that we produce a .debug_frame, not an .eh_frame
+
+; CHECK: .cfi_sections .debug_frame
+
+define void @f() nounwind {
+entry:
+  ret void
+}
+
+!llvm.dbg.sp = !{!0}
+
+!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"f", metadata !"f", metadata !"", metadata !1, i32 1, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void ()* @f, null, null} ; [ DW_TAG_subprogram ]
+!1 = metadata !{i32 589865, metadata !"/home/espindola/llvm/test.c", metadata !"/home/espindola/llvm/build", metadata !2} ; [ DW_TAG_file_type ]
+!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/home/espindola/llvm/test.c", metadata !"/home/espindola/llvm/build", metadata !"clang version 3.0 ()", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
+!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
+!4 = metadata !{null}