https://github.com/lenary updated 
https://github.com/llvm/llvm-project/pull/163666

>From 132e1d6b631c61b643fb02cd2d3c50c09e880d09 Mon Sep 17 00:00:00 2001
From: Sam Elliott <[email protected]>
Date: Wed, 15 Oct 2025 17:26:19 -0700
Subject: [PATCH 1/3] [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 22e60aa9fe312..b8a61ba4cbac9 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2355,6 +2355,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 8d019d4b2da25..ab267236ed579 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2820,6 +2820,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 73d4cb1769ed5..7ef758dbea9eb 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -123,6 +123,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 6337dd0419d4af9d83273f4024bd206f29e4f817 Mon Sep 17 00:00:00 2001
From: Sam Elliott <[email protected]>
Date: Thu, 16 Oct 2025 13:25:32 -0700
Subject: [PATCH 2/3] 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 b8a61ba4cbac9..5d12dda3740bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2356,9 +2356,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 e0bbda083b5cf..2ece34542a952 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 a729b26164df976c11093d05ac6bebda947e75cc Mon Sep 17 00:00:00 2001
From: Sam Elliott <[email protected]>
Date: Thu, 16 Oct 2025 13:46:36 -0700
Subject: [PATCH 3/3] 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 6ebc2f0f63fa7..618ab1855887f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -269,6 +269,9 @@ Non-comprehensive list of changes in this release
   allocation functions with a token ID can be enabled via the
   ``-fsanitize=alloc-token`` flag.
 
+- Added a new attribute, ``[[clang::nooutline]]`` to suppress outlining from
+  annotated functions. This uses the LLVM `nooutline` attribute.
+
 New Compiler Flags
 ------------------
 - New option ``-fno-sanitize-debug-trap-reasons`` added to disable emitting 
trap reasons into the debug info when compiling with trapping UBSan (e.g. 
``-fsanitize-trap=undefined``).

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to