//===- LLVMIRConversionGen.cpp - MLIR LLVM IR builder generator -----------===// // // 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 uses tablegen definitions of the LLVM IR Dialect operations to // generate the code building the LLVM IR from it. // //===----------------------------------------------------------------------===// #include "mlir/TableGen/Argument.h" #include "mlir/TableGen/Attribute.h" #include "mlir/TableGen/GenInfo.h" #include "mlir/TableGen/Operator.h" #include "llvm/ADT/Sequence.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/TableGenBackend.h" usingnamespacellvm; usingnamespacemlir; static LogicalResult emitError(const Record &record, const Twine &message) { … } namespace { // Helper structure to return a position of the substring in a string. struct StringLoc { … }; } // namespace // Find the next TableGen variable in the given pattern. These variables start // with a `$` character and can contain alphanumeric characters or underscores. // Return the position of the variable in the pattern and its length, including // the `$` character. The escape syntax `$$` is also detected and returned. static StringLoc findNextVariable(StringRef str) { … } // Check if `name` is a variadic operand of `op`. Seach all operands since the // MLIR and LLVM IR operand order may differ and only for the latter the // variadic operand is guaranteed to be at the end of the operands list. static bool isVariadicOperandName(const tblgen::Operator &op, StringRef name) { … } // Check if `result` is a known name of a result of `op`. static bool isResultName(const tblgen::Operator &op, StringRef name) { … } // Check if `name` is a known name of an attribute of `op`. static bool isAttributeName(const tblgen::Operator &op, StringRef name) { … } // Check if `name` is a known name of an operand of `op`. static bool isOperandName(const tblgen::Operator &op, StringRef name) { … } // Return the `op` argument index of the argument with the given `name`. static FailureOr<int> getArgumentIndex(const tblgen::Operator &op, StringRef name) { … } // Emit to `os` the operator-name driven check and the call to LLVM IRBuilder // for one definition of an LLVM IR Dialect operation. static LogicalResult emitOneBuilder(const Record &record, raw_ostream &os) { … } // Emit all builders. Returns false on success because of the generator // registration requirements. static bool emitBuilders(const RecordKeeper &recordKeeper, raw_ostream &os) { … } ConditionFn; // Emit a conditional call to the MLIR builder of the LLVM dialect operation to // build for the given LLVM IR instruction. A condition function `conditionFn` // emits a check to verify the opcode or intrinsic identifier of the LLVM IR // instruction matches the LLVM dialect operation to build. static LogicalResult emitOneMLIRBuilder(const Record &record, raw_ostream &os, ConditionFn conditionFn) { … } // Emit all intrinsic MLIR builders. Returns false on success because of the // generator registration requirements. static bool emitIntrMLIRBuilders(const RecordKeeper &recordKeeper, raw_ostream &os) { … } // Emit all op builders. Returns false on success because of the // generator registration requirements. static bool emitOpMLIRBuilders(const RecordKeeper &recordKeeper, raw_ostream &os) { … } namespace { // Wrapper class around a Tablegen definition of an LLVM enum attribute case. class LLVMEnumAttrCase : public tblgen::EnumAttrCase { … }; // Wraper class around a Tablegen definition of an LLVM enum attribute. class LLVMEnumAttr : public tblgen::EnumAttr { … }; // Wraper class around a Tablegen definition of a C-style LLVM enum attribute. class LLVMCEnumAttr : public tblgen::EnumAttr { … }; } // namespace // Emits conversion function "LLVMClass convertEnumToLLVM(Enum)" and containing // switch-based logic to convert from the MLIR LLVM dialect enum attribute case // (Enum) to the corresponding LLVM API enumerant static void emitOneEnumToConversion(const llvm::Record *record, raw_ostream &os) { … } // Emits conversion function "LLVMClass convertEnumToLLVM(Enum)" and containing // switch-based logic to convert from the MLIR LLVM dialect enum attribute case // (Enum) to the corresponding LLVM API C-style enumerant static void emitOneCEnumToConversion(const llvm::Record *record, raw_ostream &os) { … } // Emits conversion function "Enum convertEnumFromLLVM(LLVMClass)" and // containing switch-based logic to convert from the LLVM API enumerant to MLIR // LLVM dialect enum attribute (Enum). static void emitOneEnumFromConversion(const llvm::Record *record, raw_ostream &os) { … } // Emits conversion function "Enum convertEnumFromLLVM(LLVMEnum)" and // containing switch-based logic to convert from the LLVM API C-style enumerant // to MLIR LLVM dialect enum attribute (Enum). static void emitOneCEnumFromConversion(const llvm::Record *record, raw_ostream &os) { … } // Emits conversion functions between MLIR enum attribute case and corresponding // LLVM API enumerants for all registered LLVM dialect enum attributes. template <bool ConvertTo> static bool emitEnumConversionDefs(const RecordKeeper &recordKeeper, raw_ostream &os) { … } static void emitOneIntrinsic(const Record &record, raw_ostream &os) { … } // Emit the list of LLVM IR intrinsics identifiers that are convertible to a // matching MLIR LLVM dialect intrinsic operation. static bool emitConvertibleIntrinsics(const RecordKeeper &recordKeeper, raw_ostream &os) { … } static mlir::GenRegistration genLLVMIRConversions("gen-llvmir-conversions", "Generate LLVM IR conversions", emitBuilders); static mlir::GenRegistration genOpFromLLVMIRConversions( "gen-op-from-llvmir-conversions", "Generate conversions of operations from LLVM IR", emitOpMLIRBuilders); static mlir::GenRegistration genIntrFromLLVMIRConversions( "gen-intr-from-llvmir-conversions", "Generate conversions of intrinsics from LLVM IR", emitIntrMLIRBuilders); static mlir::GenRegistration genEnumToLLVMConversion("gen-enum-to-llvmir-conversions", "Generate conversions of EnumAttrs to LLVM IR", emitEnumConversionDefs</*ConvertTo=*/true>); static mlir::GenRegistration genEnumFromLLVMConversion("gen-enum-from-llvmir-conversions", "Generate conversions of EnumAttrs from LLVM IR", emitEnumConversionDefs</*ConvertTo=*/false>); static mlir::GenRegistration genConvertibleLLVMIRIntrinsics( "gen-convertible-llvmir-intrinsics", "Generate list of convertible LLVM IR intrinsics", emitConvertibleIntrinsics);