dcandler created this revision.
dcandler added reviewers: echristo, probinson, aprantl.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya, kristof.beyls, 
javed.absar.
Herald added projects: clang, LLVM.

This adds a flag to LLVM and clang to always generate call frame information, 
even if other debug information is not being generated. This would be useful 
for the Arm toolchain where the .debug_frame section is always expected to be 
present (with or without other debug sections) and can be used to calculate 
stack usage, although the flag itself has been left generic to cover any other 
potential situations where cfi directives are desired, but other debug 
information is not.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D67216

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/Driver/always-need-cfi.c
  llvm/docs/CommandGuide/llc.rst
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/test/CodeGen/ARM/always-need-cfi.ll

Index: llvm/test/CodeGen/ARM/always-need-cfi.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/ARM/always-need-cfi.ll
@@ -0,0 +1,38 @@
+; RUN: llc -mtriple armv7-unknown -frame-pointer=all -filetype=asm -o - %s | FileCheck %s --check-prefix=CHECK-NO-CFI
+; RUN: llc -mtriple armv7-unknown -frame-pointer=all -filetype=asm -always-need-cfi -o - %s | FileCheck %s --check-prefix=CHECK-ALWAYS-CFI
+
+declare void @dummy_use(i32*, i32)
+
+define void @test_basic() #0 {
+        %mem = alloca i32, i32 10
+        call void @dummy_use (i32* %mem, i32 10)
+	ret void
+}
+
+; CHECK-NO-CFI-LABEL: test_basic:
+; CHECK-NO-CFI:   .fnstart
+; CHECK-NO-CFI-NOT:   .cfi_sections .debug_frame
+; CHECK-NO-CFI-NOT:   .cfi_startproc
+; CHECK-NO-CFI:       @ %bb.0:
+; CHECK-NO-CFI:       push {r11, lr}
+; CHECK-NO-CFI-NOT:   .cfi_def_cfa_offset 8
+; CHECK-NO-CFI-NOT:   .cfi_offset lr, -4
+; CHECK-NO-CFI-NOT:   .cfi_offset r11, -8
+; CHECK-NO-CFI:       mov r11, sp
+; CHECK-NO-CFI-NOT:   .cfi_def_cfa_register r11
+; CHECK-NO-CFI-NOT:   .cfi_endproc
+; CHECK-NO-CFI:       .fnend
+
+; CHECK-ALWAYS-CFI-LABEL: test_basic:
+; CHECK-ALWAYS-CFI:   .fnstart
+; CHECK-ALWAYS-CFI:   .cfi_sections .debug_frame
+; CHECK-ALWAYS-CFI:   .cfi_startproc
+; CHECK-ALWAYS-CFI:   @ %bb.0:
+; CHECK-ALWAYS-CFI:   push {r11, lr}
+; CHECK-ALWAYS-CFI:   .cfi_def_cfa_offset 8
+; CHECK-ALWAYS-CFI:   .cfi_offset lr, -4
+; CHECK-ALWAYS-CFI:   .cfi_offset r11, -8
+; CHECK-ALWAYS-CFI:   mov r11, sp
+; CHECK-ALWAYS-CFI:   .cfi_def_cfa_register r11
+; CHECK-ALWAYS-CFI:   .cfi_endproc
+; CHECK-ALWAYS-CFI:   .fnend
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -149,6 +149,11 @@
     cl::desc("Emit a section containing remark diagnostics metadata"),
     cl::init(false));
 
+static cl::opt<bool> AlwaysNeedCFI(
+    "always-need-cfi",
+    cl::desc("Always emit call frame information"),
+    cl::init(false));
+
 char AsmPrinter::ID = 0;
 
 using gcp_map_type = DenseMap<GCStrategy *, std::unique_ptr<GCMetadataPrinter>>;
@@ -929,7 +934,7 @@
       MF->getFunction().needsUnwindTableEntry())
     return CFI_M_EH;
 
-  if (MMI->hasDebugInfo())
+  if (MMI->hasDebugInfo() || AlwaysNeedCFI)
     return CFI_M_Debug;
 
   return CFI_M_None;
Index: llvm/docs/CommandGuide/llc.rst
===================================================================
--- llvm/docs/CommandGuide/llc.rst
+++ llvm/docs/CommandGuide/llc.rst
@@ -152,6 +152,10 @@
  Emit the .remarks (ELF) / __remarks (MachO) section which contains metadata
  about remark diagnostics.
 
+.. option:: -always-need-cfi
+
+ Emit call frame information even if other debug information is not present.
+
 Tuning/Configuration Options
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Index: clang/test/Driver/always-need-cfi.c
===================================================================
--- /dev/null
+++ clang/test/Driver/always-need-cfi.c
@@ -0,0 +1,7 @@
+
+// RUN: %clang -target arm -c -### %s -falways-need-cfi 2>&1 | FileCheck --check-prefix=CHECK-ALWAYS %s
+// RUN: %clang -target arm -c -### %s -fno-always-need-cfi 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s
+// RUN: %clang -target arm -c -### %s 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s
+
+// CHECK-ALWAYS: -falways-need-cfi
+// CHECK-NO-ALWAYS-NOT: -falways-need-cfi
\ No newline at end of file
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -953,6 +953,8 @@
       Args.hasFlag(OPT_fstack_size_section, OPT_fno_stack_size_section, false);
   Opts.UniqueSectionNames = Args.hasFlag(OPT_funique_section_names,
                                          OPT_fno_unique_section_names, true);
+  Opts.AlwaysNeedCFI =
+      Args.hasFlag(OPT_falways_need_cfi, OPT_fno_always_need_cfi, false);
 
   Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions);
 
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -4563,6 +4563,10 @@
     CmdArgs.push_back(A->getValue());
   }
 
+  if (Args.hasFlag(options::OPT_falways_need_cfi,
+                   options::OPT_fno_always_need_cfi, false))
+    CmdArgs.push_back("-falways-need-cfi");
+
   // Pass -fmessage-length=.
   CmdArgs.push_back("-fmessage-length");
   if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1924,6 +1924,10 @@
 def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group<g_Group>,
   HelpText<"Generate source-level debug information with dwarf version 5">;
 
+def falways_need_cfi : Flag<["-"], "falways-need-cfi">, Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Emit call frame information, even if other debug information is not being emitted.">;
+def fno_always_need_cfi : Flag<["-"], "fno-always-need-cfi">, Group<f_Group>, Flags<[CC1Option]>;
+
 def gcodeview : Flag<["-"], "gcodeview">,
   HelpText<"Generate CodeView debug information">,
   Flags<[CC1Option, CC1AsOption, CoreOption]>;
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -96,6 +96,7 @@
 CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
                                            ///< enabled.
 CODEGENOPT(StackSizeSection  , 1, 0) ///< Set when -fstack-size-section is enabled.
+CODEGENOPT(AlwaysNeedCFI  , 1, 0) ///< Set when -falways-need-cfi is enabled.
 
 ///< Set when -fxray-always-emit-customevents is enabled.
 CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D67216: [... David Candler via Phabricator via cfe-commits

Reply via email to