Skip to content

Commit 9dbf362

Browse files
committed
[mlir][llvm] Move LLVM IR import into separate file (NFC).
The revision renames the Importer to ModuleImport and moves the class out of the ConvertFromLLVMIR.cpp file into ModuleImport.h and ModuleImport.cpp. Additionally, it introduces two helper methods on the ModuleImport class that convert functions and globals, and it merges the translateLLVMIRToModule function into the registerFromLLVMIRTranslation function to match the design of the MLIR to LLVM IR export. This restructuring is a step towards the file structure of the export and a preparation for an extensible import https://discourse.llvm.org/t/rfc-extensible-llvm-ir-import/67256/6 that uses a dialect interface to import intrinsics and metadata. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D140285
1 parent 8febe67 commit 9dbf362

File tree

4 files changed

+1408
-1337
lines changed

4 files changed

+1408
-1337
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
//===- ModuleImport.h - LLVM to MLIR conversion -----------------*- 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 file implements the import of an LLVM IR module into an LLVM dialect
10+
// module.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef MLIR_TARGET_LLVMIR_MODULEIMPORT_H
15+
#define MLIR_TARGET_LLVMIR_MODULEIMPORT_H
16+
17+
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
18+
#include "mlir/IR/BuiltinOps.h"
19+
#include "mlir/Target/LLVMIR/Import.h"
20+
#include "mlir/Target/LLVMIR/TypeFromLLVM.h"
21+
22+
namespace llvm {
23+
class BasicBlock;
24+
class CallBase;
25+
class Function;
26+
class Instruction;
27+
class Value;
28+
} // namespace llvm
29+
30+
namespace mlir {
31+
namespace LLVM {
32+
33+
namespace detail {
34+
class DebugImporter;
35+
} // namespace detail
36+
37+
/// Module import implementation class that provides methods to import globals
38+
/// and functions from an LLVM module into an MLIR module. It holds mappings
39+
/// between the original and translated globals, basic blocks, and values used
40+
/// during the translation. Additionally, it keeps track of the current constant
41+
/// insertion point since LLVM immediate values translate to MLIR operations
42+
/// that are introduced at the beginning of the region.
43+
class ModuleImport {
44+
public:
45+
ModuleImport(ModuleOp mlirModule, std::unique_ptr<llvm::Module> llvmModule);
46+
47+
/// Stores the mapping between an LLVM value and its MLIR counterpart.
48+
void mapValue(llvm::Value *llvm, Value mlir) { mapValue(llvm) = mlir; }
49+
50+
/// Provides write-once access to store the MLIR value corresponding to the
51+
/// given LLVM value.
52+
Value &mapValue(llvm::Value *value) {
53+
Value &mlir = valueMapping[value];
54+
assert(mlir == nullptr &&
55+
"attempting to map a value that is already mapped");
56+
return mlir;
57+
}
58+
59+
/// Returns the MLIR value mapped to the given LLVM value.
60+
Value lookupValue(llvm::Value *value) { return valueMapping.lookup(value); }
61+
62+
/// Stores the mapping between an LLVM block and its MLIR counterpart.
63+
void mapBlock(llvm::BasicBlock *llvm, Block *mlir) {
64+
auto result = blockMapping.try_emplace(llvm, mlir);
65+
(void)result;
66+
assert(result.second && "attempting to map a block that is already mapped");
67+
}
68+
69+
/// Returns the MLIR block mapped to the given LLVM block.
70+
Block *lookupBlock(llvm::BasicBlock *block) const {
71+
return blockMapping.lookup(block);
72+
}
73+
74+
/// Converts an LLVM value to an MLIR value, or returns failure if the
75+
/// conversion fails. Uses the `convertConstant` method to translate constant
76+
/// LLVM values.
77+
FailureOr<Value> convertValue(llvm::Value *value);
78+
79+
/// Converts a range of LLVM values to a range of MLIR values using the
80+
/// `convertValue` method, or returns failure if the conversion fails.
81+
FailureOr<SmallVector<Value>> convertValues(ArrayRef<llvm::Value *> values);
82+
83+
/// Converts `value` to an integer attribute. Asserts if the matching fails.
84+
IntegerAttr matchIntegerAttr(llvm::Value *value);
85+
86+
/// Converts `value` to a local variable attribute. Asserts if the matching
87+
/// fails.
88+
DILocalVariableAttr matchLocalVariableAttr(llvm::Value *value);
89+
90+
/// Translates the debug location.
91+
Location translateLoc(llvm::DILocation *loc);
92+
93+
/// Converts the type from LLVM to MLIR LLVM dialect.
94+
Type convertType(llvm::Type *type) {
95+
return typeTranslator.translateType(type);
96+
}
97+
98+
/// Converts an LLVM intrinsic to an MLIR LLVM dialect operation if an MLIR
99+
/// counterpart exists. Otherwise, returns failure.
100+
LogicalResult convertIntrinsic(OpBuilder &odsBuilder, llvm::CallInst *inst,
101+
llvm::Intrinsic::ID intrinsicID);
102+
103+
/// Converts an LLVM instruction to an MLIR LLVM dialect operation if an MLIR
104+
/// counterpart exists. Otherwise, returns failure.
105+
LogicalResult convertOperation(OpBuilder &odsBuilder,
106+
llvm::Instruction *inst);
107+
108+
/// Imports `func` into the current module.
109+
LogicalResult processFunction(llvm::Function *func);
110+
111+
/// Converts function attributes of LLVM Function \p func
112+
/// into LLVM dialect attributes of LLVMFuncOp \p funcOp.
113+
void processFunctionAttributes(llvm::Function *func, LLVMFuncOp funcOp);
114+
115+
/// Imports `globalVar` as a GlobalOp, creating it if it doesn't exist.
116+
GlobalOp processGlobal(llvm::GlobalVariable *globalVar);
117+
118+
/// Converts all functions of the LLVM module to MLIR functions.
119+
LogicalResult convertFunctions();
120+
121+
/// Converts all global variables of the LLVM module to MLIR global variables.
122+
LogicalResult convertGlobals();
123+
124+
private:
125+
/// Clears the block and value mapping before processing a new region.
126+
void clearBlockAndValueMapping() {
127+
valueMapping.clear();
128+
blockMapping.clear();
129+
}
130+
/// Sets the constant insertion point to the start of the given block.
131+
void setConstantInsertionPointToStart(Block *block) {
132+
constantInsertionBlock = block;
133+
constantInsertionOp = nullptr;
134+
}
135+
136+
/// Sets the fastmath flags attribute for the imported operation `op` given
137+
/// the original instruction `inst`. Asserts if the operation does not
138+
/// implement the fastmath interface.
139+
void setFastmathFlagsAttr(llvm::Instruction *inst, Operation *op) const;
140+
/// Returns personality of `func` as a FlatSymbolRefAttr.
141+
FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *func);
142+
/// Imports `bb` into `block`, which must be initially empty.
143+
LogicalResult processBasicBlock(llvm::BasicBlock *bb, Block *block);
144+
/// Imports `inst` and populates valueMapping[inst] with the result of the
145+
/// imported operation.
146+
LogicalResult processInstruction(llvm::Instruction *inst);
147+
/// Converts the `branch` arguments in the order of the phi's found in
148+
/// `target` and appends them to the `blockArguments` to attach to the
149+
/// generated branch operation. The `blockArguments` thus have the same order
150+
/// as the phi's in `target`.
151+
LogicalResult convertBranchArgs(llvm::Instruction *branch,
152+
llvm::BasicBlock *target,
153+
SmallVectorImpl<Value> &blockArguments);
154+
/// Appends the converted result type and operands of `callInst` to the
155+
/// `types` and `operands` arrays. For indirect calls, the method additionally
156+
/// inserts the called function at the beginning of the `operands` array.
157+
LogicalResult convertCallTypeAndOperands(llvm::CallBase *callInst,
158+
SmallVectorImpl<Type> &types,
159+
SmallVectorImpl<Value> &operands);
160+
/// Returns the builtin type equivalent to be used in attributes for the given
161+
/// LLVM IR dialect type.
162+
Type getStdTypeForAttr(Type type);
163+
/// Returns `value` as an attribute to attach to a GlobalOp.
164+
Attribute getConstantAsAttr(llvm::Constant *value);
165+
/// Returns the topologically sorted set of transitive dependencies needed to
166+
/// convert the given constant.
167+
SetVector<llvm::Constant *> getConstantsToConvert(llvm::Constant *constant);
168+
/// Converts an LLVM constant to an MLIR value, or returns failure if the
169+
/// conversion fails. The MLIR value may be produced by a ConstantOp,
170+
/// AddressOfOp, NullOp, or a side-effect free operation (for ConstantExprs or
171+
/// ConstantGEPs).
172+
FailureOr<Value> convertConstant(llvm::Constant *constant);
173+
/// Converts an LLVM constant and its transitive constant dependencies to MLIR
174+
/// operations by converting them in topological order using the
175+
/// `convertConstant` method, or returns failure if the conversion of any of
176+
/// them fails. All operations are inserted at the start of the current
177+
/// function entry block.
178+
FailureOr<Value> convertConstantExpr(llvm::Constant *constant);
179+
180+
/// Builder pointing at where the next instruction should be generated.
181+
OpBuilder builder;
182+
/// Block to insert the next constant into.
183+
Block *constantInsertionBlock = nullptr;
184+
/// Operation to insert the next constant after.
185+
Operation *constantInsertionOp = nullptr;
186+
/// Operation to insert the next global after.
187+
Operation *globalInsertionOp = nullptr;
188+
/// The current context.
189+
MLIRContext *context;
190+
/// The MLIR module being created.
191+
ModuleOp mlirModule;
192+
/// The LLVM module being imported.
193+
std::unique_ptr<llvm::Module> llvmModule;
194+
195+
/// Function-local mapping between original and imported block.
196+
DenseMap<llvm::BasicBlock *, Block *> blockMapping;
197+
/// Function-local mapping between original and imported values.
198+
DenseMap<llvm::Value *, Value> valueMapping;
199+
/// Uniquing map of GlobalVariables.
200+
DenseMap<llvm::GlobalVariable *, GlobalOp> globals;
201+
/// The stateful type translator (contains named structs).
202+
LLVM::TypeFromLLVMIRTranslator typeTranslator;
203+
/// Stateful debug information importer.
204+
std::unique_ptr<detail::DebugImporter> debugImporter;
205+
};
206+
207+
} // namespace LLVM
208+
} // namespace mlir
209+
210+
#endif // MLIR_TARGET_LLVMIR_MODULEIMPORT_H

mlir/lib/Target/LLVMIR/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ set(LLVM_OPTIONAL_SOURCES
66
DebugTranslation.cpp
77
DebugImporter.cpp
88
ModuleTranslation.cpp
9+
ModuleImport.cpp
910
TypeToLLVM.cpp
1011
TypeFromLLVM.cpp
1112
)
@@ -52,6 +53,7 @@ add_mlir_translation_library(MLIRToLLVMIRTranslationRegistration
5253
add_mlir_translation_library(MLIRTargetLLVMIRImport
5354
ConvertFromLLVMIR.cpp
5455
DebugImporter.cpp
56+
ModuleImport.cpp
5557
TypeFromLLVM.cpp
5658

5759
ADDITIONAL_HEADER_DIRS

0 commit comments

Comments
 (0)