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

William Moses via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 26 13:24:51 PST 2024


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" <gh at 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")));
+}
+



More information about the cfe-commits mailing list