diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 42f130c3a700d..f1ae8bfb57652 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -66,6 +66,7 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/SemaBase.h" #include "clang/Sema/SemaConcept.h" +#include "clang/Sema/SemaRISCV.h" #include "clang/Sema/TypoCorrection.h" #include "clang/Sema/Weak.h" #include "llvm/ADT/APInt.h" diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index b48f02c601889..5a86d540e5d0b 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -745,6 +745,9 @@ enum ASTRecordTypes { UPDATE_MODULE_LOCAL_VISIBLE = 76, UPDATE_TU_LOCAL_VISIBLE = 77, + + /// Record code for #pragma clang riscv intrinsic vector. + RISCV_VECTOR_INTRINSICS_PRAGMA = 78, }; /// Record types used within a source manager block. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index d276f0d21b958..63f0fde60bb16 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1079,6 +1079,9 @@ class ASTReader /// The IDs of all decls with function effects to be checked. SmallVector DeclsWithEffectsToVerify; + /// The RISC-V intrinsic pragma(including RVV, SiFive and Andes). + SmallVector RISCVVecIntrinsicPragma; + private: struct ImportedSubmodule { serialization::SubmoduleID ID; diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index dbbfc29058f43..d3029373ed2f7 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -640,6 +640,7 @@ class ASTWriter : public ASTDeserializationListener, void WriteDeclsWithEffectsToVerify(Sema &SemaRef); void WriteModuleFileExtension(Sema &SemaRef, ModuleFileExtensionWriter &Writer); + void WriteRISCVIntrinsicPragmas(Sema &SemaRef); unsigned DeclParmVarAbbrev = 0; unsigned DeclContextLexicalAbbrev = 0; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index aec61322fb8be..d015e9446d4c0 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4447,6 +4447,22 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) DeclsToCheckForDeferredDiags.insert(ReadDeclID(F, Record, I)); break; + + case RISCV_VECTOR_INTRINSICS_PRAGMA: { + unsigned NumRecords = Record.front(); + // Last record which is used to keep number of valid records. + if (Record.size() - 1 != NumRecords) + return llvm::createStringError(std::errc::illegal_byte_sequence, + "invalid rvv intrinsic pragma record"); + + if (RISCVVecIntrinsicPragma.empty()) + RISCVVecIntrinsicPragma.append(NumRecords, 0); + // There might be multiple precompiled modules imported, we need to union + // them all. + for (unsigned i = 0; i < NumRecords; ++i) + RISCVVecIntrinsicPragma[i] |= Record[i + 1]; + break; + } } } } @@ -9063,6 +9079,13 @@ void ASTReader::UpdateSema() { PointersToMembersPragmaLocation); } SemaObj->CUDA().ForceHostDeviceDepth = ForceHostDeviceDepth; + if (!RISCVVecIntrinsicPragma.empty()) { + assert(RISCVVecIntrinsicPragma.size() == 3 && + "Wrong number of RISCVVecIntrinsicPragma"); + SemaObj->RISCV().DeclareRVVBuiltins = RISCVVecIntrinsicPragma[0]; + SemaObj->RISCV().DeclareSiFiveVectorBuiltins = RISCVVecIntrinsicPragma[1]; + SemaObj->RISCV().DeclareAndesVectorBuiltins = RISCVVecIntrinsicPragma[2]; + } if (PragmaAlignPackCurrentValue) { // The bottom of the stack might have a default value. It must be adjusted diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index dc7f93e0483e4..21ec7c8b8a704 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -972,6 +972,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(PP_ASSUME_NONNULL_LOC); RECORD(PP_UNSAFE_BUFFER_USAGE); RECORD(VTABLES_TO_EMIT); + RECORD(RISCV_VECTOR_INTRINSICS_PRAGMA); // SourceManager Block. BLOCK(SOURCE_MANAGER_BLOCK); @@ -5232,6 +5233,16 @@ void ASTWriter::WriteModuleFileExtension(Sema &SemaRef, Stream.ExitBlock(); } +void ASTWriter::WriteRISCVIntrinsicPragmas(Sema &SemaRef) { + RecordData Record; + // Need to update this when new intrinsic class is added. + Record.push_back(/*size*/ 3); + Record.push_back(SemaRef.RISCV().DeclareRVVBuiltins); + Record.push_back(SemaRef.RISCV().DeclareSiFiveVectorBuiltins); + Record.push_back(SemaRef.RISCV().DeclareAndesVectorBuiltins); + Stream.EmitRecord(RISCV_VECTOR_INTRINSICS_PRAGMA, Record); +} + //===----------------------------------------------------------------------===// // General Serialization Routines //===----------------------------------------------------------------------===// @@ -6130,6 +6141,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot, WriteFPPragmaOptions(SemaPtr->CurFPFeatureOverrides()); WriteOpenCLExtensions(*SemaPtr); WriteCUDAPragmas(*SemaPtr); + WriteRISCVIntrinsicPragmas(*SemaPtr); } // If we're emitting a module, write out the submodule information. diff --git a/clang/test/PCH/riscv-rvv-vectors.c b/clang/test/PCH/riscv-rvv-vectors.c new file mode 100644 index 0000000000000..0ffd82b6c4ccc --- /dev/null +++ b/clang/test/PCH/riscv-rvv-vectors.c @@ -0,0 +1,40 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t + + +// Test precompiled header +// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -emit-pch -o %t/test_pch.pch %t/test_pch.h +// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -include-pch %t/test_pch.pch \ +// RUN: -fsyntax-only -verify %t/test_pch_src.c +// +// Test precompiled module(only available after C++20) +// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -std=c++20 -xc++-user-header -emit-header-unit -o %t/test_module1.pcm %t/test_module1.h +// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -std=c++20 -xc++-user-header -emit-header-unit -o %t/test_module2.pcm %t/test_module2.h +// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -std=c++20 -fmodule-file=%t/test_module1.pcm -fmodule-file=%t/test_module2.pcm \ +// RUN: -fsyntax-only %t/test_module_src.cpp + +//--- test_pch.h +// expected-no-diagnostics +#include + +//--- test_pch_src.c +// expected-no-diagnostics +vuint64m4_t v_add(vuint64m4_t a, vuint64m4_t b, size_t vl) { + return __riscv_vadd_vv_u64m4(a, b, vl); +} + +//--- test_module1.h +// expected-no-diagnostics +#include + +//--- test_module2.h +// expected-no-diagnostics +// empty header + +//--- test_module_src.cpp +// expected-no-diagnostics +import "test_module1.h"; +import "test_module2.h"; +vuint64m4_t v_add(vuint64m4_t a, vuint64m4_t b, size_t vl) { + return __riscv_vadd_vv_u64m4(a, b, vl); +}