Skip to content

Commit fe577b1

Browse files
authored
[AST][RISCV] Preserve RISC-V intrinsic pragma in AST (#171981)
RISC-V vector intrinsic is generated dynamically at runtime, thus it's note preserved in AST yet when using precompile header, neither do information in SemaRISCV. We need to write these information to ast record to be able to use precompile header for RISC-V. Fixes #109634
1 parent 282e8ea commit fe577b1

File tree

7 files changed

+83
-0
lines changed

7 files changed

+83
-0
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#include "clang/Sema/Scope.h"
6767
#include "clang/Sema/SemaBase.h"
6868
#include "clang/Sema/SemaConcept.h"
69+
#include "clang/Sema/SemaRISCV.h"
6970
#include "clang/Sema/TypoCorrection.h"
7071
#include "clang/Sema/Weak.h"
7172
#include "llvm/ADT/APInt.h"

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,9 @@ enum ASTRecordTypes {
745745
UPDATE_MODULE_LOCAL_VISIBLE = 76,
746746

747747
UPDATE_TU_LOCAL_VISIBLE = 77,
748+
749+
/// Record code for #pragma clang riscv intrinsic vector.
750+
RISCV_VECTOR_INTRINSICS_PRAGMA = 78,
748751
};
749752

750753
/// Record types used within a source manager block.

clang/include/clang/Serialization/ASTReader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,9 @@ class ASTReader
10791079
/// The IDs of all decls with function effects to be checked.
10801080
SmallVector<GlobalDeclID> DeclsWithEffectsToVerify;
10811081

1082+
/// The RISC-V intrinsic pragma(including RVV, SiFive and Andes).
1083+
SmallVector<bool, 3> RISCVVecIntrinsicPragma;
1084+
10821085
private:
10831086
struct ImportedSubmodule {
10841087
serialization::SubmoduleID ID;

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ class ASTWriter : public ASTDeserializationListener,
640640
void WriteDeclsWithEffectsToVerify(Sema &SemaRef);
641641
void WriteModuleFileExtension(Sema &SemaRef,
642642
ModuleFileExtensionWriter &Writer);
643+
void WriteRISCVIntrinsicPragmas(Sema &SemaRef);
643644

644645
unsigned DeclParmVarAbbrev = 0;
645646
unsigned DeclContextLexicalAbbrev = 0;

clang/lib/Serialization/ASTReader.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4465,6 +4465,22 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
44654465
for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
44664466
DeclsToCheckForDeferredDiags.insert(ReadDeclID(F, Record, I));
44674467
break;
4468+
4469+
case RISCV_VECTOR_INTRINSICS_PRAGMA: {
4470+
unsigned NumRecords = Record.front();
4471+
// Last record which is used to keep number of valid records.
4472+
if (Record.size() - 1 != NumRecords)
4473+
return llvm::createStringError(std::errc::illegal_byte_sequence,
4474+
"invalid rvv intrinsic pragma record");
4475+
4476+
if (RISCVVecIntrinsicPragma.empty())
4477+
RISCVVecIntrinsicPragma.append(NumRecords, 0);
4478+
// There might be multiple precompiled modules imported, we need to union
4479+
// them all.
4480+
for (unsigned i = 0; i < NumRecords; ++i)
4481+
RISCVVecIntrinsicPragma[i] |= Record[i + 1];
4482+
break;
4483+
}
44684484
}
44694485
}
44704486
}
@@ -9099,6 +9115,13 @@ void ASTReader::UpdateSema() {
90999115
PointersToMembersPragmaLocation);
91009116
}
91019117
SemaObj->CUDA().ForceHostDeviceDepth = ForceHostDeviceDepth;
9118+
if (!RISCVVecIntrinsicPragma.empty()) {
9119+
assert(RISCVVecIntrinsicPragma.size() == 3 &&
9120+
"Wrong number of RISCVVecIntrinsicPragma");
9121+
SemaObj->RISCV().DeclareRVVBuiltins = RISCVVecIntrinsicPragma[0];
9122+
SemaObj->RISCV().DeclareSiFiveVectorBuiltins = RISCVVecIntrinsicPragma[1];
9123+
SemaObj->RISCV().DeclareAndesVectorBuiltins = RISCVVecIntrinsicPragma[2];
9124+
}
91029125

91039126
if (PragmaAlignPackCurrentValue) {
91049127
// The bottom of the stack might have a default value. It must be adjusted

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,7 @@ void ASTWriter::WriteBlockInfoBlock() {
972972
RECORD(PP_ASSUME_NONNULL_LOC);
973973
RECORD(PP_UNSAFE_BUFFER_USAGE);
974974
RECORD(VTABLES_TO_EMIT);
975+
RECORD(RISCV_VECTOR_INTRINSICS_PRAGMA);
975976

976977
// SourceManager Block.
977978
BLOCK(SOURCE_MANAGER_BLOCK);
@@ -5250,6 +5251,16 @@ void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
52505251
Stream.ExitBlock();
52515252
}
52525253

5254+
void ASTWriter::WriteRISCVIntrinsicPragmas(Sema &SemaRef) {
5255+
RecordData Record;
5256+
// Need to update this when new intrinsic class is added.
5257+
Record.push_back(/*size*/ 3);
5258+
Record.push_back(SemaRef.RISCV().DeclareRVVBuiltins);
5259+
Record.push_back(SemaRef.RISCV().DeclareSiFiveVectorBuiltins);
5260+
Record.push_back(SemaRef.RISCV().DeclareAndesVectorBuiltins);
5261+
Stream.EmitRecord(RISCV_VECTOR_INTRINSICS_PRAGMA, Record);
5262+
}
5263+
52535264
//===----------------------------------------------------------------------===//
52545265
// General Serialization Routines
52555266
//===----------------------------------------------------------------------===//
@@ -6148,6 +6159,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot,
61486159
WriteFPPragmaOptions(SemaPtr->CurFPFeatureOverrides());
61496160
WriteOpenCLExtensions(*SemaPtr);
61506161
WriteCUDAPragmas(*SemaPtr);
6162+
WriteRISCVIntrinsicPragmas(*SemaPtr);
61516163
}
61526164

61536165
// If we're emitting a module, write out the submodule information.

clang/test/PCH/riscv-rvv-vectors.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
4+
5+
// Test precompiled header
6+
// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -emit-pch -o %t/test_pch.pch %t/test_pch.h
7+
// RUN: %clang_cc1 -triple riscv64-linux-gnu -target-feature +v -include-pch %t/test_pch.pch \
8+
// RUN: -fsyntax-only -verify %t/test_pch_src.c
9+
//
10+
// Test precompiled module(only available after C++20)
11+
// 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
12+
// 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
13+
// 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 \
14+
// RUN: -fsyntax-only %t/test_module_src.cpp
15+
16+
//--- test_pch.h
17+
// expected-no-diagnostics
18+
#include <riscv_vector.h>
19+
20+
//--- test_pch_src.c
21+
// expected-no-diagnostics
22+
vuint64m4_t v_add(vuint64m4_t a, vuint64m4_t b, size_t vl) {
23+
return __riscv_vadd_vv_u64m4(a, b, vl);
24+
}
25+
26+
//--- test_module1.h
27+
// expected-no-diagnostics
28+
#include <riscv_vector.h>
29+
30+
//--- test_module2.h
31+
// expected-no-diagnostics
32+
// empty header
33+
34+
//--- test_module_src.cpp
35+
// expected-no-diagnostics
36+
import "test_module1.h";
37+
import "test_module2.h";
38+
vuint64m4_t v_add(vuint64m4_t a, vuint64m4_t b, size_t vl) {
39+
return __riscv_vadd_vv_u64m4(a, b, vl);
40+
}

0 commit comments

Comments
 (0)