HsiangKai created this revision.
HsiangKai added reviewers: craig.topper, rogfer01, khchen, evandro, frasercrmck.
Herald added subscribers: StephenFan, vkmr, jdoerfert, luismarques, apazos, 
sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, 
brucehoult, MartinMosbeck, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, 
niosHD, sabuasal, simoncook, johnrusso, rbar, asb.
Herald added a reviewer: aaron.ballman.
HsiangKai requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.

There are overloaded version for vector intrinsics. Currently, we use
function wrapper and __overloadable__ attributes for them. It increases
the build/test time a lot.

In this patch, we define __clang_riscv_builtin_alias for RISC-V
intrinsics and use this attribute to map the overloaded version to the
corresponding builtins.

In our downstream testing, it could decrease the testing time from 6.3
seconds to 3.7 seconds for vloxei.c test.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D100611

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Decl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test

Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===================================================================
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -142,6 +142,7 @@
 // CHECK-NEXT: PassObjectSize (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: PatchableFunctionEntry (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: Pointer (SubjectMatchRule_record_not_is_union)
+// CHECK-NEXT: RISCVBuiltinAlias (SubjectMatchRule_function)
 // CHECK-NEXT: ReleaseHandle (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: RenderScriptKernel (SubjectMatchRule_function)
 // CHECK-NEXT: ReqdWorkGroupSize (SubjectMatchRule_function)
Index: clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c
@@ -0,0 +1,35 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv64 -emit-llvm -target-feature +experimental-v \
+// RUN:   %s -o - \
+// RUN:   | FileCheck %s
+
+#include <riscv_vector.h>
+
+#define __rvv_generic \
+static inline __attribute__((__always_inline__, __nodebug__, __overloadable__))
+
+__rvv_generic
+__attribute__((__clang_riscv_builtin_alias(__builtin_rvv_vadd_vv_i8m1)))
+vint8m1_t vadd_generic (vint8m1_t op0, vint8m1_t op1, size_t op2);
+
+// CHECK-LABEL: @test(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[OP0_ADDR:%.*]] = alloca <vscale x 8 x i8>, align 1
+// CHECK-NEXT:    [[OP1_ADDR:%.*]] = alloca <vscale x 8 x i8>, align 1
+// CHECK-NEXT:    [[VL_ADDR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[RET:%.*]] = alloca <vscale x 8 x i8>, align 1
+// CHECK-NEXT:    store <vscale x 8 x i8> [[OP0:%.*]], <vscale x 8 x i8>* [[OP0_ADDR]], align 1
+// CHECK-NEXT:    store <vscale x 8 x i8> [[OP1:%.*]], <vscale x 8 x i8>* [[OP1_ADDR]], align 1
+// CHECK-NEXT:    store i64 [[VL:%.*]], i64* [[VL_ADDR]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = load <vscale x 8 x i8>, <vscale x 8 x i8>* [[OP0_ADDR]], align 1
+// CHECK-NEXT:    [[TMP1:%.*]] = load <vscale x 8 x i8>, <vscale x 8 x i8>* [[OP1_ADDR]], align 1
+// CHECK-NEXT:    [[TMP2:%.*]] = load i64, i64* [[VL_ADDR]], align 8
+// CHECK-NEXT:    [[TMP3:%.*]] = call <vscale x 8 x i8> @llvm.riscv.vadd.nxv8i8.nxv8i8.i64(<vscale x 8 x i8> [[TMP0]], <vscale x 8 x i8> [[TMP1]], i64 [[TMP2]])
+// CHECK-NEXT:    store <vscale x 8 x i8> [[TMP3]], <vscale x 8 x i8>* [[RET]], align 1
+// CHECK-NEXT:    [[TMP4:%.*]] = load <vscale x 8 x i8>, <vscale x 8 x i8>* [[RET]], align 1
+// CHECK-NEXT:    ret <vscale x 8 x i8> [[TMP4]]
+//
+vint8m1_t test(vint8m1_t op0, vint8m1_t op1, size_t vl) {
+  vint8m1_t ret = vadd_generic(op0, op1, vl);
+  return ret;
+}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -5120,6 +5120,7 @@
 #define GET_SVE_BUILTINS
 #define BUILTIN(name, types, attr) case SVE::BI##name:
 #include "clang/Basic/arm_sve_builtins.inc"
+#undef BUILTIN
     return true;
   }
 }
@@ -5146,6 +5147,37 @@
   D->addAttr(::new (S.Context) ArmBuiltinAliasAttr(S.Context, AL, Ident));
 }
 
+static bool RISCVVAliasValid(unsigned BuiltinID, StringRef AliasName) {
+  switch (BuiltinID) {
+  default:
+    return false;
+#define BUILTIN(ID, TYPE, ATTRS) case RISCV::BI##ID:
+#include "clang/Basic/BuiltinsRISCV.def"
+#undef BUILTIN
+    return true;
+  }
+}
+
+static void handleRISCVBuiltinAliasAttr(Sema &S, Decl *D,
+                                        const ParsedAttr &AL) {
+  if (!AL.isArgIdent(0)) {
+    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
+        << AL << 1 << AANT_ArgumentIdentifier;
+    return;
+  }
+
+  IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident;
+  unsigned BuiltinID = Ident->getBuiltinID();
+  StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
+
+  if (!RISCVVAliasValid(BuiltinID, AliasName)) {
+    S.Diag(AL.getLoc(), diag::err_attribute_riscv_builtin_alias);
+    return;
+  }
+
+  D->addAttr(::new (S.Context) RISCVBuiltinAliasAttr(S.Context, AL, Ident));
+}
+
 //===----------------------------------------------------------------------===//
 // Checker-specific attribute handlers.
 //===----------------------------------------------------------------------===//
@@ -8243,6 +8275,10 @@
   case ParsedAttr::AT_EnforceTCBLeaf:
     handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL);
     break;
+
+  case ParsedAttr::AT_RISCVBuiltinAlias:
+    handleRISCVBuiltinAliasAttr(S, D, AL);
+    break;
   }
 }
 
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -3265,6 +3265,8 @@
 
   if (const auto *ABAA = getAttr<ArmBuiltinAliasAttr>()) {
     BuiltinID = ABAA->getBuiltinName()->getBuiltinID();
+  } else if (const auto *RBAA = getAttr<RISCVBuiltinAliasAttr>()) {
+    BuiltinID = RBAA->getBuiltinName()->getBuiltinID();
   } else if (const auto *A = getAttr<BuiltinAttr>()) {
     BuiltinID = A->getID();
   }
@@ -3275,7 +3277,7 @@
   // If the function is marked "overloadable", it has a different mangled name
   // and is not the C library function.
   if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>() &&
-      !hasAttr<ArmBuiltinAliasAttr>())
+      (!hasAttr<ArmBuiltinAliasAttr>() && !hasAttr<RISCVBuiltinAliasAttr>()))
     return 0;
 
   ASTContext &Context = getASTContext();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11249,4 +11249,7 @@
 // RISC-V builtin required extension warning
 def err_riscv_builtin_requires_extension : Error<
   "builtin requires '%0' extension support to be enabled">;
+def err_attribute_riscv_builtin_alias : Error<
+  "'__clang_riscv_builtin_alias' attribute can only be applied to a RISC-V "
+  "builtin">;
 } // end of sema component.
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -2132,6 +2132,26 @@
   }];
 }
 
+def RISCVBuiltinAliasDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+This attribute is used in the implementation of the RVV intrinsics.
+It allows the intrinsic functions to be declared using the names defined
+in RVV, and still be recognized as clang builtins equivalent to the
+underlying name. For example, ``riscv_vector_overloaded.h`` declares the function
+``vget`` with
+``__attribute__((__clang_riscv_builtin_alias(__builtin_rvv_vget_i8mf8x2_i8mf8)))``.
+This ensures that both functions are recognized as that clang builtin,
+and in the latter case, the choice of which builtin to identify the
+function as can be deferred until after overload resolution.
+
+This attribute can only be used to set up the aliases for certain RISC-V
+intrinsic functions; it is intended for use only inside ``riscv_*.h``
+and is not a general mechanism for declaring arbitrary aliases for
+clang builtin functions.
+  }];
+}
+
 def AVRInterruptDocs : Documentation {
   let Category = DocCatFunction;
   let Heading = "interrupt (AVR)";
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1767,6 +1767,13 @@
   let Documentation = [RISCVInterruptDocs];
 }
 
+def RISCVBuiltinAlias : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
+  let Spellings = [Clang<"__clang_riscv_builtin_alias">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Args = [IdentifierArgument<"BuiltinName">];
+  let Documentation = [RISCVBuiltinAliasDocs];
+}
+
 // This is not a TargetSpecificAttr so that is silently accepted and
 // ignored on other targets as encouraged by the OpenCL spec.
 //
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to