[clang] [clang] add unnamed_addr function attribute (PR #92499)

YAMAMOTO Takashi via cfe-commits cfe-commits at lists.llvm.org
Sun May 19 22:16:51 PDT 2024


https://github.com/yamt updated https://github.com/llvm/llvm-project/pull/92499

>From 52b744c91bdba1cf8cda9d6164ec8fc130d75fab Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 17 May 2024 14:47:06 +0900
Subject: [PATCH 1/3] [clang] add unnamed_addr function attribute

It simply applies the LLVM attribute with the same name to the function.

Sometimes, a programmer knows that function pointer uniqueness doesn't
really matter for some of their functions. In that case, this attribute
opens a possibility of certain optimizations like mergefunc with aliases.
It's especially useful for code generators.
---
 clang/include/clang/Basic/Attr.td                          | 7 +++++++
 clang/lib/CodeGen/CodeGenModule.cpp                        | 4 ++++
 .../Misc/pragma-attribute-supported-attributes-list.test   | 1 +
 3 files changed, 12 insertions(+)

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 52552ba488560..3ee7d43d339f1 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1944,6 +1944,13 @@ def ReturnsTwice : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def UnnamedAddr : InheritableAttr {
+  let Spellings = [Clang<"unnamed_addr">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
+  let SimpleHandler = 1;
+}
+
 def DisableTailCalls : InheritableAttr {
   let Spellings = [Clang<"disable_tail_calls">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 489c08a4d4819..ac9f082a1049b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2506,6 +2506,10 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
       B.addAttribute(llvm::Attribute::MinSize);
   }
 
+  if (D->hasAttr<UnnamedAddrAttr>()) {
+    F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+  }
+
   F->addFnAttrs(B);
 
   unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 318bfb2df2a7a..62ab5cee27a71 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -199,6 +199,7 @@
 // CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
 // CHECK-NEXT: TrivialABI (SubjectMatchRule_record)
 // CHECK-NEXT: Uninitialized (SubjectMatchRule_variable_is_local)
+// CHECK-NEXT: UnnamedAddr (SubjectMatchRule_function)
 // CHECK-NEXT: UnsafeBufferUsage (SubjectMatchRule_function)
 // CHECK-NEXT: UseHandle (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: VecReturn (SubjectMatchRule_record)

>From d96139b848f7536c927505d11a71c933d782a938 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Mon, 20 May 2024 13:57:26 +0900
Subject: [PATCH 2/3] style fix

---
 clang/lib/CodeGen/CodeGenModule.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index ac9f082a1049b..84b0ddf58059a 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2506,9 +2506,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
       B.addAttribute(llvm::Attribute::MinSize);
   }
 
-  if (D->hasAttr<UnnamedAddrAttr>()) {
+  if (D->hasAttr<UnnamedAddrAttr>())
     F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-  }
 
   F->addFnAttrs(B);
 

>From 68e92e93b05f956b10121953ee519297bf83c09a Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Mon, 20 May 2024 14:16:20 +0900
Subject: [PATCH 3/3] document clang unnamed_addr attribute

---
 clang/include/clang/Basic/Attr.td     |  2 +-
 clang/include/clang/Basic/AttrDocs.td | 13 +++++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 3ee7d43d339f1..0e19dce3b59f3 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1947,7 +1947,7 @@ def ReturnsTwice : InheritableAttr {
 def UnnamedAddr : InheritableAttr {
   let Spellings = [Clang<"unnamed_addr">];
   let Subjects = SubjectList<[Function]>;
-  let Documentation = [Undocumented];
+  let Documentation = [UnnamedAddrDocs];
   let SimpleHandler = 1;
 }
 
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index f351822ac74bd..96ff6e38286c0 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4960,6 +4960,19 @@ templates.
   }];
 }
 
+def UnnamedAddrDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``unnamed_addr`` attribute instructs the backend that the pointer of
+the marked function is not significant.
+While this attribute opens a possibility of certain optimizations like
+function merging, it should be used carefully because it weakens C/C++'s
+pointer uniqueness guarantee. It's safe to use this attribute if it's known
+that the pointer of the marked function is never used for comparisons with
+other pointers.
+  }];
+}
+
 def DisableTailCallsDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{



More information about the cfe-commits mailing list