[CIR][NFC] Use tablegen to create CIRAttrToValue visitor declarations (#187607)
This change introduces TableGen support for indicating CIR attributes that require a CIRAttrToValue visitor, adds the new flag to all attributes to which it applies, and replaces the explicit declarations with the tablegen output.
This commit is contained in:
parent
94875aea7e
commit
511a7aacee
@ -34,11 +34,24 @@ class CIR_Attr<string name, string attrMnemonic, list<Trait> traits = []>
|
||||
// not be set to 0 if this type has any ability to have a 'record' type,
|
||||
// member type, or method type.
|
||||
bit canHaveIllegalCXXABIType = 1;
|
||||
|
||||
// When set, clang-tblgen includes this attribute in the DirectToLLVM
|
||||
// `CIRAttrToValue` TypeSwitch and emits a `visitCirAttr` declaration;
|
||||
// a matching definition must exist in LowerToLLVM.cpp.
|
||||
bit hasAttrToValueLowering = 0;
|
||||
}
|
||||
|
||||
class CIR_ValueLikeAttr<string name, string attrMnemonic,
|
||||
list<Trait> traits = []>
|
||||
: CIR_Attr<name, attrMnemonic, !listconcat(traits, [TypedAttrInterface])> {
|
||||
// Most CIR attributes that can be lowered to an LLVM constant will be lowered
|
||||
// to that constant during the LowerToLLVM pass. Those that don't should
|
||||
// override this setting.
|
||||
let hasAttrToValueLowering = 1;
|
||||
}
|
||||
|
||||
class CIR_TypedAttr<string name, string attrMnemonic, list<Trait> traits = []>
|
||||
: CIR_Attr<name, attrMnemonic, !listconcat(traits, [TypedAttrInterface])> {
|
||||
|
||||
: CIR_ValueLikeAttr<name, attrMnemonic, traits> {
|
||||
let parameters = (ins AttributeSelfTypeParameter<"">:$type);
|
||||
|
||||
let builders = [
|
||||
@ -150,7 +163,7 @@ def CIR_OptInfoAttr : CIR_Attr<"OptInfo", "opt_info"> {
|
||||
// BoolAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_BoolAttr : CIR_Attr<"Bool", "bool", [TypedAttrInterface]> {
|
||||
def CIR_BoolAttr : CIR_ValueLikeAttr<"Bool", "bool", [TypedAttrInterface]> {
|
||||
let summary = "Represent true/false for !cir.bool types";
|
||||
let description = [{
|
||||
The BoolAttr represents a 'true' or 'false' value.
|
||||
@ -211,7 +224,7 @@ def CIR_PoisonAttr : CIR_TypedAttr<"Poison", "poison"> {
|
||||
// IntegerAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_IntAttr : CIR_Attr<"Int", "int", [TypedAttrInterface]> {
|
||||
def CIR_IntAttr : CIR_ValueLikeAttr<"Int", "int"> {
|
||||
let summary = "An attribute containing an integer value";
|
||||
let description = [{
|
||||
An integer attribute is a literal attribute that represents an integral
|
||||
@ -279,7 +292,7 @@ def CIR_IntAttr : CIR_Attr<"Int", "int", [TypedAttrInterface]> {
|
||||
// FPAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_FPAttr : CIR_Attr<"FP", "fp", [TypedAttrInterface]> {
|
||||
def CIR_FPAttr : CIR_ValueLikeAttr<"FP", "fp"> {
|
||||
let summary = "An attribute containing a floating-point value";
|
||||
let description = [{
|
||||
An fp attribute is a literal attribute that represents a floating-point
|
||||
@ -315,9 +328,7 @@ def CIR_FPAttr : CIR_Attr<"FP", "fp", [TypedAttrInterface]> {
|
||||
// ConstArrayAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_ConstArrayAttr : CIR_Attr<"ConstArray", "const_array", [
|
||||
TypedAttrInterface
|
||||
]> {
|
||||
def CIR_ConstArrayAttr : CIR_ValueLikeAttr<"ConstArray", "const_array"> {
|
||||
let summary = "A constant array from ArrayAttr or StringRefAttr";
|
||||
let description = [{
|
||||
An CIR array attribute is an array of literals of the specified attr types.
|
||||
@ -363,9 +374,7 @@ def CIR_ConstArrayAttr : CIR_Attr<"ConstArray", "const_array", [
|
||||
// ConstVectorAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_ConstVectorAttr : CIR_Attr<"ConstVector", "const_vector", [
|
||||
TypedAttrInterface
|
||||
]> {
|
||||
def CIR_ConstVectorAttr : CIR_ValueLikeAttr<"ConstVector", "const_vector"> {
|
||||
let summary = "A constant vector from ArrayAttr";
|
||||
let description = [{
|
||||
A CIR vector attribute is an array of literals of the specified attribute
|
||||
@ -397,9 +406,7 @@ def CIR_ConstVectorAttr : CIR_Attr<"ConstVector", "const_vector", [
|
||||
// ConstRecordAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_ConstRecordAttr : CIR_Attr<"ConstRecord", "const_record", [
|
||||
TypedAttrInterface
|
||||
]> {
|
||||
def CIR_ConstRecordAttr : CIR_ValueLikeAttr<"ConstRecord", "const_record"> {
|
||||
let summary = "Represents a constant record";
|
||||
let description = [{
|
||||
Effectively supports "struct-like" constants. It's must be built from
|
||||
@ -435,7 +442,7 @@ def CIR_ConstRecordAttr : CIR_Attr<"ConstRecord", "const_record", [
|
||||
// ConstPtrAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> {
|
||||
def CIR_ConstPtrAttr : CIR_ValueLikeAttr<"ConstPtr", "ptr"> {
|
||||
let summary = "Holds a constant pointer value";
|
||||
let parameters = (ins
|
||||
AttributeSelfTypeParameter<"", "::cir::PointerType">:$type,
|
||||
@ -464,9 +471,7 @@ def CIR_ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> {
|
||||
// DataMemberAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_DataMemberAttr : CIR_Attr<"DataMember", "data_member", [
|
||||
TypedAttrInterface
|
||||
]> {
|
||||
def CIR_DataMemberAttr : CIR_ValueLikeAttr<"DataMember", "data_member"> {
|
||||
let summary = "Holds a constant data member pointer value";
|
||||
let parameters = (ins AttributeSelfTypeParameter<
|
||||
"", "cir::DataMemberType">:$type,
|
||||
@ -498,6 +503,9 @@ def CIR_DataMemberAttr : CIR_Attr<"DataMember", "data_member", [
|
||||
}]>,
|
||||
];
|
||||
|
||||
// This attribute gets lowered during CXXABILowering
|
||||
let hasAttrToValueLowering = 0;
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
|
||||
let assemblyFormat = [{
|
||||
@ -515,7 +523,7 @@ def CIR_DataMemberAttr : CIR_Attr<"DataMember", "data_member", [
|
||||
// MethodAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_MethodAttr : CIR_Attr<"Method", "method", [TypedAttrInterface]> {
|
||||
def CIR_MethodAttr : CIR_ValueLikeAttr<"Method", "method"> {
|
||||
let summary = "Holds a constant pointer-to-member-function value";
|
||||
let description = [{
|
||||
A method attribute is a literal attribute that represents a constant
|
||||
@ -568,6 +576,9 @@ def CIR_MethodAttr : CIR_Attr<"Method", "method", [TypedAttrInterface]> {
|
||||
}]>,
|
||||
];
|
||||
|
||||
// This attribute gets lowered during CXXABILowering
|
||||
let hasAttrToValueLowering = 0;
|
||||
|
||||
let hasCustomAssemblyFormat = 1;
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
@ -671,9 +682,7 @@ def CIR_CmpThreeWayInfoAttr : CIR_Attr<"CmpThreeWayInfo", "cmp3way_info"> {
|
||||
// GlobalViewAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_GlobalViewAttr : CIR_Attr<"GlobalView", "global_view", [
|
||||
TypedAttrInterface
|
||||
]> {
|
||||
def CIR_GlobalViewAttr : CIR_ValueLikeAttr<"GlobalView", "global_view"> {
|
||||
let summary = "Provides constant access to a global address";
|
||||
let description = [{
|
||||
Get constant address of global `symbol` and optionally apply offsets to
|
||||
@ -759,7 +768,7 @@ def CIR_GlobalViewAttr : CIR_Attr<"GlobalView", "global_view", [
|
||||
// VTableAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_VTableAttr : CIR_Attr<"VTable", "vtable", [TypedAttrInterface]> {
|
||||
def CIR_VTableAttr : CIR_ValueLikeAttr<"VTable", "vtable"> {
|
||||
let summary = "Represents a C++ vtable";
|
||||
let description = [{
|
||||
Wraps a #cir.const_record containing one or more vtable arrays.
|
||||
@ -958,9 +967,7 @@ def CIR_TargetAddressSpaceAttr : CIR_Attr< "TargetAddressSpace",
|
||||
// ConstComplexAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex", [
|
||||
TypedAttrInterface
|
||||
]> {
|
||||
def CIR_ConstComplexAttr : CIR_ValueLikeAttr<"ConstComplex", "const_complex"> {
|
||||
let summary = "An attribute that contains a constant complex value";
|
||||
let description = [{
|
||||
The `#cir.const_complex` attribute contains a constant value of complex
|
||||
@ -1306,7 +1313,7 @@ def CIR_AddressPointAttr : CIR_Attr<"AddressPoint", "address_point"> {
|
||||
// TypeInfoAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CIR_TypeInfoAttr : CIR_Attr<"TypeInfo", "typeinfo", [TypedAttrInterface]> {
|
||||
def CIR_TypeInfoAttr : CIR_ValueLikeAttr<"TypeInfo", "typeinfo"> {
|
||||
let summary = "Represents a typeinfo used for RTTI";
|
||||
let description = [{
|
||||
The typeinfo data for a given class is stored into an ArrayAttr. The
|
||||
|
||||
@ -10,6 +10,7 @@ add_clang_library(clangCIRLoweringDirectToLLVM
|
||||
LowerToLLVMIR.cpp
|
||||
|
||||
DEPENDS
|
||||
CIRLowering
|
||||
MLIRCIREnumsGen
|
||||
MLIRCIROpsIncGen
|
||||
MLIRCIROpInterfacesIncGen
|
||||
|
||||
@ -263,30 +263,9 @@ public:
|
||||
const mlir::TypeConverter *converter)
|
||||
: parentOp(parentOp), rewriter(rewriter), converter(converter) {}
|
||||
|
||||
mlir::Value visit(mlir::Attribute attr) {
|
||||
return llvm::TypeSwitch<mlir::Attribute, mlir::Value>(attr)
|
||||
.Case<cir::BoolAttr, cir::IntAttr, cir::FPAttr, cir::ConstComplexAttr,
|
||||
cir::ConstArrayAttr, cir::ConstRecordAttr, cir::ConstVectorAttr,
|
||||
cir::ConstPtrAttr, cir::GlobalViewAttr, cir::TypeInfoAttr,
|
||||
cir::UndefAttr, cir::PoisonAttr, cir::VTableAttr, cir::ZeroAttr>(
|
||||
[&](auto attrT) { return visitCirAttr(attrT); })
|
||||
.Default([&](auto attrT) { return mlir::Value(); });
|
||||
}
|
||||
|
||||
mlir::Value visitCirAttr(cir::BoolAttr boolAttr);
|
||||
mlir::Value visitCirAttr(cir::IntAttr intAttr);
|
||||
mlir::Value visitCirAttr(cir::FPAttr fltAttr);
|
||||
mlir::Value visitCirAttr(cir::ConstComplexAttr complexAttr);
|
||||
mlir::Value visitCirAttr(cir::ConstPtrAttr ptrAttr);
|
||||
mlir::Value visitCirAttr(cir::ConstArrayAttr attr);
|
||||
mlir::Value visitCirAttr(cir::ConstRecordAttr attr);
|
||||
mlir::Value visitCirAttr(cir::ConstVectorAttr attr);
|
||||
mlir::Value visitCirAttr(cir::GlobalViewAttr attr);
|
||||
mlir::Value visitCirAttr(cir::TypeInfoAttr attr);
|
||||
mlir::Value visitCirAttr(cir::UndefAttr attr);
|
||||
mlir::Value visitCirAttr(cir::PoisonAttr attr);
|
||||
mlir::Value visitCirAttr(cir::VTableAttr attr);
|
||||
mlir::Value visitCirAttr(cir::ZeroAttr attr);
|
||||
#define GET_CIR_ATTR_TO_VALUE_VISITOR_DECLS
|
||||
#include "clang/CIR/Dialect/IR/CIRLowering.inc"
|
||||
#undef GET_CIR_ATTR_TO_VALUE_VISITOR_DECLS
|
||||
|
||||
private:
|
||||
mlir::Operation *parentOp;
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
!s32i = !cir.int<s, 32>
|
||||
|
||||
module {
|
||||
cir.global external @poison_array = #cir.const_array<[#cir.poison : !s32i, #cir.poison : !s32i, #cir.poison : !s32i]> : !cir.array<!s32i x 3>
|
||||
|
||||
// LLVM: @poison_array = global [3 x i32] poison
|
||||
|
||||
cir.func @lower_poison() -> !s32i {
|
||||
%0 = cir.const #cir.poison : !s32i
|
||||
cir.return %0 : !s32i
|
||||
|
||||
@ -27,6 +27,9 @@ std::vector<std::string> CXXABILoweringPatternsList;
|
||||
std::vector<std::string> CXXABILoweringAttrAlwaysLegal;
|
||||
std::vector<std::string> LLVMLoweringPatterns;
|
||||
std::vector<std::string> LLVMLoweringPatternsList;
|
||||
std::string CIRAttrToValueVisitFunc;
|
||||
std::vector<std::string> CIRAttrToValueVisitorCaseTypes;
|
||||
std::vector<std::string> CIRAttrToValueVisitorDecls;
|
||||
|
||||
struct CustomLoweringCtor {
|
||||
struct Param {
|
||||
@ -249,10 +252,47 @@ void GenerateCIREnumAttrs(const Record *Record) {
|
||||
// they never have an 'illegal' CXXABI type in them.
|
||||
CXXABILoweringAttrAlwaysLegal.push_back("cir::" + OpName);
|
||||
}
|
||||
|
||||
void GenerateAttrToValueVisitor(const Record *Rec) {
|
||||
const Record *DialectRec = Rec->getValueAsDef("dialect");
|
||||
llvm::StringRef Ns = DialectRec->getValueAsString("cppNamespace");
|
||||
Ns.consume_front("::");
|
||||
std::string CppClassRef = Ns.str();
|
||||
CppClassRef += "::";
|
||||
CppClassRef += Rec->getValueAsString("cppClassName");
|
||||
|
||||
std::string CodeBuffer;
|
||||
llvm::raw_string_ostream Code(CodeBuffer);
|
||||
Code << " mlir::Value visitCirAttr(" << CppClassRef << " attr);";
|
||||
CIRAttrToValueVisitorDecls.push_back(std::move(CodeBuffer));
|
||||
CIRAttrToValueVisitorCaseTypes.push_back(std::move(CppClassRef));
|
||||
}
|
||||
|
||||
void GenerateAttrToValueVisitFunc() {
|
||||
std::string CodeBuffer;
|
||||
llvm::raw_string_ostream Code(CodeBuffer);
|
||||
Code << " mlir::Value visit(mlir::Attribute attr) {\n"
|
||||
<< " return llvm::TypeSwitch<mlir::Attribute, mlir::Value>(attr)\n"
|
||||
<< " .Case<\n "
|
||||
<< llvm::join(CIRAttrToValueVisitorCaseTypes, ",\n ")
|
||||
<< ">(\n"
|
||||
<< " [&](auto attrT) { return visitCirAttr(attrT); })\n"
|
||||
<< " .Default([this](mlir::Attribute attr) {\n"
|
||||
<< " mlir::emitError(parentOp->getLoc(), \"unsupported CIR "
|
||||
"attribute in LLVM constant lowering\")\n"
|
||||
<< " << attr;\n"
|
||||
<< " return mlir::Value();\n"
|
||||
<< " });\n"
|
||||
<< " }\n";
|
||||
CIRAttrToValueVisitFunc = std::move(CodeBuffer);
|
||||
}
|
||||
|
||||
void GenerateCIRAttrs(const Record *Record) {
|
||||
std::string OpName = GetOpCppClassName(Record);
|
||||
if (!Record->getValueAsBit("canHaveIllegalCXXABIType"))
|
||||
CXXABILoweringAttrAlwaysLegal.push_back("cir::" + OpName);
|
||||
if (Record->getValueAsBit("hasAttrToValueLowering"))
|
||||
GenerateAttrToValueVisitor(Record);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@ -265,6 +305,12 @@ void clang::EmitCIRLowering(const llvm::RecordKeeper &RK,
|
||||
GenerateCIREnumAttrs(OpRecord);
|
||||
for (const auto *OpRecord : RK.getAllDerivedDefinitions("CIR_Attr"))
|
||||
GenerateCIRAttrs(OpRecord);
|
||||
GenerateAttrToValueVisitFunc();
|
||||
|
||||
OS << "#ifdef GET_CIR_ATTR_TO_VALUE_VISITOR_DECLS\n"
|
||||
<< CIRAttrToValueVisitFunc << "\n"
|
||||
<< llvm::join(CIRAttrToValueVisitorDecls, "\n") << "\n"
|
||||
<< "#endif // GET_CIR_ATTR_TO_VALUE_VISITOR_DECLS\n\n";
|
||||
|
||||
OS << "#ifdef GET_ABI_LOWERING_PATTERNS\n"
|
||||
<< llvm::join(CXXABILoweringPatterns, "\n") << "#endif\n\n";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user