MLIR  14.0.0git
ModuleTranslation.h
Go to the documentation of this file.
1 //===- ModuleTranslation.h - MLIR to LLVM 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 translation between an MLIR LLVM dialect module and
10 // the corresponding LLVMIR module. It only handles core LLVM IR operations.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_TARGET_LLVMIR_MODULETRANSLATION_H
15 #define MLIR_TARGET_LLVMIR_MODULETRANSLATION_H
16 
17 #include "mlir/IR/Operation.h"
18 #include "mlir/IR/Value.h"
22 
23 #include "llvm/ADT/SetVector.h"
24 #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
25 
26 namespace llvm {
27 class BasicBlock;
28 class IRBuilderBase;
29 class Function;
30 class Value;
31 } // namespace llvm
32 
33 namespace mlir {
34 class Attribute;
35 class Block;
36 class Location;
37 
38 namespace LLVM {
39 
40 namespace detail {
41 class DebugTranslation;
42 } // end namespace detail
43 
44 class LLVMFuncOp;
45 
46 /// Implementation class for module translation. Holds a reference to the module
47 /// being translated, and the mappings between the original and the translated
48 /// functions, basic blocks and values. It is practically easier to hold these
49 /// mappings in one class since the conversion of control flow operations
50 /// needs to look up block and function mappings.
52  friend std::unique_ptr<llvm::Module>
53  mlir::translateModuleToLLVMIR(Operation *, llvm::LLVMContext &, StringRef);
54 
55 public:
56  /// Stores the mapping between a function name and its LLVM IR representation.
57  void mapFunction(StringRef name, llvm::Function *func) {
58  auto result = functionMapping.try_emplace(name, func);
59  (void)result;
60  assert(result.second &&
61  "attempting to map a function that is already mapped");
62  }
63 
64  /// Finds an LLVM IR function by its name.
65  llvm::Function *lookupFunction(StringRef name) const {
66  return functionMapping.lookup(name);
67  }
68 
69  /// Stores the mapping between an MLIR value and its LLVM IR counterpart.
70  void mapValue(Value mlir, llvm::Value *llvm) { mapValue(mlir) = llvm; }
71 
72  /// Provides write-once access to store the LLVM IR value corresponding to the
73  /// given MLIR value.
74  llvm::Value *&mapValue(Value value) {
75  llvm::Value *&llvm = valueMapping[value];
76  assert(llvm == nullptr &&
77  "attempting to map a value that is already mapped");
78  return llvm;
79  }
80 
81  /// Finds an LLVM IR value corresponding to the given MLIR value.
82  llvm::Value *lookupValue(Value value) const {
83  return valueMapping.lookup(value);
84  }
85 
86  /// Looks up remapped a list of remapped values.
87  SmallVector<llvm::Value *> lookupValues(ValueRange values);
88 
89  /// Stores the mapping between an MLIR block and LLVM IR basic block.
90  void mapBlock(Block *mlir, llvm::BasicBlock *llvm) {
91  auto result = blockMapping.try_emplace(mlir, llvm);
92  (void)result;
93  assert(result.second && "attempting to map a block that is already mapped");
94  }
95 
96  /// Finds an LLVM IR basic block that corresponds to the given MLIR block.
97  llvm::BasicBlock *lookupBlock(Block *block) const {
98  return blockMapping.lookup(block);
99  }
100 
101  /// Stores the mapping between an MLIR operation with successors and a
102  /// corresponding LLVM IR instruction.
103  void mapBranch(Operation *mlir, llvm::Instruction *llvm) {
104  auto result = branchMapping.try_emplace(mlir, llvm);
105  (void)result;
106  assert(result.second &&
107  "attempting to map a branch that is already mapped");
108  }
109 
110  /// Finds an LLVM IR instruction that corresponds to the given MLIR operation
111  /// with successors.
112  llvm::Instruction *lookupBranch(Operation *op) const {
113  return branchMapping.lookup(op);
114  }
115 
116  /// Removes the mapping for blocks contained in the region and values defined
117  /// in these blocks.
118  void forgetMapping(Region &region);
119 
120  /// Returns the LLVM metadata corresponding to a reference to an mlir LLVM
121  /// dialect access group operation.
122  llvm::MDNode *getAccessGroup(Operation &opInst,
123  SymbolRefAttr accessGroupRef) const;
124 
125  /// Returns the LLVM metadata corresponding to a reference to an mlir LLVM
126  /// dialect alias scope operation
127  llvm::MDNode *getAliasScope(Operation &opInst,
128  SymbolRefAttr aliasScopeRef) const;
129 
130  /// Returns the LLVM metadata corresponding to a llvm loop's codegen
131  /// options attribute.
133  return loopOptionsMetadataMapping.lookup(options);
134  }
135 
136  void mapLoopOptionsMetadata(Attribute options, llvm::MDNode *metadata) {
137  auto result = loopOptionsMetadataMapping.try_emplace(options, metadata);
138  (void)result;
139  assert(result.second &&
140  "attempting to map loop options that was already mapped");
141  }
142 
143  // Sets LLVM metadata for memory operations that are in a parallel loop.
144  void setAccessGroupsMetadata(Operation *op, llvm::Instruction *inst);
145 
146  // Sets LLVM metadata for memory operations that have alias scope information.
147  void setAliasScopeMetadata(Operation *op, llvm::Instruction *inst);
148 
149  /// Converts the type from MLIR LLVM dialect to LLVM.
150  llvm::Type *convertType(Type type);
151 
152  /// Returns the MLIR context of the module being translated.
153  MLIRContext &getContext() { return *mlirModule->getContext(); }
154 
155  /// Returns the LLVM context in which the IR is being constructed.
156  llvm::LLVMContext &getLLVMContext() const { return llvmModule->getContext(); }
157 
158  /// Finds an LLVM IR global value that corresponds to the given MLIR operation
159  /// defining a global value.
160  llvm::GlobalValue *lookupGlobal(Operation *op) {
161  return globalsMapping.lookup(op);
162  }
163 
164  /// Returns the OpenMP IR builder associated with the LLVM IR module being
165  /// constructed.
166  llvm::OpenMPIRBuilder *getOpenMPBuilder() {
167  if (!ompBuilder) {
168  ompBuilder = std::make_unique<llvm::OpenMPIRBuilder>(*llvmModule);
169  ompBuilder->initialize();
170  }
171  return ompBuilder.get();
172  }
173 
174  /// Translates the given location.
175  const llvm::DILocation *translateLoc(Location loc, llvm::DILocalScope *scope);
176 
177  /// Translates the contents of the given block to LLVM IR using this
178  /// translator. The LLVM IR basic block corresponding to the given block is
179  /// expected to exist in the mapping of this translator. Uses `builder` to
180  /// translate the IR, leaving it at the end of the block. If `ignoreArguments`
181  /// is set, does not produce PHI nodes for the block arguments. Otherwise, the
182  /// PHI nodes are constructed for block arguments but are _not_ connected to
183  /// the predecessors that may not exist yet.
184  LogicalResult convertBlock(Block &bb, bool ignoreArguments,
185  llvm::IRBuilderBase &builder);
186 
187  /// Gets the named metadata in the LLVM IR module being constructed, creating
188  /// it if it does not exist.
189  llvm::NamedMDNode *getOrInsertNamedModuleMetadata(StringRef name);
190 
191  /// Common CRTP base class for ModuleTranslation stack frames.
192  class StackFrame {
193  public:
194  virtual ~StackFrame() {}
195  TypeID getTypeID() const { return typeID; }
196 
197  protected:
198  explicit StackFrame(TypeID typeID) : typeID(typeID) {}
199 
200  private:
201  const TypeID typeID;
202  virtual void anchor();
203  };
204 
205  /// Concrete CRTP base class for ModuleTranslation stack frames. When
206  /// translating operations with regions, users of ModuleTranslation can store
207  /// state on ModuleTranslation stack before entering the region and inspect
208  /// it when converting operations nested within that region. Users are
209  /// expected to derive this class and put any relevant information into fields
210  /// of the derived class. The usual isa/dyn_cast functionality is available
211  /// for instances of derived classes.
212  template <typename Derived>
213  class StackFrameBase : public StackFrame {
214  public:
215  explicit StackFrameBase() : StackFrame(TypeID::get<Derived>()) {}
216  };
217 
218  /// Creates a stack frame of type `T` on ModuleTranslation stack. `T` must
219  /// be derived from `StackFrameBase<T>` and constructible from the provided
220  /// arguments. Doing this before entering the region of the op being
221  /// translated makes the frame available when translating ops within that
222  /// region.
223  template <typename T, typename... Args>
224  void stackPush(Args &&...args) {
225  static_assert(
227  "can only push instances of StackFrame on ModuleTranslation stack");
228  stack.push_back(std::make_unique<T>(std::forward<Args>(args)...));
229  }
230 
231  /// Pops the last element from the ModuleTranslation stack.
232  void stackPop() { stack.pop_back(); }
233 
234  /// Calls `callback` for every ModuleTranslation stack frame of type `T`
235  /// starting from the top of the stack.
236  template <typename T>
237  WalkResult
238  stackWalk(llvm::function_ref<WalkResult(const T &)> callback) const {
240  "expected T derived from StackFrame");
241  if (!callback)
242  return WalkResult::skip();
243  for (const std::unique_ptr<StackFrame> &frame : llvm::reverse(stack)) {
244  if (T *ptr = dyn_cast_or_null<T>(frame.get())) {
245  WalkResult result = callback(*ptr);
246  if (result.wasInterrupted())
247  return result;
248  }
249  }
250  return WalkResult::advance();
251  }
252 
253  /// RAII object calling stackPush/stackPop on construction/destruction.
254  template <typename T>
255  struct SaveStack {
256  template <typename... Args>
257  explicit SaveStack(ModuleTranslation &m, Args &&...args)
258  : moduleTranslation(m) {
259  moduleTranslation.stackPush<T>(std::forward<Args>(args)...);
260  }
261  ~SaveStack() { moduleTranslation.stackPop(); }
262 
263  private:
264  ModuleTranslation &moduleTranslation;
265  };
266 
267 private:
269  std::unique_ptr<llvm::Module> llvmModule);
271 
272  /// Converts individual components.
273  LogicalResult convertOperation(Operation &op, llvm::IRBuilderBase &builder);
274  LogicalResult convertFunctionSignatures();
275  LogicalResult convertFunctions();
276  LogicalResult convertGlobals();
277  LogicalResult convertOneFunction(LLVMFuncOp func);
278 
279  /// Process access_group LLVM Metadata operations and create LLVM
280  /// metadata nodes.
281  LogicalResult createAccessGroupMetadata();
282 
283  /// Process alias.scope LLVM Metadata operations and create LLVM
284  /// metadata nodes for them and their domains.
285  LogicalResult createAliasScopeMetadata();
286 
287  /// Translates dialect attributes attached to the given operation.
288  LogicalResult convertDialectAttributes(Operation *op);
289 
290  /// Original and translated module.
291  Operation *mlirModule;
292  std::unique_ptr<llvm::Module> llvmModule;
293  /// A converter for translating debug information.
294  std::unique_ptr<detail::DebugTranslation> debugTranslation;
295 
296  /// Builder for LLVM IR generation of OpenMP constructs.
297  std::unique_ptr<llvm::OpenMPIRBuilder> ompBuilder;
298 
299  /// Mappings between llvm.mlir.global definitions and corresponding globals.
301 
302  /// A stateful object used to translate types.
303  TypeToLLVMIRTranslator typeTranslator;
304 
305  /// A dialect interface collection used for dispatching the translation to
306  /// specific dialects.
308 
309  /// Mappings between original and translated values, used for lookups.
310  llvm::StringMap<llvm::Function *> functionMapping;
311  DenseMap<Value, llvm::Value *> valueMapping;
313 
314  /// A mapping between MLIR LLVM dialect terminators and LLVM IR terminators
315  /// they are converted to. This allows for connecting PHI nodes to the source
316  /// values after all operations are converted.
318 
319  /// Mapping from an access group metadata operation to its LLVM metadata.
320  /// This map is populated on module entry and is used to annotate loops (as
321  /// identified via their branches) and contained memory accesses.
322  DenseMap<Operation *, llvm::MDNode *> accessGroupMetadataMapping;
323 
324  /// Mapping from an attribute describing loop codegen options to its LLVM
325  /// metadata. The metadata is attached to Latch block branches with this
326  /// attribute.
327  DenseMap<Attribute, llvm::MDNode *> loopOptionsMetadataMapping;
328 
329  /// Mapping from an access scope metadata operation to its LLVM metadata.
330  /// This map is populated on module entry.
331  DenseMap<Operation *, llvm::MDNode *> aliasScopeMetadataMapping;
332 
333  /// Stack of user-specified state elements, useful when translating operations
334  /// with regions.
336 };
337 
338 namespace detail {
339 /// For all blocks in the region that were converted to LLVM IR using the given
340 /// ModuleTranslation, connect the PHI nodes of the corresponding LLVM IR blocks
341 /// to the results of preceding blocks.
342 void connectPHINodes(Region &region, const ModuleTranslation &state);
343 
344 /// Get a topologically sorted list of blocks of the given region.
346 
347 /// Create an LLVM IR constant of `llvmType` from the MLIR attribute `attr`.
348 /// This currently supports integer, floating point, splat and dense element
349 /// attributes and combinations thereof. Also, an array attribute with two
350 /// elements is supported to represent a complex constant. In case of error,
351 /// report it to `loc` and return nullptr.
352 llvm::Constant *getLLVMConstant(llvm::Type *llvmType, Attribute attr,
353  Location loc,
354  const ModuleTranslation &moduleTranslation,
355  bool isTopLevel = true);
356 
357 /// Creates a call to an LLVM IR intrinsic function with the given arguments.
358 llvm::Value *createIntrinsicCall(llvm::IRBuilderBase &builder,
359  llvm::Intrinsic::ID intrinsic,
360  ArrayRef<llvm::Value *> args = {},
361  ArrayRef<llvm::Type *> tys = {});
362 } // namespace detail
363 
364 } // namespace LLVM
365 } // namespace mlir
366 
367 namespace llvm {
368 template <typename T>
370  static inline bool
371  doit(const ::mlir::LLVM::ModuleTranslation::StackFrame &frame) {
372  return frame.getTypeID() == ::mlir::TypeID::get<T>();
373  }
374 };
375 } // namespace llvm
376 
377 #endif // MLIR_TARGET_LLVMIR_MODULETRANSLATION_H
Include the generated interface declarations.
llvm::Constant * getLLVMConstant(llvm::Type *llvmType, Attribute attr, Location loc, const ModuleTranslation &moduleTranslation, bool isTopLevel=true)
Create an LLVM IR constant of llvmType from the MLIR attribute attr.
This class contains a list of basic blocks and a link to the parent operation it is attached to...
Definition: Region.h:26
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
Block represents an ordered list of Operations.
Definition: Block.h:29
Utility class to translate MLIR LLVM dialect types to LLVM IR.
Definition: TypeToLLVM.h:39
bool wasInterrupted() const
Returns true if the walk was interrupted.
Definition: Visitors.h:55
llvm::LLVMContext & getLLVMContext() const
Returns the LLVM context in which the IR is being constructed.
Concrete CRTP base class for ModuleTranslation stack frames.
void mapLoopOptionsMetadata(Attribute options, llvm::MDNode *metadata)
llvm::BasicBlock * lookupBlock(Block *block) const
Finds an LLVM IR basic block that corresponds to the given MLIR block.
static constexpr const bool value
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:52
void mapBlock(Block *mlir, llvm::BasicBlock *llvm)
Stores the mapping between an MLIR block and LLVM IR basic block.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
llvm::Value * createIntrinsicCall(llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic, ArrayRef< llvm::Value *> args={}, ArrayRef< llvm::Type *> tys={})
Creates a call to an LLVM IR intrinsic function with the given arguments.
Implementation class for module translation.
llvm::OpenMPIRBuilder * getOpenMPBuilder()
Returns the OpenMP IR builder associated with the LLVM IR module being constructed.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
void mapValue(Value mlir, llvm::Value *llvm)
Stores the mapping between an MLIR value and its LLVM IR counterpart.
llvm::Instruction * lookupBranch(Operation *op) const
Finds an LLVM IR instruction that corresponds to the given MLIR operation with successors.
MLIRContext & getContext()
Returns the MLIR context of the module being translated.
Attributes are known-constant values of operations.
Definition: Attributes.h:27
static bool doit(const ::mlir::LLVM::ModuleTranslation::StackFrame &frame)
RAII object calling stackPush/stackPop on construction/destruction.
void stackPush(Args &&...args)
Creates a stack frame of type T on ModuleTranslation stack.
A utility result that is used to signal how to proceed with an ongoing walk:
Definition: Visitors.h:34
llvm::Value * lookupValue(Value value) const
Finds an LLVM IR value corresponding to the given MLIR value.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
WalkResult stackWalk(llvm::function_ref< WalkResult(const T &)> callback) const
Calls callback for every ModuleTranslation stack frame of type T starting from the top of the stack...
void connectPHINodes(Region &region, const ModuleTranslation &state)
For all blocks in the region that were converted to LLVM IR using the given ModuleTranslation, connect the PHI nodes of the corresponding LLVM IR blocks to the results of preceding blocks.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:84
static llvm::ManagedStatic< PassManagerOptions > options
SaveStack(ModuleTranslation &m, Args &&...args)
llvm::Function * lookupFunction(StringRef name) const
Finds an LLVM IR function by its name.
Common CRTP base class for ModuleTranslation stack frames.
void mapBranch(Operation *mlir, llvm::Instruction *llvm)
Stores the mapping between an MLIR operation with successors and a corresponding LLVM IR instruction...
SetVector< Block * > getTopologicallySortedBlocks(Region &region)
Get a topologically sorted list of blocks of the given region.
void stackPop()
Pops the last element from the ModuleTranslation stack.
llvm::GlobalValue * lookupGlobal(Operation *op)
Finds an LLVM IR global value that corresponds to the given MLIR operation defining a global value...
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
std::unique_ptr< llvm::Module > translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext, llvm::StringRef name="LLVMDialectModule")
Translate operation that satisfies LLVM dialect module requirements into an LLVM IR module living in ...
void mapFunction(StringRef name, llvm::Function *func)
Stores the mapping between a function name and its LLVM IR representation.
Interface collection for translation to LLVM IR, dispatches to a concrete interface implementation ba...
llvm::Value *& mapValue(Value value)
Provides write-once access to store the LLVM IR value corresponding to the given MLIR value...
llvm::MDNode * lookupLoopOptionsMetadata(Attribute options) const
Returns the LLVM metadata corresponding to a llvm loop&#39;s codegen options attribute.
This class provides an abstraction over the different types of ranges over Values.