[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
SLTozer wrote: I've updated this patch, and made it dependent on a [previous PR](https://github.com/llvm/llvm-project/pull/11) - the logic for enabling the flag is coupled with code from the earlier PR, and also we now slightly extend the test added in that PR instead of creating a new one. https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not explicitly set -fno-extend-lifetimes, + // then default to -fextend-lifetimes. + if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { SLTozer wrote: I've moved this behaviour to the driver now. Also regarding the first request to use `A->getValue() == "g"` - if just `-O` is passed then `A->getValue()` will crash, as there are no values. An alternative would be to change the check to `A->getNumValues() && A->getValue() == "g"`, but I think `containsValue` is more concise. https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
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 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>; +def fextend_variable_liveness_EQ : Joined<["-"], "fextend-variable-liveness=">, + 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
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not explicitly set -fno-extend-lifetimes, + // then default to -fextend-lifetimes. + if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { rnk wrote: I agree, the driver's job is usually to unpack high level flags into semi-orthogonal cc1 flags. So, for example, in clang-cl, /O1 becomes a collection of things like `-Os -ffunction-sections -fdata-sections` and maybe something else I've forgotten. `clang++ -fexceptions` becomes `-fexceptions -fcxx-exceptions` in most contexts, separating destructor cleanups from try/throw language support. cc1 flags kind of represent features that are useful to toggle on and off for testing and test case reduction, since they're one of the things we reduce in the [clang crash reducer script](https://github.com/llvm/llvm-project/blob/main/clang/utils/creduce-clang-crash.py). https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not explicitly set -fno-extend-lifetimes, + // then default to -fextend-lifetimes. + if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { dwblaikie wrote: I'm not sure if we have a fundamental principle about how flags should work in the driver V the frontend, but yeah - in some ways the driver acts as a lowering/canonicalizer - representing flag defaults, etc. So I think the expectation that `clang -cc1 -Og` does the same thing as `clang -Og` isn't valid/not something we're striving for (& in some sense counter to what we are striving for: that all the defaults/grouping is handled by the driver, and the frontend can just think about whether a flag is enabled or disabled) https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not explicitly set -fno-extend-lifetimes, + // then default to -fextend-lifetimes. + if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { SLTozer wrote: Is there an advantage to having it passed through the driver? I ask mainly because I see `-fextend-lifetimes` as being a feature of `-Og` optimization, and if you invoke `clang -cc1 -Og` directly then you'd expect/hope that the optimization behaviour would be the same as `clang -Og` - I'm not too familiar with expected Clang behaviour though, so if this is quite normal for driver/frontend behaviour then I'm fine to switch it. https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -0,0 +1,30 @@ +/// Check that we generate fake uses only when -fextend-lifetimes is set and we +/// are not setting optnone, or when we have optimizations set to -Og and we have +/// not passed -fno-extend-lifetimes. +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -fextend-lifetimes %s -o - | FileCheck %s MaskRay wrote: We just need two RUN lines, one with -fextended-lifetimes and one without. -O group is completely orthogonal and does not need to be tested https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not explicitly set -fno-extend-lifetimes, + // then default to -fextend-lifetimes. + if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { MaskRay wrote: `A->getValue() == "g"` Perhaps move the code around ToolChains/Clang.cpp:9198 and let the driver pass -fextend-lifetimes to frontend. https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
https://github.com/SLTozer updated https://github.com/llvm/llvm-project/pull/118026 >From 7e42a82d73e3be98aab8e523b16a2e43d31b0552 Mon Sep 17 00:00:00 2001 From: Stephen Tozer Date: Thu, 28 Nov 2024 13:53:20 + Subject: [PATCH 1/2] Enable -fextend-lifetimes at -Og --- clang/docs/CommandGuide/clang.rst | 7 -- clang/docs/ReleaseNotes.rst | 4 +++ clang/lib/Frontend/CompilerInvocation.cpp | 8 ++ clang/test/CodeGen/fake-use-opt-flags.cpp | 30 +++ 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGen/fake-use-opt-flags.cpp diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst index ca8176f854729b..8f3f0de9446b41 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-lifetimes` flag is also +set, which tries to prevent optimizations from reducing the lifetime of +user variables. :option:`-O` Equivalent to :option:`-O1`. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 601a233b81904f..14fec70dfb85f7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -441,6 +441,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-lifetimes``, a new compiler + flag, resulting in slightly reduced optimization compared to ``-O1`` in + exchange for improved variable visibility. + Removed Compiler Flags - diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 3dd94c31b2bc7a..09322d0617aaad 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not set any explicit -fextend-lifetimes + // value, then default to -fextend-lifetimes=all. + if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { +if (!Args.hasArg(options::OPT_fextend_lifetimes)) + Opts.ExtendLifetimes = true; + } + // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to // -fdirect-access-external-data. Opts.DirectAccessExternalData = diff --git a/clang/test/CodeGen/fake-use-opt-flags.cpp b/clang/test/CodeGen/fake-use-opt-flags.cpp new file mode 100644 index 00..a99ed7a573ab22 --- /dev/null +++ b/clang/test/CodeGen/fake-use-opt-flags.cpp @@ -0,0 +1,30 @@ +/// Check that we generate fake uses only when -fextend-lifetimes is set and we +/// are not setting optnone, or when we have optimizations set to -Og and we have +/// not passed -fno-extend-lifetimes. +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -fextend-lifetimes %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -disable-O0-optnone -fextend-lifetimes %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Og %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Og -fno-extend-lifetimes %s -o - | FileCheck %s + +/// Test various optimization flags with -fextend-lifetimes... +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O1 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O1 -fextend-lifetimes %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O2 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O2 -fextend-lifetimes %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O3 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O3 -fextend-lifetimes %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Os %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Os -fextend-lifetimes %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Oz %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Oz -fextend-lifetimes %s -o - | FileCheck %s --check-prefixes
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
https://github.com/SLTozer edited https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -0,0 +1,30 @@ +/// Check that we generate fake uses only when -fextend-lifetimes is set and we +/// are not setting optnone, or when we have optimizations set to -Og and we have +/// not passed -fno-extend-lifetimes. +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -fextend-lifetimes %s -o - | FileCheck %s SLTozer wrote: Normally I would use implicit-check-not, but in this case we're `CHECK-NEXT`ing from the start of the function to the very end, which equally guarantees that no fake uses have been generated. https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not set any explicit -fextend-lifetimes + // value, then default to -fextend-lifetimes=all. SLTozer wrote: Ah, I implemented the `=` option on a local-only branch, and accidentally left this comment in. My mistake, though I may yet decide to merge the feature into the earlier PRs. https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not set any explicit -fextend-lifetimes + // value, then default to -fextend-lifetimes=all. jmorse wrote: This is going to create confusion by speculating the existence of an `={all,params,this}` fextend-lifetimes when it doesn't exist yet, and might not. https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
https://github.com/jmorse edited https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -441,6 +441,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-lifetimes``, a new compiler + flag, resulting in slightly reduced optimization compared to ``-O1`` in jmorse wrote: Can we just say "trading optimization for improved..." to indicate that this is a conscious decision the developer might make? https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
@@ -0,0 +1,30 @@ +/// Check that we generate fake uses only when -fextend-lifetimes is set and we +/// are not setting optnone, or when we have optimizations set to -Og and we have +/// not passed -fno-extend-lifetimes. +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -fextend-lifetimes %s -o - | FileCheck %s jmorse wrote: Intention of this RUN line is that no fake uses are generated, but there are no test-lines for ensuring that -> add an implicit-fake-not? And the other check-only FileCheck commands. https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
https://github.com/jmorse commented: Some minor test comments, otherwise looking good, https://github.com/llvm/llvm-project/pull/118026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
llvmbot wrote: @llvm/pr-subscribers-clang-codegen Author: Stephen Tozer (SLTozer) Changes This patch follows two other ongoing reviews, https://github.com/llvm/llvm-project/pull/11 and https://github.com/llvm/llvm-project/pull/110102, which add a new feature to Clang - `-fextend-lifetimes`, which generates fake uses for user variables (and the `this` pointer) to prevent them from being optimized out, providing a better debug experience at the cost of less efficient generated code. This is useful for debugging code without the need to disable optimizations outright, which is particularly important when debugging applications where some level of optimization is necessary, e.g. game code. Following the inclusion of the flag, this patch enables it by default when `-Og` is set. Currently, `-Og` is equivalent to `-O1` - it is effectively just an alias. By enabling `-fextend-lifetimes`, this patch changes the code generated by Clang with `-Og` to have reduced optimization and greater debuggability than `-O1`, differentiating the two according to their respective purposes. This idea was discussed previously on [Discourse](https://discourse.llvm.org/t/rfc-redefine-og-o1-and-add-a-new-level-of-og/72850), where there was general agreement with the principle of this change. --- Full diff: https://github.com/llvm/llvm-project/pull/118026.diff 4 Files Affected: - (modified) clang/docs/CommandGuide/clang.rst (+5-2) - (modified) clang/docs/ReleaseNotes.rst (+4) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+8) - (added) clang/test/CodeGen/fake-use-opt-flags.cpp (+30) ``diff diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst index ca8176f854729b..8f3f0de9446b41 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-lifetimes` flag is also +set, which tries to prevent optimizations from reducing the lifetime of +user variables. :option:`-O` Equivalent to :option:`-O1`. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 601a233b81904f..14fec70dfb85f7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -441,6 +441,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-lifetimes``, a new compiler + flag, resulting in slightly reduced optimization compared to ``-O1`` in + exchange for improved variable visibility. + Removed Compiler Flags - diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 3dd94c31b2bc7a..09322d0617aaad 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not set any explicit -fextend-lifetimes + // value, then default to -fextend-lifetimes=all. + if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { +if (!Args.hasArg(options::OPT_fextend_lifetimes)) + Opts.ExtendLifetimes = true; + } + // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to // -fdirect-access-external-data. Opts.DirectAccessExternalData = diff --git a/clang/test/CodeGen/fake-use-opt-flags.cpp b/clang/test/CodeGen/fake-use-opt-flags.cpp new file mode 100644 index 00..a99ed7a573ab22 --- /dev/null +++ b/clang/test/CodeGen/fake-use-opt-flags.cpp @@ -0,0 +1,30 @@ +/// Check that we generate fake uses only when -fextend-lifetimes is set and we +/// are not setting optnone, or when we have optimizations set to -Og and we have +/// not passed -fno-extend-lifetimes. +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -fextend-lifetimes %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -disable-O0-optnone -fextend-lifetimes %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Og %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Og -fno-extend-lifetimes %s -o - | FileCheck %s + +/// Test various optimization flags with -fextend-lifetimes... +// RUN:
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Stephen Tozer (SLTozer) Changes This patch follows two other ongoing reviews, https://github.com/llvm/llvm-project/pull/11 and https://github.com/llvm/llvm-project/pull/110102, which add a new feature to Clang - `-fextend-lifetimes`, which generates fake uses for user variables (and the `this` pointer) to prevent them from being optimized out, providing a better debug experience at the cost of less efficient generated code. This is useful for debugging code without the need to disable optimizations outright, which is particularly important when debugging applications where some level of optimization is necessary, e.g. game code. Following the inclusion of the flag, this patch enables it by default when `-Og` is set. Currently, `-Og` is equivalent to `-O1` - it is effectively just an alias. By enabling `-fextend-lifetimes`, this patch changes the code generated by Clang with `-Og` to have reduced optimization and greater debuggability than `-O1`, differentiating the two according to their respective purposes. This idea was discussed previously on [Discourse](https://discourse.llvm.org/t/rfc-redefine-og-o1-and-add-a-new-level-of-og/72850), where there was general agreement with the principle of this change. --- Full diff: https://github.com/llvm/llvm-project/pull/118026.diff 4 Files Affected: - (modified) clang/docs/CommandGuide/clang.rst (+5-2) - (modified) clang/docs/ReleaseNotes.rst (+4) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+8) - (added) clang/test/CodeGen/fake-use-opt-flags.cpp (+30) ``diff diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst index ca8176f854729b..8f3f0de9446b41 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-lifetimes` flag is also +set, which tries to prevent optimizations from reducing the lifetime of +user variables. :option:`-O` Equivalent to :option:`-O1`. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 601a233b81904f..14fec70dfb85f7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -441,6 +441,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-lifetimes``, a new compiler + flag, resulting in slightly reduced optimization compared to ``-O1`` in + exchange for improved variable visibility. + Removed Compiler Flags - diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 3dd94c31b2bc7a..09322d0617aaad 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not set any explicit -fextend-lifetimes + // value, then default to -fextend-lifetimes=all. + if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { +if (!Args.hasArg(options::OPT_fextend_lifetimes)) + Opts.ExtendLifetimes = true; + } + // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to // -fdirect-access-external-data. Opts.DirectAccessExternalData = diff --git a/clang/test/CodeGen/fake-use-opt-flags.cpp b/clang/test/CodeGen/fake-use-opt-flags.cpp new file mode 100644 index 00..a99ed7a573ab22 --- /dev/null +++ b/clang/test/CodeGen/fake-use-opt-flags.cpp @@ -0,0 +1,30 @@ +/// Check that we generate fake uses only when -fextend-lifetimes is set and we +/// are not setting optnone, or when we have optimizations set to -Og and we have +/// not passed -fno-extend-lifetimes. +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -fextend-lifetimes %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -disable-O0-optnone -fextend-lifetimes %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Og %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Og -fno-extend-lifetimes %s -o - | FileCheck %s + +/// Test various optimization flags with -fextend-lifetimes... +// RUN: %clang_c
[clang] [Clang] Enable -fextend-lifetimes at -Og (PR #118026)
https://github.com/SLTozer created https://github.com/llvm/llvm-project/pull/118026 This patch follows two other ongoing reviews, https://github.com/llvm/llvm-project/pull/11 and https://github.com/llvm/llvm-project/pull/110102, which add a new feature to Clang - `-fextend-lifetimes`, which generates fake uses for user variables (and the `this` pointer) to prevent them from being optimized out, providing a better debug experience at the cost of less efficient generated code. This is useful for debugging code without the need to disable optimizations outright, which is particularly important when debugging applications where some level of optimization is necessary, e.g. game code. Following the inclusion of the flag, this patch enables it by default when `-Og` is set. Currently, `-Og` is equivalent to `-O1` - it is effectively just an alias. By enabling `-fextend-lifetimes`, this patch changes the code generated by Clang with `-Og` to have reduced optimization and greater debuggability than `-O1`, differentiating the two according to their respective purposes. This idea was discussed previously on [Discourse](https://discourse.llvm.org/t/rfc-redefine-og-o1-and-add-a-new-level-of-og/72850), where there was general agreement with the principle of this change. >From 7e42a82d73e3be98aab8e523b16a2e43d31b0552 Mon Sep 17 00:00:00 2001 From: Stephen Tozer Date: Thu, 28 Nov 2024 13:53:20 + Subject: [PATCH] Enable -fextend-lifetimes at -Og --- clang/docs/CommandGuide/clang.rst | 7 -- clang/docs/ReleaseNotes.rst | 4 +++ clang/lib/Frontend/CompilerInvocation.cpp | 8 ++ clang/test/CodeGen/fake-use-opt-flags.cpp | 30 +++ 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGen/fake-use-opt-flags.cpp diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst index ca8176f854729b..8f3f0de9446b41 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-lifetimes` flag is also +set, which tries to prevent optimizations from reducing the lifetime of +user variables. :option:`-O` Equivalent to :option:`-O1`. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 601a233b81904f..14fec70dfb85f7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -441,6 +441,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-lifetimes``, a new compiler + flag, resulting in slightly reduced optimization compared to ``-O1`` in + exchange for improved variable visibility. + Removed Compiler Flags - diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 3dd94c31b2bc7a..09322d0617aaad 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1834,6 +1834,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.setInlining(CodeGenOptions::NormalInlining); } + // If we have specified -Og and have not set any explicit -fextend-lifetimes + // value, then default to -fextend-lifetimes=all. + if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { +if (!Args.hasArg(options::OPT_fextend_lifetimes)) + Opts.ExtendLifetimes = true; + } + // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to // -fdirect-access-external-data. Opts.DirectAccessExternalData = diff --git a/clang/test/CodeGen/fake-use-opt-flags.cpp b/clang/test/CodeGen/fake-use-opt-flags.cpp new file mode 100644 index 00..a99ed7a573ab22 --- /dev/null +++ b/clang/test/CodeGen/fake-use-opt-flags.cpp @@ -0,0 +1,30 @@ +/// Check that we generate fake uses only when -fextend-lifetimes is set and we +/// are not setting optnone, or when we have optimizations set to -Og and we have +/// not passed -fno-extend-lifetimes. +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -fextend-lifetimes %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O0 -disable-O0-optnone -fextend-lifetimes %s -o - | FileCheck %s --check-prefixes=CHECK,EXTEND +// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -Og %s -o - | FileCheck %s --check-prefix