https://github.com/wsmoses created 
https://github.com/llvm/llvm-project/pull/83059

This PR adds functionality for specifying an LLVM function attribute within 
clang. This is necessary for transfering information from C++ into LLVM which 
doens't have a C++-level attribute. This functionality has been demonstrated to 
be helpful in a variety of ways, such as LLVM HTO.

However, this attribute is only intended for advanced users who need to specify 
specific information only available in LLVM attributes. Use of attributes which 
are not tied to a specific version of Clang (e.g. pure) should be preferred 
when available.

 

>From 0afeea9dcc8b02ade26e6ec0652ae1fa6ec33a7c Mon Sep 17 00:00:00 2001
From: "William S. Moses" <g...@wsmoses.com>
Date: Mon, 26 Feb 2024 16:17:55 -0500
Subject: [PATCH] [Clang][HTO] Add clang attribute for propagating llvm-level
 information

---
 clang/include/clang/Basic/Attr.td     |  7 +++++++
 clang/include/clang/Basic/AttrDocs.td | 13 +++++++++++++
 clang/lib/CodeGen/CGCall.cpp          |  8 ++++++++
 clang/lib/CodeGen/CodeGenFunction.cpp | 10 ++++++++++
 clang/test/CodeGen/attr-llvmfn.c      | 14 ++++++++++++++
 5 files changed, 52 insertions(+)
 create mode 100644 clang/test/CodeGen/attr-llvmfn.c

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index fa191c7378dba4..044f4fada3590f 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2211,6 +2211,13 @@ def AllocAlign : InheritableAttr {
   let Documentation = [AllocAlignDocs];
 }
 
+def LLVMFuncAttr : InheritableAttr {
+  let Spellings = [Clang<"llvm_fn_attr">];
+  let Args = [StringArgument<"LLVMAttrName">, StringArgument<"LLVMAttrValue">];
+  let Documentation = [LLVMFuncAttrDocs];
+  let InheritEvenIfAlreadyPresent = 1;
+}
+
 def NoReturn : InheritableAttr {
   let Spellings = [GCC<"noreturn">, Declspec<"noreturn">];
   // FIXME: Does GCC allow this on the function instead?
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b96fbddd51154c..3f93bb6d6fc648 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -781,6 +781,19 @@ pointer is not sufficiently aligned.
   }];
 }
 
+def LLVMFuncAttrDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Use ``__attribute__((llvm_fn_attr(attr_name, attr_value)))`` on a function to 
specify an LLVM function attribute that will be added to this function. 
+
+Note that uses of this attribute are highly compiler specific as the meaning 
and availability of LLVM attributes may change between compiler versions.
+
+This attribute is only intended for advanced users who need to specify 
specific information only available in LLVM attributes. Use of attributes which 
are not tied to a specific version of Clang (e.g. pure) should be preferred 
when available.
+
+The first arugment is a string representing the name of the LLVM attribute to 
be applied and the second arugment is a string representing its value.
+  }];
+}
+
 def EnableIfDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index d05cf1c6e1814e..cb960bf7a3af6f 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2465,6 +2465,14 @@ void CodeGenModule::ConstructAttributeList(StringRef 
Name,
 
     if (TargetDecl->hasAttr<ArmLocallyStreamingAttr>())
       FuncAttrs.addAttribute("aarch64_pstate_sm_body");
+
+    for(auto Attr: TargetDecl->specific_attrs<LLVMFuncAttr>()) {
+      auto name = Attr->getLLVMAttrName();
+      auto value = Attr->getLLVMAttrValue();
+
+      auto Attr = llvm::Attribute::parseAttr(getLLVMContext(), 
AttributeAndValue.first, AttributeAndValue.second);
+      FuncAttrs.addAttribute(Attr);
+    }
   }
 
   // Attach "no-builtins" attributes to:
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index 1ad905078d349c..1d8031c1a27900 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -831,6 +831,16 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, 
QualType RetTy,
         FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass)
       SanOpts.Mask &= ~SanitizerKind::Null;
 
+  if (D) {
+    for(auto Attr: TargetDecl->specific_attrs<LLVMFuncAttr>()) {
+      auto name = Attr->getLLVMAttrName();
+      auto value = Attr->getLLVMAttrValue();
+
+      auto Attr = llvm::Attribute::parseAttr(getLLVMContext(), 
AttributeAndValue.first, AttributeAndValue.second);
+      Fn->addFnAttr(Attr);
+    }
+  }
+
   // Apply xray attributes to the function (as a string, for now)
   bool AlwaysXRayAttr = false;
   if (const auto *XRayAttr = D ? D->getAttr<XRayInstrumentAttr>() : nullptr) {
diff --git a/clang/test/CodeGen/attr-llvmfn.c b/clang/test/CodeGen/attr-llvmfn.c
new file mode 100644
index 00000000000000..72f14a726f795e
--- /dev/null
+++ b/clang/test/CodeGen/attr-llvmfn.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - | FileCheck %s
+
+void t1() __attribute__((llvm_fn_attr("custom_attr", "custom_value"), 
llvm_fn_attr("second_attr", "second_value")));
+
+void t1()
+{
+}
+
+void t2();
+
+void t3() {
+       t2() ____attribute__((llvm_fn_attr("custom_attr", "custom_value"), 
llvm_fn_attr("second_attr", "second_value")));
+}
+

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to