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