https://github.com/lenary updated https://github.com/llvm/llvm-project/pull/163666
>From 44a5ae384da96462fa2b85ca5647d9a3a4080c14 Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Wed, 15 Oct 2025 17:26:19 -0700 Subject: [PATCH 1/4] [clang] Add clang::nooutline Attribute This change: - Adds a `[[clang::nooutline]]` function attribute for C and C++. There is no equivalent GNU syntax for this attribute, so no `__attribute__` syntax. - Uses the presence of `[[clang::nooutline]]` to add the `nooutline` attribute to IR function definitions. - Adds test for the above. The `nooutline` attribute disables both the Machine Outliner (enabled at Oz for some targets), and the IR Outliner (disabled by default). --- clang/include/clang/Basic/Attr.td | 7 +++++++ clang/lib/CodeGen/CodeGenModule.cpp | 3 +++ clang/test/CodeGen/attr-nooutline.c | 16 ++++++++++++++++ ...agma-attribute-supported-attributes-list.test | 1 + clang/test/Sema/attr-nooutline.c | 7 +++++++ clang/test/Sema/attr-nooutline.cpp | 7 +++++++ 6 files changed, 41 insertions(+) create mode 100644 clang/test/CodeGen/attr-nooutline.c create mode 100644 clang/test/Sema/attr-nooutline.c create mode 100644 clang/test/Sema/attr-nooutline.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index ea3f9df6d8342..361ae41da97dc 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2371,6 +2371,13 @@ def NoInline : DeclOrStmtAttr { let SimpleHandler = 1; } +def NoOutline : DeclOrStmtAttr { + let Spellings = [CXX11<"clang", "nooutline">, C23<"clang", "nooutline">]; + let Subjects = SubjectList<[Function], ErrorDiag>; + let Documentation = [Undocumented]; + let SimpleHandler = 1; +} + def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> { let Spellings = [GCC<"nomips16">]; let Subjects = SubjectList<[Function], ErrorDiag>; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 65f5468c4b998..6a087be3751f0 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2928,6 +2928,9 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::MinSize); } + if (D->hasAttr<NoOutlineAttr>()) + B.addAttribute(llvm::Attribute::NoOutline); + F->addFnAttrs(B); unsigned alignment = D->getMaxAlignment() / Context.getCharWidth(); diff --git a/clang/test/CodeGen/attr-nooutline.c b/clang/test/CodeGen/attr-nooutline.c new file mode 100644 index 0000000000000..b9f175da24cb5 --- /dev/null +++ b/clang/test/CodeGen/attr-nooutline.c @@ -0,0 +1,16 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 6 +// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -disable-O0-optnone -o - | FileCheck %s + + +// CHECK: Function Attrs: noinline nooutline nounwind +// CHECK-LABEL: define dso_local i32 @t1( +// CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 +// CHECK-NEXT: ret i32 [[TMP0]] +// +[[clang::nooutline]] int t1(int x) { + return x; +} diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index d6d900f3caf84..a7c667fa6018d 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -130,6 +130,7 @@ // CHECK-NEXT: NoMerge (SubjectMatchRule_function, SubjectMatchRule_variable) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) // CHECK-NEXT: NoMips16 (SubjectMatchRule_function) +// CHECK-NEXT: NoOutline (SubjectMatchRule_function) // CHECK-NEXT: NoProfileFunction (SubjectMatchRule_function) // CHECK-NEXT: NoRandomizeLayout (SubjectMatchRule_record) // CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global) diff --git a/clang/test/Sema/attr-nooutline.c b/clang/test/Sema/attr-nooutline.c new file mode 100644 index 0000000000000..83848c22d1003 --- /dev/null +++ b/clang/test/Sema/attr-nooutline.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only + +[[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} + +[[clang::nooutline]] void t1(void); + +[[clang::nooutline(2)]] void t2(void); // expected-error {{'clang::nooutline' attribute takes no arguments}} diff --git a/clang/test/Sema/attr-nooutline.cpp b/clang/test/Sema/attr-nooutline.cpp new file mode 100644 index 0000000000000..b6c9b3995081a --- /dev/null +++ b/clang/test/Sema/attr-nooutline.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++17-extensions + +[[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} + +[[clang::nooutline]] void t1(void); + +[[clang::nooutline(2)]] void t2(void); // expected-error {{'clang::nooutline' attribute takes no arguments}} >From 62dcb6101bc55e193a57162326a6138a8f474772 Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Thu, 16 Oct 2025 13:25:32 -0700 Subject: [PATCH 2/4] Address reviewer feedback: Tests, Docs, TableGen --- clang/include/clang/Basic/Attr.td | 4 ++-- clang/include/clang/Basic/AttrDocs.td | 30 +++++++++++++++++++++++++++ clang/test/CodeGen/attr-nooutline.c | 29 +++++++++++++++++--------- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 361ae41da97dc..f2a372503c041 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2372,9 +2372,9 @@ def NoInline : DeclOrStmtAttr { } def NoOutline : DeclOrStmtAttr { - let Spellings = [CXX11<"clang", "nooutline">, C23<"clang", "nooutline">]; + let Spellings = [Clang<"nooutline">]; let Subjects = SubjectList<[Function], ErrorDiag>; - let Documentation = [Undocumented]; + let Documentation = [NoOutlineDocs]; let SimpleHandler = 1; } diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index cad45501df6d2..67fadaff6e4a9 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -862,6 +862,36 @@ with ``__noinline__`` defined as a macro as ``__attribute__((noinline))``. }]; } +def NoOutlineDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +This function attribute suppresses outlining from the annotated function. + +Outlining is the process where common parts of separate functions are extracted +into a separate function (or assembly snippet), and calls to that function or +snippet are inserted in the original functions. In this way, it can be seen as +the opposite of inlining. It can help to reduce code size. + +.. code-block:: c + + [[clang::nooutline]] int x1(int y) { + int z = COMPLEX_MACRO(y); // Not outlined + return z + const1; + } + + int x2(int y) { + int z = COMPLEX_MACRO(y); // May be outlined + return z * const2; + } + + int x3(int y) { + int z = COMPLEX_MACRO(y); // May be outlined + reutrn z / const3; + } + + }]; +} + def MustTailDocs : Documentation { let Category = DocCatStmt; let Content = [{ diff --git a/clang/test/CodeGen/attr-nooutline.c b/clang/test/CodeGen/attr-nooutline.c index b9f175da24cb5..8519414397a8b 100644 --- a/clang/test/CodeGen/attr-nooutline.c +++ b/clang/test/CodeGen/attr-nooutline.c @@ -1,15 +1,24 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 6 -// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -disable-O0-optnone -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=CXX - -// CHECK: Function Attrs: noinline nooutline nounwind -// CHECK-LABEL: define dso_local i32 @t1( -// CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 -// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 -// CHECK-NEXT: ret i32 [[TMP0]] +// C: Function Attrs: noinline nooutline nounwind optnone +// C-LABEL: define dso_local i32 @t1( +// C-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// C-NEXT: [[ENTRY:.*:]] +// C-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +// C-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 +// C-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 +// C-NEXT: ret i32 [[TMP0]] +// +// CXX: Function Attrs: mustprogress noinline nooutline nounwind optnone +// CXX-LABEL: define dso_local noundef i32 @_Z2t1i( +// CXX-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// CXX-NEXT: [[ENTRY:.*:]] +// CXX-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +// CXX-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 +// CXX-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 +// CXX-NEXT: ret i32 [[TMP0]] // [[clang::nooutline]] int t1(int x) { return x; >From 66969e52f04e3b5b49727aec9606beb2cf9e3451 Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Thu, 16 Oct 2025 13:46:36 -0700 Subject: [PATCH 3/4] Release Notes --- clang/docs/ReleaseNotes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59fdbc80e8bed..91571aee7ad6c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -138,6 +138,9 @@ Non-comprehensive list of changes in this release Usable in constant expressions. Implicit conversion is supported for class/struct types with conversion operators. +- Added a new attribute, ``[[clang::nooutline]]`` to suppress outlining from + annotated functions. This uses the LLVM `nooutline` attribute. + New Compiler Flags ------------------ - New option ``-fms-anonymous-structs`` / ``-fno-ms-anonymous-structs`` added >From 2d1b2b782a39c1083bc6ab8e4a5bc5f032351ae0 Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Thu, 16 Oct 2025 14:07:51 -0700 Subject: [PATCH 4/4] Address Review Feedback: Flags, Release Notes --- clang/docs/ReleaseNotes.rst | 6 +++--- clang/test/Sema/attr-nooutline.c | 2 +- clang/test/Sema/attr-nooutline.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 91571aee7ad6c..3c40407faf9d1 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -138,9 +138,6 @@ Non-comprehensive list of changes in this release Usable in constant expressions. Implicit conversion is supported for class/struct types with conversion operators. -- Added a new attribute, ``[[clang::nooutline]]`` to suppress outlining from - annotated functions. This uses the LLVM `nooutline` attribute. - New Compiler Flags ------------------ - New option ``-fms-anonymous-structs`` / ``-fno-ms-anonymous-structs`` added @@ -165,6 +162,9 @@ Attribute Changes in Clang will still generate a stack protector if other local variables or command line flags require it. +- Added a new attribute, ``[[clang::nooutline]]`` to suppress outlining from + annotated functions. This uses the LLVM `nooutline` attribute. + Improvements to Clang's diagnostics ----------------------------------- - Added ``-Wlifetime-safety`` to enable lifetime safety analysis, diff --git a/clang/test/Sema/attr-nooutline.c b/clang/test/Sema/attr-nooutline.c index 83848c22d1003..ceb77c5d59bd8 100644 --- a/clang/test/Sema/attr-nooutline.c +++ b/clang/test/Sema/attr-nooutline.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 -verify -fsyntax-only %s [[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} diff --git a/clang/test/Sema/attr-nooutline.cpp b/clang/test/Sema/attr-nooutline.cpp index b6c9b3995081a..ceb77c5d59bd8 100644 --- a/clang/test/Sema/attr-nooutline.cpp +++ b/clang/test/Sema/attr-nooutline.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++17-extensions +// RUN: %clang_cc1 -verify -fsyntax-only %s [[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
