Coverage Report

Created: 2020-06-26 05:44

/home/arjun/llvm-project/mlir/include/mlir/IR/Module.h
Line
Count
Source (jump to first uncovered line)
1
//===- Module.h - MLIR Module Class -----------------------------*- 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
// Module is the top-level container for code in an MLIR program.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef MLIR_IR_MODULE_H
14
#define MLIR_IR_MODULE_H
15
16
#include "mlir/IR/SymbolTable.h"
17
#include "llvm/Support/PointerLikeTypeTraits.h"
18
19
namespace mlir {
20
class ModuleTerminatorOp;
21
22
//===----------------------------------------------------------------------===//
23
// Module Operation.
24
//===----------------------------------------------------------------------===//
25
26
/// ModuleOp represents a module, or an operation containing one region with a
27
/// single block containing opaque operations. The region of a module is not
28
/// allowed to implicitly capture global values, and all external references
29
/// must use symbolic references via attributes(e.g. via a string name).
30
class ModuleOp
31
    : public Op<
32
          ModuleOp, OpTrait::ZeroOperands, OpTrait::ZeroResult,
33
          OpTrait::IsIsolatedFromAbove, OpTrait::AffineScope,
34
          OpTrait::SymbolTable,
35
          OpTrait::SingleBlockImplicitTerminator<ModuleTerminatorOp>::Impl,
36
          SymbolOpInterface::Trait> {
37
public:
38
  using Op::Op;
39
  using Op::print;
40
41
0
  static StringRef getOperationName() { return "module"; }
42
43
  static void build(OpBuilder &builder, OperationState &result,
44
                    Optional<StringRef> name = llvm::None);
45
46
  /// Construct a module from the given location with an optional name.
47
  static ModuleOp create(Location loc, Optional<StringRef> name = llvm::None);
48
49
  /// Operation hooks.
50
  static ParseResult parse(OpAsmParser &parser, OperationState &result);
51
  void print(OpAsmPrinter &p);
52
  LogicalResult verify();
53
54
  /// Return body of this module.
55
  Region &getBodyRegion();
56
  Block *getBody();
57
58
  /// Return the name of this module if present.
59
  Optional<StringRef> getName();
60
61
  /// Print the this module in the custom top-level form.
62
  void print(raw_ostream &os, OpPrintingFlags flags = llvm::None);
63
  void print(raw_ostream &os, AsmState &state,
64
             OpPrintingFlags flags = llvm::None);
65
  void dump();
66
67
  //===--------------------------------------------------------------------===//
68
  // Body Management.
69
  //===--------------------------------------------------------------------===//
70
71
  /// Iteration over the operations in the module.
72
  using iterator = Block::iterator;
73
74
0
  iterator begin() { return getBody()->begin(); }
75
0
  iterator end() { return getBody()->end(); }
76
0
  Operation &front() { return *begin(); }
77
78
  /// This returns a range of operations of the given type 'T' held within the
79
  /// module.
80
  template <typename T> iterator_range<Block::op_iterator<T>> getOps() {
81
    return getBody()->getOps<T>();
82
  }
83
84
  /// Insert the operation into the back of the body, before the terminator.
85
0
  void push_back(Operation *op) {
86
0
    insert(Block::iterator(getBody()->getTerminator()), op);
87
0
  }
88
89
  /// Insert the operation at the given insertion point. Note: The operation is
90
  /// never inserted after the terminator, even if the insertion point is end().
91
0
  void insert(Operation *insertPt, Operation *op) {
92
0
    insert(Block::iterator(insertPt), op);
93
0
  }
94
0
  void insert(Block::iterator insertPt, Operation *op) {
95
0
    auto *body = getBody();
96
0
    if (insertPt == body->end())
97
0
      insertPt = Block::iterator(body->getTerminator());
98
0
    body->getOperations().insert(insertPt, op);
99
0
  }
100
101
  //===--------------------------------------------------------------------===//
102
  // SymbolOpInterface Methods
103
  //===--------------------------------------------------------------------===//
104
105
  /// A ModuleOp may optionally define a symbol.
106
0
  bool isOptionalSymbol() { return true; }
107
};
108
109
/// The ModuleTerminatorOp is a special terminator operation for the body of a
110
/// ModuleOp, it has no semantic meaning beyond keeping the body of a ModuleOp
111
/// well-formed.
112
///
113
/// This operation does _not_ have a custom syntax. However, ModuleOp will omit
114
/// the terminator in their custom syntax for brevity.
115
class ModuleTerminatorOp
116
    : public Op<ModuleTerminatorOp, OpTrait::ZeroOperands, OpTrait::ZeroResult,
117
                OpTrait::HasParent<ModuleOp>::Impl, OpTrait::IsTerminator> {
118
public:
119
  using Op::Op;
120
0
  static StringRef getOperationName() { return "module_terminator"; }
121
0
  static void build(OpBuilder &, OperationState &) {}
122
};
123
124
/// This class acts as an owning reference to a module, and will automatically
125
/// destroy the held module if valid.
126
class OwningModuleRef {
127
public:
128
0
  OwningModuleRef(std::nullptr_t = nullptr) {}
129
0
  OwningModuleRef(ModuleOp module) : module(module) {}
130
0
  OwningModuleRef(OwningModuleRef &&other) : module(other.release()) {}
131
0
  ~OwningModuleRef() {
132
0
    if (module)
133
0
      module.erase();
134
0
  }
135
136
  // Assign from another module reference.
137
0
  OwningModuleRef &operator=(OwningModuleRef &&other) {
138
0
    if (module)
139
0
      module.erase();
140
0
    module = other.release();
141
0
    return *this;
142
0
  }
143
144
  /// Allow accessing the internal module.
145
0
  ModuleOp get() const { return module; }
146
0
  ModuleOp operator*() const { return module; }
147
0
  ModuleOp *operator->() { return &module; }
148
0
  explicit operator bool() const { return module; }
149
150
  /// Release the referenced module.
151
0
  ModuleOp release() {
152
0
    ModuleOp released;
153
0
    std::swap(released, module);
154
0
    return released;
155
0
  }
156
157
private:
158
  ModuleOp module;
159
};
160
161
} // end namespace mlir
162
163
namespace llvm {
164
165
/// Allow stealing the low bits of ModuleOp.
166
template <> struct PointerLikeTypeTraits<mlir::ModuleOp> {
167
public:
168
0
  static inline void *getAsVoidPointer(mlir::ModuleOp I) {
169
0
    return const_cast<void *>(I.getAsOpaquePointer());
170
0
  }
171
0
  static inline mlir::ModuleOp getFromVoidPointer(void *P) {
172
0
    return mlir::ModuleOp::getFromOpaquePointer(P);
173
0
  }
174
  static constexpr int NumLowBitsAvailable = 3;
175
};
176
177
} // end namespace llvm
178
179
#endif // MLIR_IR_MODULE_H