MLIR 23.0.0git
LLVMImportInterface.h
Go to the documentation of this file.
1//===- LLVMImportInterface.h - Import from LLVM interface -------*- C++ -*-===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This header file defines dialect interfaces for the LLVM IR import.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef MLIR_TARGET_LLVMIR_LLVMIMPORTINTERFACE_H
14#define MLIR_TARGET_LLVMIR_LLVMIMPORTINTERFACE_H
15
17#include "mlir/IR/Builders.h"
19#include "mlir/IR/Diagnostics.h"
21#include "mlir/IR/Location.h"
22#include "llvm/IR/Instruction.h"
23#include "llvm/IR/Instructions.h"
24#include "llvm/Support/FormatVariadic.h"
25
26namespace llvm {
27class IRBuilderBase;
28} // namespace llvm
29
30namespace mlir {
31namespace LLVM {
32class ModuleImport;
33} // namespace LLVM
34} // namespace mlir
35
36#include "mlir/Target/LLVMIR/LLVMImportDialectInterface.h.inc"
37
38namespace mlir {
39/// Interface collection for the import of LLVM IR that dispatches to a concrete
40/// dialect interface implementation. Queries the dialect interfaces to obtain a
41/// list of the supported LLVM IR constructs and then builds a mapping for the
42/// efficient dispatch.
44 : public DialectInterfaceCollection<LLVMImportDialectInterface> {
45public:
46 using Base::Base;
47
48 /// Queries all registered dialect interfaces for the supported LLVM IR
49 /// intrinsic and metadata kinds and builds the dispatch tables for the
50 /// conversion. Returns failure if multiple dialect interfaces translate the
51 /// same LLVM IR intrinsic.
52 LogicalResult initializeImport(llvm::LLVMContext &llvmContext) {
53 for (const LLVMImportDialectInterface &iface : *this) {
54 // Verify the supported intrinsics have not been mapped before.
55 const auto *intrinsicIt =
56 llvm::find_if(iface.getSupportedIntrinsics(), [&](unsigned id) {
57 return intrinsicToDialect.count(id);
58 });
59 if (intrinsicIt != iface.getSupportedIntrinsics().end()) {
60 return emitError(
61 UnknownLoc::get(iface.getContext()),
62 llvm::formatv(
63 "expected unique conversion for intrinsic ({0}), but "
64 "got conflicting {1} and {2} conversions",
65 *intrinsicIt, iface.getDialect()->getNamespace(),
66 intrinsicToDialect.lookup(*intrinsicIt)->getNamespace()));
67 }
68 const auto *instructionIt =
69 llvm::find_if(iface.getSupportedInstructions(), [&](unsigned id) {
70 return instructionToDialect.count(id);
71 });
72 if (instructionIt != iface.getSupportedInstructions().end()) {
73 return emitError(
74 UnknownLoc::get(iface.getContext()),
75 llvm::formatv(
76 "expected unique conversion for instruction ({0}), but "
77 "got conflicting {1} and {2} conversions",
78 *intrinsicIt, iface.getDialect()->getNamespace(),
79 instructionToDialect.lookup(*intrinsicIt)
80 ->getDialect()
81 ->getNamespace()));
82 }
83 // Add a mapping for all supported intrinsic identifiers.
84 for (unsigned id : iface.getSupportedIntrinsics())
85 intrinsicToDialect[id] = iface.getDialect();
86 // Add a mapping for all supported instruction identifiers.
87 for (unsigned id : iface.getSupportedInstructions())
88 instructionToDialect[id] = &iface;
89 // Add a mapping for all supported metadata kinds.
90 for (unsigned kind : iface.getSupportedMetadata(llvmContext))
91 metadataToDialect[kind].push_back(iface.getDialect());
92 }
93
94 return success();
95 }
96
97 /// Converts the LLVM intrinsic to an MLIR operation if a conversion exists.
98 /// Returns failure otherwise.
99 LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst,
100 LLVM::ModuleImport &moduleImport) const;
101
102 /// Returns true if the given LLVM IR intrinsic is convertible to an MLIR
103 /// operation.
104 bool isConvertibleIntrinsic(llvm::Intrinsic::ID id) {
105 return intrinsicToDialect.count(id);
106 }
107
108 /// Converts the LLVM instruction to an MLIR operation if a conversion exists.
109 /// Returns failure otherwise.
110 LogicalResult convertInstruction(OpBuilder &builder, llvm::Instruction *inst,
111 ArrayRef<llvm::Value *> llvmOperands,
112 LLVM::ModuleImport &moduleImport) const {
113 // Lookup the dialect interface for the given instruction.
114 const LLVMImportDialectInterface *iface =
115 instructionToDialect.lookup(inst->getOpcode());
116 if (!iface)
117 return failure();
118
119 return iface->convertInstruction(builder, inst, llvmOperands, moduleImport);
120 }
121
122 /// Returns true if the given LLVM IR instruction is convertible to an MLIR
123 /// operation.
124 bool isConvertibleInstruction(unsigned id) {
125 return instructionToDialect.count(id);
126 }
127
128 /// Attaches the given LLVM metadata to the imported operation if a conversion
129 /// to one or more MLIR dialect attributes exists and succeeds. Returns
130 /// success if at least one of the conversions is successful and failure if
131 /// all of them fail.
132 LogicalResult setMetadataAttrs(OpBuilder &builder, unsigned kind,
133 llvm::MDNode *node, Operation *op,
134 LLVM::ModuleImport &moduleImport) const {
135 // Lookup the dialect interfaces for the given metadata.
136 auto it = metadataToDialect.find(kind);
137 if (it == metadataToDialect.end())
138 return failure();
139
140 // Dispatch the conversion to the dialect interfaces.
141 bool isSuccess = false;
142 for (Dialect *dialect : it->getSecond()) {
143 const LLVMImportDialectInterface *iface = getInterfaceFor(dialect);
144 assert(iface && "expected to find a dialect interface");
145 if (succeeded(
146 iface->setMetadataAttrs(builder, kind, node, op, moduleImport)))
147 isSuccess = true;
148 }
149
150 // Returns failure if all conversions fail.
151 return success(isSuccess);
152 }
153
154 /// Returns true if the given LLVM IR metadata is convertible to an MLIR
155 /// attribute.
156 bool isConvertibleMetadata(unsigned kind) {
157 return metadataToDialect.count(kind);
158 }
159
160private:
161 /// Generate llvm.call_intrinsic when no supporting dialect available.
162 static LogicalResult
163 convertUnregisteredIntrinsic(OpBuilder &builder, llvm::CallInst *inst,
164 LLVM::ModuleImport &moduleImport);
165
166 DenseMap<unsigned, Dialect *> intrinsicToDialect;
169};
170
171} // namespace mlir
172
173#endif // MLIR_TARGET_LLVMIR_LLVMIMPORTINTERFACE_H
return success()
DialectInterfaceCollection< LLVMImportDialectInterface > Base
const LLVMImportDialectInterface * getInterfaceFor(Object *obj) const
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition Dialect.h:38
Interface collection for the import of LLVM IR that dispatches to a concrete dialect interface implem...
LogicalResult convertInstruction(OpBuilder &builder, llvm::Instruction *inst, ArrayRef< llvm::Value * > llvmOperands, LLVM::ModuleImport &moduleImport) const
Converts the LLVM instruction to an MLIR operation if a conversion exists.
LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst, LLVM::ModuleImport &moduleImport) const
Converts the LLVM intrinsic to an MLIR operation if a conversion exists.
LogicalResult setMetadataAttrs(OpBuilder &builder, unsigned kind, llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport) const
Attaches the given LLVM metadata to the imported operation if a conversion to one or more MLIR dialec...
bool isConvertibleMetadata(unsigned kind)
Returns true if the given LLVM IR metadata is convertible to an MLIR attribute.
LogicalResult initializeImport(llvm::LLVMContext &llvmContext)
Queries all registered dialect interfaces for the supported LLVM IR intrinsic and metadata kinds and ...
bool isConvertibleInstruction(unsigned id)
Returns true if the given LLVM IR instruction is convertible to an MLIR operation.
bool isConvertibleIntrinsic(llvm::Intrinsic::ID id)
Returns true if the given LLVM IR intrinsic is convertible to an MLIR operation.
Module import implementation class that provides methods to import globals and functions from an LLVM...
This class helps build Operations.
Definition Builders.h:209
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition CallGraph.h:229
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap
Definition LLVM.h:120