MLIR  18.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"
23 #include "llvm/IR/Instruction.h"
24 #include "llvm/IR/Instructions.h"
25 #include "llvm/Support/FormatVariadic.h"
26 
27 namespace llvm {
28 class IRBuilderBase;
29 } // namespace llvm
30 
31 namespace mlir {
32 namespace LLVM {
33 class ModuleImport;
34 } // namespace LLVM
35 
36 /// Base class for dialect interfaces used to import LLVM IR. Dialects that can
37 /// be imported should provide an implementation of this interface for the
38 /// supported intrinsics. The interface may be implemented in a separate library
39 /// to avoid the "main" dialect library depending on LLVM IR. The interface can
40 /// be attached using the delayed registration mechanism available in
41 /// DialectRegistry.
43  : public DialectInterface::Base<LLVMImportDialectInterface> {
44 public:
45  LLVMImportDialectInterface(Dialect *dialect) : Base(dialect) {}
46 
47  /// Hook for derived dialect interfaces to implement the import of
48  /// intrinsics into MLIR.
49  virtual LogicalResult
50  convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst,
51  LLVM::ModuleImport &moduleImport) const {
52  return failure();
53  }
54 
55  /// Hook for derived dialect interfaces to implement the import of metadata
56  /// into MLIR. Attaches the converted metadata kind and node to the provided
57  /// operation.
58  virtual LogicalResult
59  setMetadataAttrs(OpBuilder &builder, unsigned kind, llvm::MDNode *node,
60  Operation *op, LLVM::ModuleImport &moduleImport) const {
61  return failure();
62  }
63 
64  /// Hook for derived dialect interfaces to publish the supported intrinsics.
65  /// As every LLVM IR intrinsic has a unique integer identifier, the function
66  /// returns the list of supported intrinsic identifiers.
67  virtual ArrayRef<unsigned> getSupportedIntrinsics() const { return {}; }
68 
69  /// Hook for derived dialect interfaces to publish the supported metadata
70  /// kinds. As every metadata kind has a unique integer identifier, the
71  /// function returns the list of supported metadata identifiers.
72  virtual ArrayRef<unsigned> getSupportedMetadata() const { return {}; }
73 };
74 
75 /// Interface collection for the import of LLVM IR that dispatches to a concrete
76 /// dialect interface implementation. Queries the dialect interfaces to obtain a
77 /// list of the supported LLVM IR constructs and then builds a mapping for the
78 /// efficient dispatch.
80  : public DialectInterfaceCollection<LLVMImportDialectInterface> {
81 public:
82  using Base::Base;
83 
84  /// Queries all registered dialect interfaces for the supported LLVM IR
85  /// intrinsic and metadata kinds and builds the dispatch tables for the
86  /// conversion. Returns failure if multiple dialect interfaces translate the
87  /// same LLVM IR intrinsic.
89  for (const LLVMImportDialectInterface &iface : *this) {
90  // Verify the supported intrinsics have not been mapped before.
91  const auto *it =
92  llvm::find_if(iface.getSupportedIntrinsics(), [&](unsigned id) {
93  return intrinsicToDialect.count(id);
94  });
95  if (it != iface.getSupportedIntrinsics().end()) {
96  return emitError(
97  UnknownLoc::get(iface.getContext()),
98  llvm::formatv("expected unique conversion for intrinsic ({0}), but "
99  "got conflicting {1} and {2} conversions",
100  *it, iface.getDialect()->getNamespace(),
101  intrinsicToDialect.lookup(*it)->getNamespace()));
102  }
103  // Add a mapping for all supported intrinsic identifiers.
104  for (unsigned id : iface.getSupportedIntrinsics())
105  intrinsicToDialect[id] = iface.getDialect();
106  // Add a mapping for all supported metadata kinds.
107  for (unsigned kind : iface.getSupportedMetadata())
108  metadataToDialect[kind].push_back(iface.getDialect());
109  }
110 
111  return success();
112  }
113 
114  /// Converts the LLVM intrinsic to an MLIR operation if a conversion exists.
115  /// Returns failure otherwise.
116  LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst,
117  LLVM::ModuleImport &moduleImport) const {
118  // Lookup the dialect interface for the given intrinsic.
119  Dialect *dialect = intrinsicToDialect.lookup(inst->getIntrinsicID());
120  if (!dialect)
121  return failure();
122 
123  // Dispatch the conversion to the dialect interface.
124  const LLVMImportDialectInterface *iface = getInterfaceFor(dialect);
125  assert(iface && "expected to find a dialect interface");
126  return iface->convertIntrinsic(builder, inst, moduleImport);
127  }
128 
129  /// Returns true if the given LLVM IR intrinsic is convertible to an MLIR
130  /// operation.
132  return intrinsicToDialect.count(id);
133  }
134 
135  /// Attaches the given LLVM metadata to the imported operation if a conversion
136  /// to one or more MLIR dialect attributes exists and succeeds. Returns
137  /// success if at least one of the conversions is successful and failure if
138  /// all of them fail.
139  LogicalResult setMetadataAttrs(OpBuilder &builder, unsigned kind,
140  llvm::MDNode *node, Operation *op,
141  LLVM::ModuleImport &moduleImport) const {
142  // Lookup the dialect interfaces for the given metadata.
143  auto it = metadataToDialect.find(kind);
144  if (it == metadataToDialect.end())
145  return failure();
146 
147  // Dispatch the conversion to the dialect interfaces.
148  bool isSuccess = false;
149  for (Dialect *dialect : it->getSecond()) {
150  const LLVMImportDialectInterface *iface = getInterfaceFor(dialect);
151  assert(iface && "expected to find a dialect interface");
152  if (succeeded(
153  iface->setMetadataAttrs(builder, kind, node, op, moduleImport)))
154  isSuccess = true;
155  }
156 
157  // Returns failure if all conversions fail.
158  return success(isSuccess);
159  }
160 
161  /// Returns true if the given LLVM IR metadata is convertible to an MLIR
162  /// attribute.
163  bool isConvertibleMetadata(unsigned kind) {
164  return metadataToDialect.count(kind);
165  }
166 
167 private:
168  DenseMap<unsigned, Dialect *> intrinsicToDialect;
170 };
171 
172 } // namespace mlir
173 
174 #endif // MLIR_TARGET_LLVMIR_LLVMIMPORTINTERFACE_H
A collection of dialect interfaces within a context, for a given concrete interface type.
DialectInterfaceCollection< LLVMImportDialectInterface > Base
const LLVMImportDialectInterface * getInterfaceFor(Object *obj) const
Get the interface for a given object, or null if one is not registered.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
Base class for dialect interfaces used to import LLVM IR.
virtual LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst, LLVM::ModuleImport &moduleImport) const
Hook for derived dialect interfaces to implement the import of intrinsics into MLIR.
LLVMImportDialectInterface(Dialect *dialect)
virtual ArrayRef< unsigned > getSupportedIntrinsics() const
Hook for derived dialect interfaces to publish the supported intrinsics.
virtual ArrayRef< unsigned > getSupportedMetadata() const
Hook for derived dialect interfaces to publish the supported metadata kinds.
virtual LogicalResult setMetadataAttrs(OpBuilder &builder, unsigned kind, llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport) const
Hook for derived dialect interfaces to implement the import of metadata into MLIR.
Interface collection for the import of LLVM IR that dispatches to a concrete dialect interface implem...
LogicalResult initializeImport()
Queries all registered dialect interfaces for the supported LLVM IR intrinsic and metadata kinds and ...
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.
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...
Definition: ModuleImport.h:47
This class helps build Operations.
Definition: Builders.h:206
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
The base class used for all derived interface types.
Include the generated interface declarations.
Definition: CallGraph.h:229
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
Definition: LogicalResult.h:68
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26