Skip to content

[RISCV][NFC] Make generated intrinsic records more human-readable #133710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion clang/include/clang/Support/RISCVVIntrinsicUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/Bitset.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <cstdint>
Expand Down Expand Up @@ -376,6 +377,8 @@ enum PolicyScheme : uint8_t {
HasPolicyOperand,
};

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, enum PolicyScheme PS);

// TODO refactor RVVIntrinsic class design after support all intrinsic
// combination. This represents an instantiation of an intrinsic with a
// particular type and prototype
Expand Down Expand Up @@ -507,6 +510,23 @@ enum RVVRequire {
RVV_REQ_NUM,
};

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, enum RVVRequire Require);

struct RequiredExtensions {
llvm::Bitset<RVV_REQ_NUM> Bits;
RequiredExtensions() {}
RequiredExtensions(std::initializer_list<RVVRequire> Init) {
for (auto I : Init)
Bits.set(I);
}

void set(unsigned I) { Bits.set(I); }
bool operator[](unsigned I) const { return Bits[I]; }
};

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const RequiredExtensions &Exts);

// Raw RVV intrinsic info, used to expand later.
// This struct is highly compact for minimized code size.
struct RVVIntrinsicRecord {
Expand All @@ -518,7 +538,7 @@ struct RVVIntrinsicRecord {
const char *OverloadedName;

// Required target features for this intrinsic.
uint32_t RequiredExtensions[(RVV_REQ_NUM + 31) / 32];
RequiredExtensions RequiredExtensions;

// Prototype for this intrinsic, index of RVVSignatureTable.
uint16_t PrototypeIndex;
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Sema/SemaRISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,7 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
for (auto &Record : Recs) {
// Check requirements.
if (llvm::any_of(FeatureCheckList, [&](const auto &Item) {
return ((Record.RequiredExtensions[Item.second / 32] &
(1U << (Item.second % 32))) != 0) &&
return Record.RequiredExtensions[Item.second] &&
!TI.hasFeature(Item.first);
}))
continue;
Expand Down
105 changes: 80 additions & 25 deletions clang/lib/Support/RISCVVIntrinsicUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1196,36 +1196,91 @@ SmallVector<PrototypeDescriptor> parsePrototypes(StringRef Prototypes) {
return PrototypeDescriptors;
}

#define STRINGIFY(NAME) \
case NAME: \
OS << #NAME; \
break;

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, enum PolicyScheme PS) {
switch (PS) {
STRINGIFY(SchemeNone)
STRINGIFY(HasPassthruOperand)
STRINGIFY(HasPolicyOperand)
}
return OS;
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, enum RVVRequire Require) {
switch (Require) {
STRINGIFY(RVV_REQ_RV64)
STRINGIFY(RVV_REQ_Zvfhmin)
STRINGIFY(RVV_REQ_Xsfvcp)
STRINGIFY(RVV_REQ_Xsfvfnrclipxfqf)
STRINGIFY(RVV_REQ_Xsfvfwmaccqqq)
STRINGIFY(RVV_REQ_Xsfvqmaccdod)
STRINGIFY(RVV_REQ_Xsfvqmaccqoq)
STRINGIFY(RVV_REQ_Zvbb)
STRINGIFY(RVV_REQ_Zvbc)
STRINGIFY(RVV_REQ_Zvkb)
STRINGIFY(RVV_REQ_Zvkg)
STRINGIFY(RVV_REQ_Zvkned)
STRINGIFY(RVV_REQ_Zvknha)
STRINGIFY(RVV_REQ_Zvknhb)
STRINGIFY(RVV_REQ_Zvksed)
STRINGIFY(RVV_REQ_Zvksh)
STRINGIFY(RVV_REQ_Zvfbfwma)
STRINGIFY(RVV_REQ_Zvfbfmin)
STRINGIFY(RVV_REQ_Zvfh)
STRINGIFY(RVV_REQ_Experimental)
default:
llvm_unreachable("Unsupported RVVRequire!");
break;
}
return OS;
}

#undef STRINGIFY

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const RequiredExtensions &Exts) {
OS << "{";
ListSeparator LS;
for (unsigned I = 0; I < RVV_REQ_NUM; I++)
if (Exts[I])
OS << LS << static_cast<RVVRequire>(I);
OS << "}";
return OS;
}

raw_ostream &operator<<(raw_ostream &OS, const RVVIntrinsicRecord &Record) {
OS << "{";
OS << "\"" << Record.Name << "\",";
OS << "/*Name=*/\"" << Record.Name << "\", ";
if (Record.OverloadedName == nullptr ||
StringRef(Record.OverloadedName).empty())
OS << "nullptr,";
OS << "/*OverloadedName=*/nullptr, ";
else
OS << "\"" << Record.OverloadedName << "\",";
OS << "{";
for (uint32_t Exts : Record.RequiredExtensions)
OS << Exts << ',';
OS << "},";
OS << Record.PrototypeIndex << ",";
OS << Record.SuffixIndex << ",";
OS << Record.OverloadedSuffixIndex << ",";
OS << (int)Record.PrototypeLength << ",";
OS << (int)Record.SuffixLength << ",";
OS << (int)Record.OverloadedSuffixSize << ",";
OS << (int)Record.TypeRangeMask << ",";
OS << (int)Record.Log2LMULMask << ",";
OS << (int)Record.NF << ",";
OS << (int)Record.HasMasked << ",";
OS << (int)Record.HasVL << ",";
OS << (int)Record.HasMaskedOffOperand << ",";
OS << (int)Record.HasTailPolicy << ",";
OS << (int)Record.HasMaskPolicy << ",";
OS << (int)Record.HasFRMRoundModeOp << ",";
OS << (int)Record.IsTuple << ",";
OS << (int)Record.UnMaskedPolicyScheme << ",";
OS << (int)Record.MaskedPolicyScheme << ",";
OS << "/*OverloadedName=*/\"" << Record.OverloadedName << "\", ";
OS << "/*RequiredExtensions=*/" << Record.RequiredExtensions << ", ";
OS << "/*PrototypeIndex=*/" << Record.PrototypeIndex << ", ";
OS << "/*SuffixIndex=*/" << Record.SuffixIndex << ", ";
OS << "/*OverloadedSuffixIndex=*/" << Record.OverloadedSuffixIndex << ", ";
OS << "/*PrototypeLength=*/" << (int)Record.PrototypeLength << ", ";
OS << "/*SuffixLength=*/" << (int)Record.SuffixLength << ", ";
OS << "/*OverloadedSuffixSize=*/" << (int)Record.OverloadedSuffixSize << ", ";
OS << "/*TypeRangeMask=*/" << (int)Record.TypeRangeMask << ", ";
OS << "/*Log2LMULMask=*/" << (int)Record.Log2LMULMask << ", ";
OS << "/*NF=*/" << (int)Record.NF << ", ";
OS << "/*HasMasked=*/" << (int)Record.HasMasked << ", ";
OS << "/*HasVL=*/" << (int)Record.HasVL << ", ";
OS << "/*HasMaskedOffOperand=*/" << (int)Record.HasMaskedOffOperand << ", ";
OS << "/*HasTailPolicy=*/" << (int)Record.HasTailPolicy << ", ";
OS << "/*HasMaskPolicy=*/" << (int)Record.HasMaskPolicy << ", ";
OS << "/*HasFRMRoundModeOp=*/" << (int)Record.HasFRMRoundModeOp << ", ";
OS << "/*IsTuple=*/" << (int)Record.IsTuple << ", ";
OS << "/*UnMaskedPolicyScheme=*/" << (PolicyScheme)Record.UnMaskedPolicyScheme
<< ", ";
OS << "/*MaskedPolicyScheme=*/" << (PolicyScheme)Record.MaskedPolicyScheme
<< ", ";
OS << "},\n";
return OS;
}
Expand Down
8 changes: 3 additions & 5 deletions clang/utils/TableGen/RISCVVEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct SemaRecord {
unsigned Log2LMULMask;

// Required extensions for this intrinsic.
uint32_t RequiredExtensions[(RVV_REQ_NUM + 31) / 32];
RequiredExtensions RequiredExtensions;

// Prototype for this intrinsic.
SmallVector<PrototypeDescriptor> Prototype;
Expand Down Expand Up @@ -769,7 +769,6 @@ void RVVEmitter::createRVVIntrinsics(

SR.Log2LMULMask = Log2LMULMask;

memset(SR.RequiredExtensions, 0, sizeof(SR.RequiredExtensions));
for (auto RequiredFeature : RequiredFeatures) {
unsigned RequireExt =
StringSwitch<RVVRequire>(RequiredFeature)
Expand All @@ -793,7 +792,7 @@ void RVVEmitter::createRVVIntrinsics(
.Case("Zvfbfmin", RVV_REQ_Zvfbfmin)
.Case("Zvfh", RVV_REQ_Zvfh)
.Case("Experimental", RVV_REQ_Experimental);
SR.RequiredExtensions[RequireExt / 32] |= 1U << (RequireExt % 32);
SR.RequiredExtensions.set(RequireExt);
}

SR.NF = NF;
Expand Down Expand Up @@ -837,8 +836,7 @@ void RVVEmitter::createRVVIntrinsicRecords(std::vector<RVVIntrinsicRecord> &Out,
R.PrototypeLength = SR.Prototype.size();
R.SuffixLength = SR.Suffix.size();
R.OverloadedSuffixSize = SR.OverloadedSuffix.size();
memcpy(R.RequiredExtensions, SR.RequiredExtensions,
sizeof(R.RequiredExtensions));
R.RequiredExtensions = SR.RequiredExtensions;
R.TypeRangeMask = SR.TypeRangeMask;
R.Log2LMULMask = SR.Log2LMULMask;
R.NF = SR.NF;
Expand Down
Loading