[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)

Stephen Tozer via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 12 08:12:36 PST 2024


https://github.com/SLTozer updated https://github.com/llvm/llvm-project/pull/118026

>From efd7f58e421b0afdc886688128f72170e0c4a970 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Wed, 25 Sep 2024 15:08:39 +0100
Subject: [PATCH 1/2] [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                  | 14 ++++++++++++++
 clang/include/clang/Basic/CodeGenOptions.def |  3 +++
 clang/include/clang/Basic/CodeGenOptions.h   |  6 ++++++
 clang/include/clang/Driver/Options.td        | 20 ++++++++++++++++++++
 clang/lib/Driver/ToolChains/Clang.cpp        |  2 ++
 clang/test/Driver/extend-variable-liveness.c | 15 +++++++++++++++
 6 files changed, 60 insertions(+)
 create mode 100644 clang/test/Driver/extend-variable-liveness.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 601a233b81904f..19a40d4666c727 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -412,6 +412,20 @@ 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-variable-liveness`` flag has been added to allow for improved
+  debugging of optimized code. Using ``-fextend-variable-liveness`` will cause
+  Clang to generate code that tries to preserve the liveness of source variables
+  through optimizations, meaning that variables will typically be visible in a
+  debugger more often. The flag has two levels: ``-fextend-variable-liveness``,
+  or ``-fextend-variable-liveness=all``, extendes the liveness of all user
+  variables and the ``this`` pointer. Alternatively ``-fextend-this-ptr``, or
+  ``-fextend-variable-liveness=this``, has the same behaviour but applies only
+  to the ``this`` variable in C++ class member functions, meaning its effect is
+  a strict subset of ``-fextend-variable-liveness``. Note that this flag
+  modifies the results of optimizations that Clang performs, which will result
+  in reduced performance in generated code; however, this feature will not
+  extend the liveness of some variables in cases where doing so would likely
+  have a severe 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 4cf22c4ee08ce0..8d181c96bc9641 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -393,6 +393,9 @@ CODEGENOPT(EnableTLSDESC, 1, 0)
 /// Bit size of immediate TLS offsets (0 == use the default).
 VALUE_CODEGENOPT(TLSSize, 8, 0)
 
+/// The types of variables that we will extend the live ranges of.
+ENUM_CODEGENOPT(ExtendVariableLiveness, ExtendVariableLivenessKind, 2, ExtendVariableLivenessKind::None)
+
 /// The default stack protector guard offset to use.
 VALUE_CODEGENOPT(StackProtectorGuardOffset, 32, INT_MAX)
 
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 2dcf98b465661e..f55d9513443e8c 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -95,6 +95,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
     Embed_Marker    // Embed a marker as a placeholder for bitcode.
   };
 
+  enum class ExtendVariableLivenessKind {
+    None,
+    This,
+    All,
+  };
+
   enum InlineAsmDialectKind {
     IAD_ATT,
     IAD_Intel,
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 9c356c9d2ea4ef..bd9e5407d3843b 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4298,6 +4298,26 @@ def stack_usage_file : Separate<["-"], "stack-usage-file">,
   Visibility<[CC1Option]>,
   HelpText<"Filename (or -) to write stack usage output to">,
   MarshallingInfoString<CodeGenOpts<"StackUsageOutput">>;
+def fextend_variable_liveness_EQ : Joined<["-"], "fextend-variable-liveness=">,
+  Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+  HelpText<"Extend the liveness of user variables through optimizations to "
+           "prevent stale or optimized-out variable values when debugging. Can "
+           "be applied to all user variables, or just to the C++ 'this' ptr. "
+           "May choose not to extend the liveness of some variables, such as "
+           "non-scalars larger than 4 unsigned ints, or variables in any "
+           "inlined functions.">,
+  Values<"all,this,none">,
+  NormalizedValues<["All", "This", "None"]>,
+  NormalizedValuesScope<"CodeGenOptions::ExtendVariableLivenessKind">,
+  MarshallingInfoEnum<CodeGenOpts<"ExtendVariableLiveness">, "None">;
+def fextend_this_ptr_liveness : Flag<["-"], "fextend-this-ptr-liveness">,
+  Visibility<[ClangOption, CC1Option]>,
+  Alias<fextend_variable_liveness_EQ>, AliasArgs<["this"]>,
+  HelpText<"Alias for -fextend-variable-liveness=this.">;
+def fextend_variable_liveness : Flag<["-"], "fextend-variable-liveness">,
+  Visibility<[ClangOption, CC1Option]>,
+  Alias<fextend_variable_liveness_EQ>, AliasArgs<["all"]>,
+  HelpText<"Alias for -fextend-variable-liveness=all.">;
 
 defm unique_basic_block_section_names : BoolFOption<"unique-basic-block-section-names",
   CodeGenOpts<"UniqueBasicBlockSectionNames">, DefaultFalse,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 217c1a845f0a47..ece14d1e3cbf7d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7654,6 +7654,8 @@ 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");
 
+  Args.AddLastArg(CmdArgs, options::OPT_fextend_variable_liveness_EQ);
+
   // Forward -fcomment-block-commands to -cc1.
   Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
   // Forward -fparse-all-comments to -cc1.
diff --git a/clang/test/Driver/extend-variable-liveness.c b/clang/test/Driver/extend-variable-liveness.c
new file mode 100644
index 00000000000000..bdd89d6f7721ce
--- /dev/null
+++ b/clang/test/Driver/extend-variable-liveness.c
@@ -0,0 +1,15 @@
+// Tests that -fextend-variable-liveness and its aliases are correctly passed
+// by the driver.
+
+// RUN: %clang -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,DEFAULT
+// RUN: %clang -fextend-variable-liveness=none -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NONE
+// RUN: %clang -fextend-variable-liveness=this -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,THIS
+// RUN: %clang -fextend-this-ptr-liveness -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,THIS
+// RUN: %clang -fextend-variable-liveness=all -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,ALL
+// RUN: %clang -fextend-variable-liveness -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,ALL
+
+// CHECK:       "-cc1"
+// DEFAULT-NOT: -fextend-variable-liveness
+// NONE-SAME:   "-fextend-variable-liveness=none"
+// THIS-SAME:   "-fextend-variable-liveness=this"
+// ALL-SAME:    "-fextend-variable-liveness=all"

>From 2b59ce78f1b84081966db17f48f86776236066ad Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Thu, 28 Nov 2024 13:53:20 +0000
Subject: [PATCH 2/2] Enable -fextend-lifetimes at -Og

---
 clang/docs/CommandGuide/clang.rst            | 7 +++++--
 clang/docs/ReleaseNotes.rst                  | 4 ++++
 clang/lib/Driver/ToolChains/Clang.cpp        | 8 +++++++-
 clang/test/Driver/extend-variable-liveness.c | 3 ++-
 4 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst
index ca8176f854729b..f8294a01048fec 100644
--- a/clang/docs/CommandGuide/clang.rst
+++ b/clang/docs/CommandGuide/clang.rst
@@ -442,8 +442,11 @@ Code Generation Options
     :option:`-Oz` Like :option:`-Os` (and thus :option:`-O2`), but reduces code
     size further.
 
-    :option:`-Og` Like :option:`-O1`. In future versions, this option might
-    disable different optimizations in order to improve debuggability.
+    :option:`-Og` Similar to :option:`-O1`, but with slightly reduced
+    optimization and better variable visibility. The same optimizations are run
+    as at :option:`-O1`, but the :option:`-fextend-variable-liveness` flag is
+    also set, which tries to prevent optimizations from reducing the liveness of
+    user variables, improving their availability when debugging.
 
     :option:`-O` Equivalent to :option:`-O1`.
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 19a40d4666c727..2771e45aabeb43 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -455,6 +455,10 @@ Modified Compiler Flags
   ``memset`` and similar functions for which it is a documented undefined
   behavior. It is implied by ``-Wnontrivial-memaccess``
 
+- The ``-Og`` optimization flag now sets ``-fextend-variable-liveness``, a new
+  compiler flag which trades a small amount of optimization in exchange for
+  improved variable visibility.
+
 Removed Compiler Flags
 -------------------------
 
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index ece14d1e3cbf7d..629f7dd21ce38d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7654,7 +7654,13 @@ 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");
 
-  Args.AddLastArg(CmdArgs, options::OPT_fextend_variable_liveness_EQ);
+  if (Arg *A = Args.getLastArg(options::OPT_fextend_variable_liveness_EQ)) {
+    A->render(Args, CmdArgs);
+  } else if (Arg *A = Args.getLastArg(options::OPT_O_Group);
+             A && A->containsValue("g")) {
+    // Set -fextend-variable-liveness=all by default at -Og.
+    CmdArgs.push_back("-fextend-variable-liveness=all");
+  }
 
   // Forward -fcomment-block-commands to -cc1.
   Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
diff --git a/clang/test/Driver/extend-variable-liveness.c b/clang/test/Driver/extend-variable-liveness.c
index bdd89d6f7721ce..95c9f6bc6904c1 100644
--- a/clang/test/Driver/extend-variable-liveness.c
+++ b/clang/test/Driver/extend-variable-liveness.c
@@ -1,7 +1,8 @@
 // Tests that -fextend-variable-liveness and its aliases are correctly passed
-// by the driver.
+// by the driver, and are set by default at -Og.
 
 // RUN: %clang -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,DEFAULT
+// RUN: %clang -### -Og -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,ALL
 // RUN: %clang -fextend-variable-liveness=none -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NONE
 // RUN: %clang -fextend-variable-liveness=this -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,THIS
 // RUN: %clang -fextend-this-ptr-liveness -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,THIS



More information about the cfe-commits mailing list