[clang] [Clang][HTO] Add clang attribute for propagating llvm-level information (PR #83059)

via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 26 13:25:21 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: William Moses (wsmoses)

<details>
<summary>Changes</summary>

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.

 

---
Full diff: https://github.com/llvm/llvm-project/pull/83059.diff


5 Files Affected:

- (modified) clang/include/clang/Basic/Attr.td (+7) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+13) 
- (modified) clang/lib/CodeGen/CGCall.cpp (+8) 
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+10) 
- (added) clang/test/CodeGen/attr-llvmfn.c (+14) 


``````````diff
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")));
+}
+

``````````

</details>


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


More information about the cfe-commits mailing list