https://github.com/SLTozer created https://github.com/llvm/llvm-project/pull/110000
Following the commit that added the fake use intrinsic to LLVM, this patch adds a pair of flags for the clang frontend that emit fake use intrinsics, for the purpose of extending the lifetime of variables (either all source variables, or just the `this` pointer). This patch does not implement the fake use intrinsic emission of the flags themselves, it simply adds the flags, the corresponding release note, and the attachment of the `has_fake_uses` attribute to affected functions; the remaining functionality appears in the next patch. >From a33566974fbf260181d20d3f1b67081d21493506 Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.to...@sony.com> Date: Wed, 25 Sep 2024 15:08:39 +0100 Subject: [PATCH] [Clang] Add "extend lifetime" flags and release note Following the commit that added the fake use intrinsic to LLVM, this patch adds a pair of flags for the clang frontend that emit fake use intrinsics, for the purpose of extending the lifetime of variables (either all source variables, or just the `this` pointer). This patch does not implement the fake use intrinsic emission of the flags themselves, it simply adds the flags, the corresponding release note, and the attachment of the `has_fake_uses` attribute to affected functions; the remaining functionality appears in the next patch. --- clang/docs/ReleaseNotes.rst | 10 ++++++++++ clang/include/clang/Basic/CodeGenOptions.def | 6 ++++++ clang/include/clang/Driver/Options.td | 9 +++++++++ clang/lib/CodeGen/CGCall.cpp | 4 ++++ clang/lib/Driver/ToolChains/Clang.cpp | 5 +++++ clang/lib/Frontend/CompilerInvocation.cpp | 5 +++++ clang/test/CodeGen/extend-lifetimes-hasfakeuses.c | 12 ++++++++++++ 7 files changed, 51 insertions(+) create mode 100644 clang/test/CodeGen/extend-lifetimes-hasfakeuses.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 14907e7db18de3..249f2171babda1 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -211,6 +211,16 @@ New Compiler Flags only for thread-local variables, and none (which corresponds to the existing ``-fno-c++-static-destructors`` flag) skips all static destructors registration. +- The ``-fextend-lifetimes`` and ``-fextend-this-ptr`` flags have been added to + allow for improved debugging of optimized code. Using ``-fextend-lifetimes`` + will cause Clang to generate code that tries to preserve the lifetimes of + source variables, meaning that variables will typically be visible in a + debugger more often. The ``-fextend-this-ptr`` flag has the same behaviour, + but applies only to the ``this`` variable in C++ class member functions. Note + that this flag modifies the optimizations that Clang performs, which will + result in reduced performance in generated code; however, this feature will + not extend the lifetime of some variables in cases where doing so would have + too severe an impact on generated code performance. Deprecated Compiler Flags ------------------------- diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 2893377e5a38be..18f5225813133f 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -388,6 +388,12 @@ CODEGENOPT(EnableTLSDESC, 1, 0) /// Bit size of immediate TLS offsets (0 == use the default). VALUE_CODEGENOPT(TLSSize, 8, 0) +/// Whether to extend the live range of the `this` pointer. +CODEGENOPT(ExtendThisPtr, 1, 0) + +/// Whether to extend the live ranges of all local variables. +CODEGENOPT(ExtendLifetimes, 1, 0) + /// The default stack protector guard offset to use. VALUE_CODEGENOPT(StackProtectorGuardOffset, 32, INT_MAX) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 23bd686a85f526..a82dbbc113d105 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4263,6 +4263,15 @@ def stack_usage_file : Separate<["-"], "stack-usage-file">, Visibility<[CC1Option]>, HelpText<"Filename (or -) to write stack usage output to">, MarshallingInfoString<CodeGenOpts<"StackUsageOutput">>; +def fextend_this_ptr : Flag <["-"], "fextend-this-ptr">, Group<f_Group>, + MarshallingInfoFlag<CodeGenOpts<"ExtendThisPtr">>, + HelpText<"Extend the lifetime of the 'this' pointer to improve visibility " + "in optimized debugging">, Visibility<[ClangOption, CC1Option]>; +def fextend_lifetimes : Flag <["-"], "fextend-lifetimes">, Group<f_Group>, + MarshallingInfoFlag<CodeGenOpts<"ExtendLifetimes">>, + HelpText<"Extend the lifetimes of local variables and parameters to improve " + "visibility in optimized debugging">, + Visibility<[ClangOption, CC1Option]>; defm unique_basic_block_section_names : BoolFOption<"unique-basic-block-section-names", CodeGenOpts<"UniqueBasicBlockSectionNames">, DefaultFalse, diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 4ae981e4013e9c..2453c580f7db0f 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2543,6 +2543,10 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, if (shouldDisableTailCalls()) FuncAttrs.addAttribute("disable-tail-calls", "true"); + // Mark the function as having fake uses when -fextend-lifetimes is on. + if (CodeGenOpts.ExtendLifetimes || CodeGenOpts.ExtendThisPtr) + FuncAttrs.addAttribute(llvm::Attribute::HasFakeUses); + // CPU/feature overrides. addDefaultFunctionDefinitionAttributes // handles these separately to set them based on the global defaults. GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0bab48caf1a5e2..3fe7817acf61c2 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -7583,6 +7583,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fretain_comments_from_system_headers)) CmdArgs.push_back("-fretain-comments-from-system-headers"); + if (Args.hasArg(options::OPT_fextend_this_ptr)) + CmdArgs.push_back("-fextend-this-ptr"); + if (Args.hasArg(options::OPT_fextend_lifetimes)) + CmdArgs.push_back("-fextend-lifetimes"); + // Forward -fcomment-block-commands to -cc1. Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands); // Forward -fparse-all-comments to -cc1. diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index efd852593468aa..93972c37ac6821 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2217,6 +2217,11 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags, Opts.SanitizeTrap); + Opts.ExtendThisPtr = + Opts.OptimizationLevel > 0 && Args.hasArg(OPT_fextend_this_ptr); + Opts.ExtendLifetimes = + Opts.OptimizationLevel > 0 && Args.hasArg(OPT_fextend_lifetimes); + Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true); if (!LangOpts->CUDAIsDevice) diff --git a/clang/test/CodeGen/extend-lifetimes-hasfakeuses.c b/clang/test/CodeGen/extend-lifetimes-hasfakeuses.c new file mode 100644 index 00000000000000..081bace3dc7cce --- /dev/null +++ b/clang/test/CodeGen/extend-lifetimes-hasfakeuses.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -O2 -fextend-lifetimes -o - | FileCheck --check-prefixes=CHECK-ALL,CHECK-O2 %s +// RUN: %clang_cc1 %s -emit-llvm -O0 -fextend-lifetimes -o - | FileCheck --check-prefixes=CHECK-ALL,CHECK-O0 %s + +// Checks that we emit the function attribute has_fake_uses when +// -fextend-lifetimes is on and optimizations are enabled, and that it does not +// when optimizations are disabled. + +// CHECK-ALL: define {{.*}}void @foo +// CHECK-O2: attributes #0 = {{{.*}}has_fake_uses +// CHECK-O0-NOT: attributes #0 = {{{.*}}has_fake_uses + +void foo() {} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits