mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 19:08:21 +08:00
Most lowering patterns have exactly the same class declaration with different names and different `matchAndRewrite` implementations, yet their declaration occupies near 1000 lines of code in `LowerToLLVM.h`, making this file difficult to read and boring to maintain. In this patch, I migrate their declarations to be generated from `CIROps.td` using `clang-tblgen`. Some extra `CIR_Op` TableGen fields are introduced to help this: - The `CIR_Op` class now defines a `bit` field `hasLLVMLowering` which defaults to `true`. If its value is `true`, `clang-tblgen` would generate an LLVM lowering pattern declaration for the operation. - Some LLVM lowering patterns has bounded recursion. This could be enabled by setting the `isLLVMLoweringRecursive` field in a `CIR_Op` record to `true`. - Some LLVM lowering patterns have defined additional class members. They could be listed in the `extraLLVMLoweringPatternDecl` field. Note that in the incubator we have a similar TableGen code generator that generates LLVM lowering code for CIR builtin ops which has a one-to-one correspondence to LLVM dialect operations. This patch does NOT try to upstream it. Some additional noticeable changes made by this patch: - This patch adds the `dataLayout` member to every LLVM lowering pattern class to make the job easier for a code generator. In the future we might want to add more members to the lowering patterns, and we will need to update the code generator to make such changes.
126 lines
4.1 KiB
C++
126 lines
4.1 KiB
C++
//===-- CIRLoweringEmitter.cpp - Generate CIR lowering patterns -----------===//
|
|
//
|
|
// 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 TableGen backend emits CIR operation lowering patterns.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "TableGenBackends.h"
|
|
#include "llvm/TableGen/TableGenBackend.h"
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
using namespace llvm;
|
|
using namespace clang;
|
|
|
|
namespace {
|
|
std::vector<std::string> LLVMLoweringPatterns;
|
|
std::vector<std::string> LLVMLoweringPatternsList;
|
|
|
|
// Adapted from mlir/lib/TableGen/Operator.cpp
|
|
// Returns the C++ class name of the operation, which is the name of the
|
|
// operation with the dialect prefix removed and the first underscore removed.
|
|
// If the operation name starts with an underscore, the underscore is considered
|
|
// part of the class name.
|
|
std::string GetOpCppClassName(const Record *OpRecord) {
|
|
StringRef Name = OpRecord->getName();
|
|
StringRef Prefix;
|
|
StringRef CppClassName;
|
|
std::tie(Prefix, CppClassName) = Name.split('_');
|
|
if (Prefix.empty()) {
|
|
// Class name with a leading underscore and without dialect prefix
|
|
return Name.str();
|
|
}
|
|
if (CppClassName.empty()) {
|
|
// Class name without dialect prefix
|
|
return Prefix.str();
|
|
}
|
|
|
|
return CppClassName.str();
|
|
}
|
|
|
|
std::string GetOpLLVMLoweringPatternName(llvm::StringRef OpName) {
|
|
std::string Name = "CIRToLLVM";
|
|
Name += OpName;
|
|
Name += "Lowering";
|
|
return Name;
|
|
}
|
|
|
|
void GenerateLLVMLoweringPattern(llvm::StringRef OpName,
|
|
llvm::StringRef PatternName, bool IsRecursive,
|
|
llvm::StringRef ExtraDecl) {
|
|
std::string CodeBuffer;
|
|
llvm::raw_string_ostream Code(CodeBuffer);
|
|
|
|
Code << "class " << PatternName
|
|
<< " : public mlir::OpConversionPattern<cir::" << OpName << "> {\n";
|
|
Code << " [[maybe_unused]] mlir::DataLayout const &dataLayout;\n";
|
|
Code << "\n";
|
|
|
|
Code << "public:\n";
|
|
Code << " using mlir::OpConversionPattern<cir::" << OpName
|
|
<< ">::OpConversionPattern;\n";
|
|
|
|
Code << " " << PatternName
|
|
<< "(mlir::TypeConverter const "
|
|
"&typeConverter, mlir::MLIRContext *context, mlir::DataLayout const "
|
|
"&dataLayout)\n";
|
|
Code << " : OpConversionPattern<cir::" << OpName
|
|
<< ">(typeConverter, context), dataLayout(dataLayout)";
|
|
if (IsRecursive) {
|
|
Code << " {\n";
|
|
Code << " setHasBoundedRewriteRecursion();\n";
|
|
Code << " }\n";
|
|
} else {
|
|
Code << " {}\n";
|
|
}
|
|
|
|
Code << "\n";
|
|
|
|
Code << " mlir::LogicalResult matchAndRewrite(cir::" << OpName
|
|
<< " op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) "
|
|
"const override;\n";
|
|
|
|
if (!ExtraDecl.empty()) {
|
|
Code << "\nprivate:\n";
|
|
Code << ExtraDecl << "\n";
|
|
}
|
|
|
|
Code << "};\n";
|
|
|
|
LLVMLoweringPatterns.push_back(std::move(CodeBuffer));
|
|
}
|
|
|
|
void Generate(const Record *OpRecord) {
|
|
std::string OpName = GetOpCppClassName(OpRecord);
|
|
|
|
if (OpRecord->getValueAsBit("hasLLVMLowering")) {
|
|
std::string PatternName = GetOpLLVMLoweringPatternName(OpName);
|
|
bool IsRecursive = OpRecord->getValueAsBit("isLLVMLoweringRecursive");
|
|
llvm::StringRef ExtraDecl =
|
|
OpRecord->getValueAsString("extraLLVMLoweringPatternDecl");
|
|
|
|
GenerateLLVMLoweringPattern(OpName, PatternName, IsRecursive, ExtraDecl);
|
|
LLVMLoweringPatternsList.push_back(std::move(PatternName));
|
|
}
|
|
}
|
|
} // namespace
|
|
|
|
void clang::EmitCIRLowering(const llvm::RecordKeeper &RK,
|
|
llvm::raw_ostream &OS) {
|
|
emitSourceFileHeader("Lowering patterns for CIR operations", OS);
|
|
for (const auto *OpRecord : RK.getAllDerivedDefinitions("CIR_Op"))
|
|
Generate(OpRecord);
|
|
|
|
OS << "#ifdef GET_LLVM_LOWERING_PATTERNS\n"
|
|
<< llvm::join(LLVMLoweringPatterns, "\n") << "#endif\n\n";
|
|
OS << "#ifdef GET_LLVM_LOWERING_PATTERNS_LIST\n"
|
|
<< llvm::join(LLVMLoweringPatternsList, ",\n") << "\n#endif\n\n";
|
|
}
|