Skip to content

Commit

Permalink
move all emitters to header
Browse files Browse the repository at this point in the history
  • Loading branch information
makslevental committed May 20, 2024
1 parent d75d60f commit 35f91b7
Show file tree
Hide file tree
Showing 33 changed files with 1,001 additions and 755 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ void WebAssemblyAsmPrinter::emitDecls(const Module &M) {
void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
// This is required to emit external declarations (like .functypes) when
// no functions are defined in the compilation unit and therefore,
// emitDecls() is not called until now.
// emitDirectiveDecls() is not called until now.
emitDecls(M);

// When a function's address is taken, a TABLE_INDEX relocation is emitted
Expand Down
62 changes: 62 additions & 0 deletions mlir/include/mlir/TableGen/AttrOrTypeDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "mlir/Support/LLVM.h"
#include "mlir/TableGen/Builder.h"
#include "mlir/TableGen/Trait.h"
#include "llvm/TableGen/Record.h"

namespace llvm {
class DagInit;
Expand Down Expand Up @@ -277,6 +278,67 @@ class TypeDef : public AttrOrTypeDef {
StringRef getTypeName() const;
};

//===----------------------------------------------------------------------===//
// DefGenerator
//===----------------------------------------------------------------------===//

/// This struct is the base generator used when processing tablegen interfaces.
class DefGenerator {
public:
bool emitDecls(StringRef selectedDialect);
bool emitDefs(StringRef selectedDialect);

protected:
DefGenerator(std::vector<llvm::Record *> &&defs, raw_ostream &os,
StringRef defType, StringRef valueType, bool isAttrGenerator,
bool formatErrorIsFatal)
: defRecords(std::move(defs)), os(os), defType(defType),
valueType(valueType), isAttrGenerator(isAttrGenerator),
formatErrorIsFatal(formatErrorIsFatal) {
// Sort by occurrence in file.
llvm::sort(defRecords, [](llvm::Record *lhs, llvm::Record *rhs) {
return lhs->getID() < rhs->getID();
});
}

/// Emit the list of def type names.
void emitTypeDefList(ArrayRef<AttrOrTypeDef> defs);
/// Emit the code to dispatch between different defs during parsing/printing.
void emitParsePrintDispatch(ArrayRef<AttrOrTypeDef> defs);

/// The set of def records to emit.
std::vector<llvm::Record *> defRecords;
/// The attribute or type class to emit.
/// The stream to emit to.
raw_ostream &os;
/// The prefix of the tablegen def name, e.g. Attr or Type.
StringRef defType;
/// The C++ base value type of the def, e.g. Attribute or Type.
StringRef valueType;
/// Flag indicating if this generator is for Attributes. False if the
/// generator is for types.
bool isAttrGenerator;
/// Whether a failure in parsing the assembly format should be a fatal error.
bool formatErrorIsFatal;
};

/// A specialized generator for AttrDefs.
struct AttrDefGenerator : public DefGenerator {
AttrDefGenerator(const llvm::RecordKeeper &records, raw_ostream &os,
bool formatErrorIsFatal)
: DefGenerator(records.getAllDerivedDefinitionsIfDefined("AttrDef"), os,
"Attr", "Attribute", /*isAttrGenerator=*/true,
formatErrorIsFatal) {}
};
/// A specialized generator for TypeDefs.
struct TypeDefGenerator : public DefGenerator {
TypeDefGenerator(const llvm::RecordKeeper &records, raw_ostream &os,
bool formatErrorIsFatal)
: DefGenerator(records.getAllDerivedDefinitionsIfDefined("TypeDef"), os,
"Type", "Type", /*isAttrGenerator=*/false,
formatErrorIsFatal) {}
};

} // namespace tblgen
} // namespace mlir

Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/TableGen/AttrOrTypeFormatGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class AttrOrTypeDef;
/// Generate a parser and printer based on a custom assembly format for an
/// attribute or type.
void generateAttrOrTypeFormat(const AttrOrTypeDef &def, MethodBody &parser,
MethodBody &printer);
MethodBody &printer, bool formatErrorIsFatal);

} // namespace tblgen
} // namespace mlir
Expand Down
5 changes: 4 additions & 1 deletion mlir/include/mlir/TableGen/DialectGenUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@
#define MLIR_TOOLS_MLIRTBLGEN_DIALECTGENUTILITIES_H_

#include "mlir/Support/LLVM.h"
#include "llvm/Support/CommandLine.h"

namespace mlir {
namespace tblgen {
class Dialect;

/// Find the dialect selected by the user to generate for. Returns std::nullopt
/// if no dialect was found, or if more than one potential dialect was found.
std::optional<Dialect> findDialectToGenerate(ArrayRef<Dialect> dialects);
std::optional<Dialect>
findDialectToGenerate(ArrayRef<Dialect> dialects,
const std::string &selectedDialect);
} // namespace tblgen
} // namespace mlir

Expand Down
3 changes: 0 additions & 3 deletions mlir/include/mlir/TableGen/FormatGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,9 +596,6 @@ bool canFormatStringAsKeyword(StringRef value,
bool isValidLiteral(StringRef value,
function_ref<void(Twine)> emitError = nullptr);

/// Whether a failure in parsing the assembly format should be a fatal error.
extern llvm::cl::opt<bool> formatErrorIsFatal;

} // namespace tblgen
} // namespace mlir

Expand Down
82 changes: 82 additions & 0 deletions mlir/include/mlir/TableGen/GenInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "mlir/Support/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
#include <functional>
#include <utility>

Expand Down Expand Up @@ -69,6 +70,87 @@ struct GenRegistration {
const GenFunction &function);
};

namespace tblgen {
bool emitBCRW(const llvm::RecordKeeper &records, raw_ostream &os,
const std::string &selectedBcDialect);

bool emitOpDecls(const llvm::RecordKeeper &recordKeeper, raw_ostream &os,
const std::string &opIncFilter, const std::string &opExcFilter,
unsigned opShardCount, bool formatErrorIsFatal);
bool emitOpDefs(const llvm::RecordKeeper &recordKeeper, raw_ostream &os,
const std::string &opIncFilter, const std::string &opExcFilter,
unsigned opShardCount, bool formatErrorIsFatal);

bool emitDialectDecls(const llvm::RecordKeeper &recordKeeper, raw_ostream &os,
const std::string &selectedDialect);
bool emitDialectDefs(const llvm::RecordKeeper &recordKeeper, raw_ostream &os,
const std::string &selectedDialect);
bool emitDirectiveDecls(const llvm::RecordKeeper &recordKeeper,
llvm::StringRef dialect, raw_ostream &os);

bool emitPythonEnums(const llvm::RecordKeeper &recordKeeper, raw_ostream &os);
bool emitAllPythonOps(const llvm::RecordKeeper &records, raw_ostream &os,
const std::string &clDialectName,
const std::string &clDialectExtensionName);

bool emitEnumDecls(const llvm::RecordKeeper &recordKeeper, raw_ostream &os);
bool emitEnumDefs(const llvm::RecordKeeper &recordKeeper, raw_ostream &os);

bool emitLLVMBuilders(const llvm::RecordKeeper &recordKeeper, raw_ostream &os);
bool emitLLVMOpMLIRBuilders(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
bool emitLLVMIntrMLIRBuilders(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
template <bool ConvertTo>
bool emitLLVMEnumConversionDefs(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
bool emitLLVMConvertibleIntrinsics(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
bool emitLLVMIntrinsics(const llvm::RecordKeeper &records,
llvm::raw_ostream &os, const std::string &nameFilter,
const std::string &accessGroupRegexp,
const std::string &aliasAnalysisRegexp,
const std::string &opBaseClass);

void emitAttrOrTypeDefDoc(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os, StringRef recordTypeName);
void emitOpDoc(const llvm::RecordKeeper &recordKeeper, raw_ostream &os,
const std::string &emitOpDoc, bool allowHugoSpecificFeatures,
const std::string &opIncFilter, const std::string &opExcFilter);
bool emitDialectDoc(const llvm::RecordKeeper &recordKeeper, raw_ostream &os,
const std::string &selectedDialect,
const std::string &opIncFilter,
const std::string &opExcFilter,
const std::string &stripPrefix,
bool allowHugoSpecificFeatures);
void emitDocs(const llvm::RecordKeeper &recordKeeper, raw_ostream &os);

bool emitCAPIHeader(const llvm::RecordKeeper &records, raw_ostream &os,
std::string groupPrefix);
bool emitCAPIImpl(const llvm::RecordKeeper &records, raw_ostream &os,
std::string groupPrefix);
void emitPasses(const llvm::RecordKeeper &recordKeeper, raw_ostream &os,
const std::string &opIncFilter, const std::string &groupName);
void emitRewriters(const llvm::RecordKeeper &recordKeeper, raw_ostream &os);

bool emitSPIRVInterfaceDefs(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
bool emitSPIRVInterfaceDecls(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
bool emitSPIRVEnumDecls(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
bool emitSPIRVEnumDefs(const llvm::RecordKeeper &recordKeeper, raw_ostream &os);
bool emitSPIRVCapabilityImplication(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
bool emitSPIRVSerializationFns(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
bool emitSPIRVAttrUtils(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);
bool emitSPIRVAvailabilityImpl(const llvm::RecordKeeper &recordKeeper,
raw_ostream &os);

} // namespace tblgen

} // namespace mlir

#endif // MLIR_TABLEGEN_GENINFO_H_
3 changes: 2 additions & 1 deletion mlir/include/mlir/TableGen/OpFormatGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class OpClass;
class Operator;

// Generate the assembly format for the given operator.
void generateOpFormat(const Operator &constOp, OpClass &opClass);
void generateOpFormat(const Operator &constOp, OpClass &opClass,
bool formatErrorIsFatal);

} // namespace tblgen
} // namespace mlir
Expand Down
7 changes: 5 additions & 2 deletions mlir/include/mlir/TableGen/OpGenHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ namespace tblgen {
/// Returns all the op definitions filtered by the user. The filtering is via
/// command-line option "op-include-regex" and "op-exclude-regex".
std::vector<llvm::Record *>
getRequestedOpDefinitions(const llvm::RecordKeeper &recordKeeper);
getRequestedOpDefinitions(const llvm::RecordKeeper &recordKeeper,
const std::string &opIncFilter,
const std::string &opExcFilter);

/// Checks whether `str` is a Python keyword or would shadow builtin function.
/// Regenerate using python -c"print(set(sorted(__import__('keyword').kwlist)))"
bool isPythonReserved(llvm::StringRef str);

/// Shard the op defintions into the number of shards set by "op-shard-count".
void shardOpDefinitions(ArrayRef<llvm::Record *> defs,
SmallVectorImpl<ArrayRef<llvm::Record *>> &shardedDefs);
SmallVectorImpl<ArrayRef<llvm::Record *>> &shardedDefs,
unsigned shardOpDefinitions);

} // namespace tblgen
} // namespace mlir
Expand Down
142 changes: 142 additions & 0 deletions mlir/include/mlir/TableGen/OpInterfacesGen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//===- OpInterfacesGen.h - MLIR operation generator helpers -----*- 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 helpers used in the op interface generators.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TOOLS_MLIRTBLGEN_OPINTERFACESGEN_H_
#define MLIR_TOOLS_MLIRTBLGEN_OPINTERFACESGEN_H_

#include "mlir/Support/LLVM.h"
#include "mlir/TableGen/Format.h"
#include "mlir/TableGen/GenInfo.h"
#include "mlir/TableGen/Interfaces.h"
#include "llvm/TableGen/Record.h"
#include <vector>

namespace mlir {
namespace tblgen {

template <typename GeneratorT>
struct InterfaceGenRegistration {
InterfaceGenRegistration(StringRef genArg, StringRef genDesc)
: genDeclArg(("gen-" + genArg + "-interface-decls").str()),
genDefArg(("gen-" + genArg + "-interface-defs").str()),
genDocArg(("gen-" + genArg + "-interface-docs").str()),
genDeclDesc(("Generate " + genDesc + " interface declarations").str()),
genDefDesc(("Generate " + genDesc + " interface definitions").str()),
genDocDesc(("Generate " + genDesc + " interface documentation").str()),
genDecls(genDeclArg, genDeclDesc,
[](const llvm::RecordKeeper &records, raw_ostream &os) {
return GeneratorT(records, os).emitInterfaceDecls();
}),
genDefs(genDefArg, genDefDesc,
[](const llvm::RecordKeeper &records, raw_ostream &os) {
return GeneratorT(records, os).emitInterfaceDefs();
}),
genDocs(genDocArg, genDocDesc,
[](const llvm::RecordKeeper &records, raw_ostream &os) {
return GeneratorT(records, os).emitInterfaceDocs();
}) {}

std::string genDeclArg, genDefArg, genDocArg;
std::string genDeclDesc, genDefDesc, genDocDesc;
mlir::GenRegistration genDecls, genDefs, genDocs;
};

/// This struct is the base generator used when processing tablegen interfaces.
class InterfaceGenerator {
public:
bool emitInterfaceDefs();
bool emitInterfaceDecls();
bool emitInterfaceDocs();

protected:
InterfaceGenerator(std::vector<llvm::Record *> &&defs, raw_ostream &os)
: defs(std::move(defs)), os(os) {}

void emitConceptDecl(const Interface &interface);
void emitModelDecl(const Interface &interface);
void emitModelMethodsDef(const Interface &interface);
void emitTraitDecl(const Interface &interface, StringRef interfaceName,
StringRef interfaceTraitsName);
void emitInterfaceDecl(const Interface &interface);

/// The set of interface records to emit.
std::vector<llvm::Record *> defs;
// The stream to emit to.
raw_ostream &os;
/// The C++ value type of the interface, e.g. Operation*.
StringRef valueType;
/// The C++ base interface type.
StringRef interfaceBaseType;
/// The name of the typename for the value template.
StringRef valueTemplate;
/// The name of the substituion variable for the value.
StringRef substVar;
/// The format context to use for methods.
tblgen::FmtContext nonStaticMethodFmt;
tblgen::FmtContext traitMethodFmt;
tblgen::FmtContext extraDeclsFmt;
};

std::vector<llvm::Record *>
getAllInterfaceDefinitions(const llvm::RecordKeeper &recordKeeper,
StringRef name);

/// A specialized generator for attribute interfaces.
struct AttrInterfaceGenerator : public InterfaceGenerator {
AttrInterfaceGenerator(const llvm::RecordKeeper &records, raw_ostream &os)
: InterfaceGenerator(getAllInterfaceDefinitions(records, "Attr"), os) {
valueType = "::mlir::Attribute";
interfaceBaseType = "AttributeInterface";
valueTemplate = "ConcreteAttr";
substVar = "_attr";
StringRef castCode = "(::llvm::cast<ConcreteAttr>(tablegen_opaque_val))";
nonStaticMethodFmt.addSubst(substVar, castCode).withSelf(castCode);
traitMethodFmt.addSubst(substVar,
"(*static_cast<const ConcreteAttr *>(this))");
extraDeclsFmt.addSubst(substVar, "(*this)");
}
};
/// A specialized generator for operation interfaces.
struct OpInterfaceGenerator : public InterfaceGenerator {
OpInterfaceGenerator(const llvm::RecordKeeper &records, raw_ostream &os)
: InterfaceGenerator(getAllInterfaceDefinitions(records, "Op"), os) {
valueType = "::mlir::Operation *";
interfaceBaseType = "OpInterface";
valueTemplate = "ConcreteOp";
substVar = "_op";
StringRef castCode = "(llvm::cast<ConcreteOp>(tablegen_opaque_val))";
nonStaticMethodFmt.addSubst("_this", "impl")
.addSubst(substVar, castCode)
.withSelf(castCode);
traitMethodFmt.addSubst(substVar, "(*static_cast<ConcreteOp *>(this))");
extraDeclsFmt.addSubst(substVar, "(*this)");
}
};
/// A specialized generator for type interfaces.
struct TypeInterfaceGenerator : public InterfaceGenerator {
TypeInterfaceGenerator(const llvm::RecordKeeper &records, raw_ostream &os)
: InterfaceGenerator(getAllInterfaceDefinitions(records, "Type"), os) {
valueType = "::mlir::Type";
interfaceBaseType = "TypeInterface";
valueTemplate = "ConcreteType";
substVar = "_type";
StringRef castCode = "(::llvm::cast<ConcreteType>(tablegen_opaque_val))";
nonStaticMethodFmt.addSubst(substVar, castCode).withSelf(castCode);
traitMethodFmt.addSubst(substVar,
"(*static_cast<const ConcreteType *>(this))");
extraDeclsFmt.addSubst(substVar, "(*this)");
}
};
} // namespace tblgen
} // namespace mlir

#endif // MLIR_TOOLS_MLIRTBLGEN_OPINTERFACESGEN_H_
Loading

0 comments on commit 35f91b7

Please sign in to comment.