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) 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, HelpText<"Generate source-level debug information with dwarf version 5">; +def falways_need_cfi : Flag<["-"], "falways-need-cfi">, 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, Flags<[CC1Option]>; + def gcodeview : Flag<["-"], "gcodeview">, HelpText<"Generate CodeView debug information">, Flags<[CC1Option, CC1AsOption, CoreOption]>; 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/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/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: 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: 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 AlwaysNeedCFI( + "always-need-cfi", + cl::desc("Always emit call frame information"), + cl::init(false)); + char AsmPrinter::ID = 0; using gcp_map_type = DenseMap>; @@ -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/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