Skip to content

Commit 5f71a95

Browse files
committed
[mlir] Add convertInstruction and getSupportedInstructions to LLVMImportInterface
This patch adds the `convertInstruction` and `getSupportedInstructions` to `LLVMImportInterface`, allowing any non-LLVM dialect to specify how to import LLVM IR instructions. This patch is necessary for llvm#73057
1 parent f15b7de commit 5f71a95

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

mlir/include/mlir/Target/LLVMIR/LLVMImportInterface.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ class LLVMImportDialectInterface
5252
return failure();
5353
}
5454

55+
/// Hook for derived dialect interfaces to implement the import of
56+
/// instructions into MLIR.
57+
virtual LogicalResult
58+
convertInstruction(OpBuilder &builder, llvm::Instruction *inst,
59+
ArrayRef<llvm::Value *> llvmOperands,
60+
LLVM::ModuleImport &moduleImport) const {
61+
return failure();
62+
}
63+
5564
/// Hook for derived dialect interfaces to implement the import of metadata
5665
/// into MLIR. Attaches the converted metadata kind and node to the provided
5766
/// operation.
@@ -66,6 +75,11 @@ class LLVMImportDialectInterface
6675
/// returns the list of supported intrinsic identifiers.
6776
virtual ArrayRef<unsigned> getSupportedIntrinsics() const { return {}; }
6877

78+
/// Hook for derived dialect interfaces to publish the supported instructions.
79+
/// As every LLVM IR instructions has a unique integer identifier, the
80+
/// function returns the list of supported instructions identifiers.
81+
virtual ArrayRef<unsigned> getSupportedInstructions() const { return {}; }
82+
6983
/// Hook for derived dialect interfaces to publish the supported metadata
7084
/// kinds. As every metadata kind has a unique integer identifier, the
7185
/// function returns the list of supported metadata identifiers.
@@ -100,9 +114,27 @@ class LLVMImportInterface
100114
*it, iface.getDialect()->getNamespace(),
101115
intrinsicToDialect.lookup(*it)->getNamespace()));
102116
}
117+
const auto *instIt =
118+
llvm::find_if(iface.getSupportedInstructions(), [&](unsigned id) {
119+
return instructionToDialect.count(id);
120+
});
121+
if (instIt != iface.getSupportedInstructions().end()) {
122+
return emitError(
123+
UnknownLoc::get(iface.getContext()),
124+
llvm::formatv(
125+
"expected unique conversion for instruction ({0}), but "
126+
"got conflicting {1} and {2} conversions",
127+
*it, iface.getDialect()->getNamespace(),
128+
instructionToDialect.lookup(*it)
129+
->getDialect()
130+
->getNamespace()));
131+
}
103132
// Add a mapping for all supported intrinsic identifiers.
104133
for (unsigned id : iface.getSupportedIntrinsics())
105134
intrinsicToDialect[id] = iface.getDialect();
135+
// Add a mapping for all supported instruction identifiers.
136+
for (unsigned id : iface.getSupportedInstructions())
137+
instructionToDialect[id] = &iface;
106138
// Add a mapping for all supported metadata kinds.
107139
for (unsigned kind : iface.getSupportedMetadata())
108140
metadataToDialect[kind].push_back(iface.getDialect());
@@ -132,6 +164,26 @@ class LLVMImportInterface
132164
return intrinsicToDialect.count(id);
133165
}
134166

167+
/// Converts the LLVM instruction to an MLIR operation if a conversion exists.
168+
/// Returns failure otherwise.
169+
LogicalResult convertInstruction(OpBuilder &builder, llvm::Instruction *inst,
170+
ArrayRef<llvm::Value *> llvmOperands,
171+
LLVM::ModuleImport &moduleImport) const {
172+
// Lookup the dialect interface for the given instruction.
173+
const LLVMImportDialectInterface *iface =
174+
instructionToDialect.lookup(inst->getOpcode());
175+
if (!iface)
176+
return failure();
177+
178+
return iface->convertInstruction(builder, inst, llvmOperands, moduleImport);
179+
}
180+
181+
/// Returns true if the given LLVM IR instruction is convertible to an MLIR
182+
/// operation.
183+
bool isConvertibleInstruction(unsigned id) {
184+
return instructionToDialect.count(id);
185+
}
186+
135187
/// Attaches the given LLVM metadata to the imported operation if a conversion
136188
/// to one or more MLIR dialect attributes exists and succeeds. Returns
137189
/// success if at least one of the conversions is successful and failure if
@@ -166,6 +218,7 @@ class LLVMImportInterface
166218

167219
private:
168220
DenseMap<unsigned, Dialect *> intrinsicToDialect;
221+
DenseMap<unsigned, const LLVMImportDialectInterface *> instructionToDialect;
169222
DenseMap<unsigned, SmallVector<Dialect *, 1>> metadataToDialect;
170223
};
171224

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,17 @@ static SmallVector<int64_t> getPositionFromIndices(ArrayRef<unsigned> indices) {
123123
/// access to the private module import methods.
124124
static LogicalResult convertInstructionImpl(OpBuilder &odsBuilder,
125125
llvm::Instruction *inst,
126-
ModuleImport &moduleImport) {
126+
ModuleImport &moduleImport,
127+
LLVMImportInterface &importIface) {
127128
// Copy the operands to an LLVM operands array reference for conversion.
128129
SmallVector<llvm::Value *> operands(inst->operands());
129130
ArrayRef<llvm::Value *> llvmOperands(operands);
130131

131132
// Convert all instructions that provide an MLIR builder.
132133
#include "mlir/Dialect/LLVMIR/LLVMOpFromLLVMIRConversions.inc"
134+
if (importIface.isConvertibleInstruction(inst->getOpcode()))
135+
return importIface.convertInstruction(odsBuilder, inst, llvmOperands,
136+
moduleImport);
133137
return failure();
134138
}
135139

@@ -1596,7 +1600,7 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
15961600
}
15971601

15981602
// Convert all instructions that have an mlirBuilder.
1599-
if (succeeded(convertInstructionImpl(builder, inst, *this)))
1603+
if (succeeded(convertInstructionImpl(builder, inst, *this, iface)))
16001604
return success();
16011605

16021606
return emitError(loc) << "unhandled instruction: " << diag(*inst);

0 commit comments

Comments
 (0)