aboutsummaryrefslogtreecommitdiff
path: root/clang/include
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2022-07-13 15:52:17 +0800
committerKito Cheng <kito.cheng@sifive.com>2022-07-26 15:47:47 +0800
commit7a5cb15ea6facd82756adafae76d60f36a0b60fd (patch)
treeda7a2edf49c6964a3d4e48ed34fcb1ccf939304e /clang/include
parent2f9fa9ef5387de3d87b0c866c678d93695c1c1f3 (diff)
downloadllvm-7a5cb15ea6facd82756adafae76d60f36a0b60fd.zip
llvm-7a5cb15ea6facd82756adafae76d60f36a0b60fd.tar.gz
llvm-7a5cb15ea6facd82756adafae76d60f36a0b60fd.tar.bz2
[RISCV] Lazily add RVV C intrinsics.
Leverage the method OpenCL uses that adds C intrinsics when the lookup failed. There is no need to define C intrinsics in the header file any more. It could help to avoid the large header file to speed up the compilation of RVV source code. Besides that, only the C intrinsics used by the users will be added into the declaration table. This patch is based on https://reviews.llvm.org/D103228 and inspired by OpenCL implementation. ### Experimental Results #### TL;DR: - Binary size of clang increase ~200k, which is +0.07% for debug build and +0.13% for release build. - Single file compilation speed up ~33x for debug build and ~8.5x for release build - Regression time reduce ~10% (`ninja check-all`, enable all targets) #### Header size change ``` | size | LoC | ------------------------------ Before | 4,434,725 | 69,749 | After | 6,140 | 162 | ``` #### Single File Compilation Time Testcase: ``` #include <riscv_vector.h> vint32m1_t test_vadd_vv_vfloat32m1_t(vint32m1_t op1, vint32m1_t op2, size_t vl) { return vadd(op1, op2, vl); } ``` ##### Debug build: Before: ``` real 0m19.352s user 0m19.252s sys 0m0.092s ``` After: ``` real 0m0.576s user 0m0.552s sys 0m0.024s ``` ~33x speed up for debug build ##### Release build: Before: ``` real 0m0.773s user 0m0.741s sys 0m0.032s ``` After: ``` real 0m0.092s user 0m0.080s sys 0m0.012s ``` ~8.5x speed up for release build #### Regression time Note: the failed case is `tools/llvm-debuginfod-find/debuginfod.test` which is unrelated to this patch. ##### Debug build Before: ``` Testing Time: 1358.38s Skipped : 11 Unsupported : 446 Passed : 75767 Expectedly Failed: 190 Failed : 1 ``` After ``` Testing Time: 1220.29s Skipped : 11 Unsupported : 446 Passed : 75767 Expectedly Failed: 190 Failed : 1 ``` ##### Release build Before: ``` Testing Time: 381.98s Skipped : 12 Unsupported : 1407 Passed : 74765 Expectedly Failed: 176 Failed : 1 ``` After: ``` Testing Time: 346.25s Skipped : 12 Unsupported : 1407 Passed : 74765 Expectedly Failed: 176 Failed : 1 ``` #### Binary size of clang ##### Debug build Before ``` text data bss dec hex filename 335261851 12726004 552812 348540667 14c64efb bin/clang ``` After ``` text data bss dec hex filename 335442803 12798708 552940 348794451 14ca2e53 bin/clang ``` +253K, +0.07% code size ##### Release build Before ``` text data bss dec hex filename 144123975 8374648 483140 152981763 91e5103 bin/clang ``` After ``` text data bss dec hex filename 144255762 8447296 483268 153186326 9217016 bin/clang ``` +204K, +0.13% Authored-by: Kito Cheng <kito.cheng@sifive.com> Co-Authored-by: Hsiangkai Wang <kai.wang@sifive.com> Reviewed By: khchen, aaron.ballman Differential Revision: https://reviews.llvm.org/D111617
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang/Basic/CMakeLists.txt3
-rw-r--r--clang/include/clang/Basic/TokenKinds.def3
-rw-r--r--clang/include/clang/Parse/Parser.h1
-rw-r--r--clang/include/clang/Sema/RISCVIntrinsicManager.h36
-rw-r--r--clang/include/clang/Sema/Sema.h8
-rw-r--r--clang/include/clang/Support/RISCVVIntrinsicUtils.h97
6 files changed, 127 insertions, 21 deletions
diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 8cd8913..b930842 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -90,3 +90,6 @@ clang_tablegen(riscv_vector_builtins.inc -gen-riscv-vector-builtins
clang_tablegen(riscv_vector_builtin_cg.inc -gen-riscv-vector-builtin-codegen
SOURCE riscv_vector.td
TARGET ClangRISCVVectorBuiltinCG)
+clang_tablegen(riscv_vector_builtin_sema.inc -gen-riscv-vector-builtin-sema
+ SOURCE riscv_vector.td
+ TARGET ClangRISCVVectorBuiltinSema)
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 7b65a15..84fc089 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -908,6 +908,9 @@ PRAGMA_ANNOTATION(pragma_fp)
// Annotation for the attribute pragma directives - #pragma clang attribute ...
PRAGMA_ANNOTATION(pragma_attribute)
+// Annotation for the riscv pragma directives - #pragma clang riscv intrinsic ...
+PRAGMA_ANNOTATION(pragma_riscv)
+
// Annotations for module import translated from #include etc.
ANNOTATION(module_include)
ANNOTATION(module_begin)
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index a9c85ce..41bfc9f 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -215,6 +215,7 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> AttributePragmaHandler;
std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
+ std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
std::unique_ptr<CommentHandler> CommentSemaHandler;
diff --git a/clang/include/clang/Sema/RISCVIntrinsicManager.h b/clang/include/clang/Sema/RISCVIntrinsicManager.h
new file mode 100644
index 0000000..5051002
--- /dev/null
+++ b/clang/include/clang/Sema/RISCVIntrinsicManager.h
@@ -0,0 +1,36 @@
+//===- RISCVIntrinsicManager.h - RISC-V Intrinsic Handler -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the RISCVIntrinsicManager, which handles RISC-V vector
+// intrinsic functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_RISCVINTRINSICMANAGER_H
+#define LLVM_CLANG_SEMA_RISCVINTRINSICMANAGER_H
+
+namespace clang {
+class Sema;
+class LookupResult;
+class IdentifierInfo;
+class Preprocessor;
+
+namespace sema {
+class RISCVIntrinsicManager {
+public:
+ virtual ~RISCVIntrinsicManager() = default;
+
+ // Create RISC-V intrinsic and insert into symbol table and return true if
+ // found, otherwise return false.
+ virtual bool CreateIntrinsicIfFound(LookupResult &LR, IdentifierInfo *II,
+ Preprocessor &PP) = 0;
+};
+} // end namespace sema
+} // end namespace clang
+
+#endif
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b149c24..06ea0b4 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -226,6 +226,7 @@ namespace sema {
class FunctionScopeInfo;
class LambdaScopeInfo;
class PossiblyUnreachableDiag;
+ class RISCVIntrinsicManager;
class SemaPPCallbacks;
class TemplateDeductionInfo;
}
@@ -1587,7 +1588,12 @@ public:
/// assignment.
llvm::DenseMap<const VarDecl *, int> RefsMinusAssignments;
+ /// Indicate RISC-V vector builtin functions enabled or not.
+ bool DeclareRISCVVBuiltins = false;
+
private:
+ std::unique_ptr<sema::RISCVIntrinsicManager> RVIntrinsicManager;
+
Optional<std::unique_ptr<DarwinSDKInfo>> CachedDarwinSDKInfo;
bool WarnedDarwinSDKInfoMissing = false;
@@ -13590,6 +13596,8 @@ void Sema::PragmaStack<Sema::AlignPackInfo>::Act(SourceLocation PragmaLocation,
llvm::StringRef StackSlotLabel,
AlignPackInfo Value);
+std::unique_ptr<sema::RISCVIntrinsicManager>
+CreateRISCVIntrinsicManager(Sema &S);
} // end namespace clang
namespace llvm {
diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h
index a5e7e6d..727f48d 100644
--- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h
+++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h
@@ -18,6 +18,10 @@
#include <string>
#include <vector>
+namespace llvm {
+class raw_ostream;
+} // end namespace llvm
+
namespace clang {
namespace RISCV {
@@ -104,12 +108,14 @@ struct PrototypeDescriptor {
uint8_t TM = static_cast<uint8_t>(TypeModifier::NoModifier);
bool operator!=(const PrototypeDescriptor &PD) const {
- return PD.PT != PT || PD.VTM != VTM || PD.TM != TM;
+ return !(*this == PD);
}
- bool operator>(const PrototypeDescriptor &PD) const {
- return !(PD.PT <= PT && PD.VTM <= VTM && PD.TM <= TM);
+ bool operator==(const PrototypeDescriptor &PD) const {
+ return PD.PT == PT && PD.VTM == VTM && PD.TM == TM;
+ }
+ bool operator<(const PrototypeDescriptor &PD) const {
+ return std::tie(PT, VTM, TM) < std::tie(PD.PT, PD.VTM, PD.TM);
}
-
static const PrototypeDescriptor Mask;
static const PrototypeDescriptor Vector;
static const PrototypeDescriptor VL;
@@ -224,8 +230,12 @@ public:
bool isFloat(unsigned Width) const {
return isFloat() && ElementBitwidth == Width;
}
-
+ bool isConstant() const { return IsConstant; }
bool isPointer() const { return IsPointer; }
+ unsigned getElementBitwidth() const { return ElementBitwidth; }
+
+ ScalarTypeKind getScalarType() const { return ScalarType; }
+ VScaleVal getScale() const { return Scale; }
private:
// Verify RVV vector type and set Valid.
@@ -263,18 +273,6 @@ public:
PrototypeDescriptor Proto);
};
-using RISCVPredefinedMacroT = uint8_t;
-
-enum RISCVPredefinedMacro : RISCVPredefinedMacroT {
- Basic = 0,
- V = 1 << 1,
- Zvfh = 1 << 2,
- RV64 = 1 << 3,
- VectorMaxELen64 = 1 << 4,
- VectorMaxELenFp32 = 1 << 5,
- VectorMaxELenFp64 = 1 << 6,
-};
-
enum PolicyScheme : uint8_t {
SchemeNone,
HasPassthruOperand,
@@ -302,7 +300,6 @@ private:
// The types we use to obtain the specific LLVM intrinsic. They are index of
// InputTypes. -1 means the return type.
std::vector<int64_t> IntrinsicTypes;
- RISCVPredefinedMacroT RISCVPredefinedMacros = 0;
unsigned NF = 1;
public:
@@ -333,9 +330,6 @@ public:
llvm::StringRef getIRName() const { return IRName; }
llvm::StringRef getManualCodegen() const { return ManualCodegen; }
PolicyScheme getPolicyScheme() const { return Scheme; }
- RISCVPredefinedMacroT getRISCVPredefinedMacros() const {
- return RISCVPredefinedMacros;
- }
unsigned getNF() const { return NF; }
const std::vector<int64_t> &getIntrinsicTypes() const {
return IntrinsicTypes;
@@ -349,6 +343,67 @@ public:
llvm::ArrayRef<PrototypeDescriptor> PrototypeDescriptors);
};
+// RVVRequire should be sync'ed with target features, but only
+// required features used in riscv_vector.td.
+enum RVVRequire : uint8_t {
+ RVV_REQ_None = 0,
+ RVV_REQ_RV64 = 1 << 0,
+ RVV_REQ_FullMultiply = 1 << 1,
+
+ LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_FullMultiply)
+};
+
+// Raw RVV intrinsic info, used to expand later.
+// This struct is highly compact for minimized code size.
+struct RVVIntrinsicRecord {
+ // Intrinsic name, e.g. vadd_vv
+ const char *Name;
+
+ // Overloaded intrinsic name, could be empty if it can be computed from Name.
+ // e.g. vadd
+ const char *OverloadedName;
+
+ // Prototype for this intrinsic, index of RVVSignatureTable.
+ uint16_t PrototypeIndex;
+
+ // Prototype for masked intrinsic, index of RVVSignatureTable.
+ uint16_t MaskedPrototypeIndex;
+
+ // Suffix of intrinsic name, index of RVVSignatureTable.
+ uint16_t SuffixIndex;
+
+ // Suffix of overloaded intrinsic name, index of RVVSignatureTable.
+ uint16_t OverloadedSuffixIndex;
+
+ // Length of the prototype.
+ uint8_t PrototypeLength;
+
+ // Length of prototype of masked intrinsic.
+ uint8_t MaskedPrototypeLength;
+
+ // Length of intrinsic name suffix.
+ uint8_t SuffixLength;
+
+ // Length of overloaded intrinsic suffix.
+ uint8_t OverloadedSuffixSize;
+
+ // Required target features for this intrinsic.
+ uint8_t RequiredExtensions;
+
+ // Supported type, mask of BasicType.
+ uint8_t TypeRangeMask;
+
+ // Supported LMUL.
+ uint8_t Log2LMULMask;
+
+ // Number of fields, greater than 1 if it's segment load/store.
+ uint8_t NF;
+};
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const RVVIntrinsicRecord &RVVInstrRecord);
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
} // end namespace RISCV
} // end namespace clang