126 lines · cpp
1//===-- CIRLoweringEmitter.cpp - Generate CIR lowering patterns -----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This TableGen backend emits CIR operation lowering patterns.10//11//===----------------------------------------------------------------------===//12 13#include "TableGenBackends.h"14#include "llvm/TableGen/TableGenBackend.h"15#include <string>16#include <utility>17#include <vector>18 19using namespace llvm;20using namespace clang;21 22namespace {23std::vector<std::string> LLVMLoweringPatterns;24std::vector<std::string> LLVMLoweringPatternsList;25 26// Adapted from mlir/lib/TableGen/Operator.cpp27// Returns the C++ class name of the operation, which is the name of the28// operation with the dialect prefix removed and the first underscore removed.29// If the operation name starts with an underscore, the underscore is considered30// part of the class name.31std::string GetOpCppClassName(const Record *OpRecord) {32 StringRef Name = OpRecord->getName();33 StringRef Prefix;34 StringRef CppClassName;35 std::tie(Prefix, CppClassName) = Name.split('_');36 if (Prefix.empty()) {37 // Class name with a leading underscore and without dialect prefix38 return Name.str();39 }40 if (CppClassName.empty()) {41 // Class name without dialect prefix42 return Prefix.str();43 }44 45 return CppClassName.str();46}47 48std::string GetOpLLVMLoweringPatternName(llvm::StringRef OpName) {49 std::string Name = "CIRToLLVM";50 Name += OpName;51 Name += "Lowering";52 return Name;53}54 55void GenerateLLVMLoweringPattern(llvm::StringRef OpName,56 llvm::StringRef PatternName, bool IsRecursive,57 llvm::StringRef ExtraDecl) {58 std::string CodeBuffer;59 llvm::raw_string_ostream Code(CodeBuffer);60 61 Code << "class " << PatternName62 << " : public mlir::OpConversionPattern<cir::" << OpName << "> {\n";63 Code << " [[maybe_unused]] mlir::DataLayout const &dataLayout;\n";64 Code << "\n";65 66 Code << "public:\n";67 Code << " using mlir::OpConversionPattern<cir::" << OpName68 << ">::OpConversionPattern;\n";69 70 Code << " " << PatternName71 << "(mlir::TypeConverter const "72 "&typeConverter, mlir::MLIRContext *context, mlir::DataLayout const "73 "&dataLayout)\n";74 Code << " : OpConversionPattern<cir::" << OpName75 << ">(typeConverter, context), dataLayout(dataLayout)";76 if (IsRecursive) {77 Code << " {\n";78 Code << " setHasBoundedRewriteRecursion();\n";79 Code << " }\n";80 } else {81 Code << " {}\n";82 }83 84 Code << "\n";85 86 Code << " mlir::LogicalResult matchAndRewrite(cir::" << OpName87 << " op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) "88 "const override;\n";89 90 if (!ExtraDecl.empty()) {91 Code << "\nprivate:\n";92 Code << ExtraDecl << "\n";93 }94 95 Code << "};\n";96 97 LLVMLoweringPatterns.push_back(std::move(CodeBuffer));98}99 100void Generate(const Record *OpRecord) {101 std::string OpName = GetOpCppClassName(OpRecord);102 103 if (OpRecord->getValueAsBit("hasLLVMLowering")) {104 std::string PatternName = GetOpLLVMLoweringPatternName(OpName);105 bool IsRecursive = OpRecord->getValueAsBit("isLLVMLoweringRecursive");106 llvm::StringRef ExtraDecl =107 OpRecord->getValueAsString("extraLLVMLoweringPatternDecl");108 109 GenerateLLVMLoweringPattern(OpName, PatternName, IsRecursive, ExtraDecl);110 LLVMLoweringPatternsList.push_back(std::move(PatternName));111 }112}113} // namespace114 115void clang::EmitCIRLowering(const llvm::RecordKeeper &RK,116 llvm::raw_ostream &OS) {117 emitSourceFileHeader("Lowering patterns for CIR operations", OS);118 for (const auto *OpRecord : RK.getAllDerivedDefinitions("CIR_Op"))119 Generate(OpRecord);120 121 OS << "#ifdef GET_LLVM_LOWERING_PATTERNS\n"122 << llvm::join(LLVMLoweringPatterns, "\n") << "#endif\n\n";123 OS << "#ifdef GET_LLVM_LOWERING_PATTERNS_LIST\n"124 << llvm::join(LLVMLoweringPatternsList, ",\n") << "\n#endif\n\n";125}126