MLIR  22.0.0git
Parser.h
Go to the documentation of this file.
1 //===- Parser.h - MLIR Parser Library Interface -----------------*- 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 is contains a unified interface for parsing serialized MLIR.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_PARSER_PARSER_H
14 #define MLIR_PARSER_PARSER_H
15 
16 #include "mlir/IR/AsmState.h"
17 #include "mlir/IR/Builders.h"
18 #include "mlir/IR/OwningOpRef.h"
19 #include <cstddef>
20 
21 namespace llvm {
22 class SourceMgr;
23 class SMDiagnostic;
24 class StringRef;
25 } // namespace llvm
26 
27 namespace mlir {
28 namespace detail {
29 
30 /// Given a block containing operations that have just been parsed, if the block
31 /// contains a single operation of `ContainerOpT` type then remove it from the
32 /// block and return it. If the block does not contain just that operation,
33 /// create a new operation instance of `ContainerOpT` and move all of the
34 /// operations within `parsedBlock` into the first block of the first region.
35 /// `ContainerOpT` is required to have a single region containing a single
36 /// block, and must implement the `SingleBlockImplicitTerminator` trait.
37 template <typename ContainerOpT>
39  Block *parsedBlock, MLIRContext *context, Location sourceFileLoc) {
40 
41  // Check to see if we parsed a single instance of this operation.
42  if (llvm::hasSingleElement(*parsedBlock)) {
43  if (ContainerOpT op = dyn_cast<ContainerOpT>(&parsedBlock->front())) {
44  op->remove();
45  return op;
46  }
47  }
48 
49  // If not, then build a new top-level op if a concrete operation type was
50  // specified.
51  if constexpr (std::is_same_v<ContainerOpT, Operation *>) {
52  (void)context;
53  return emitError(sourceFileLoc)
54  << "source must contain a single top-level operation, found: "
55  << parsedBlock->getOperations().size(),
56  nullptr;
57  } else {
58  static_assert(
59  ContainerOpT::template hasTrait<OpTrait::OneRegion>() &&
60  (ContainerOpT::template hasTrait<OpTrait::NoTerminator>() ||
61  OpTrait::template hasSingleBlockImplicitTerminator<
62  ContainerOpT>::value),
63  "Expected `ContainerOpT` to have a single region with a single "
64  "block that has an implicit terminator or does not require one");
65 
66  OpBuilder builder(context);
67  ContainerOpT op = ContainerOpT::create(builder, sourceFileLoc);
68  OwningOpRef<ContainerOpT> opRef(op);
69  assert(op->getNumRegions() == 1 && op->getRegion(0).hasOneBlock() &&
70  "expected generated operation to have a single region with a single "
71  "block");
72  Block *opBlock = &op->getRegion(0).front();
73  opBlock->getOperations().splice(opBlock->begin(),
74  parsedBlock->getOperations());
75 
76  // After splicing, verify just this operation to ensure it can properly
77  // contain the operations inside of it.
78  if (failed(op.verifyInvariants()))
80  return opRef;
81  }
82 }
83 } // namespace detail
84 
85 /// This parses the file specified by the indicated SourceMgr and appends parsed
86 /// operations to the given block. If the block is non-empty, the operations are
87 /// placed before the current terminator. If parsing is successful, success is
88 /// returned. Otherwise, an error message is emitted through the error handler
89 /// registered in the context, and failure is returned. If `sourceFileLoc` is
90 /// non-null, it is populated with a file location representing the start of the
91 /// source file that is being parsed.
92 LogicalResult parseSourceFile(const llvm::SourceMgr &sourceMgr, Block *block,
93  const ParserConfig &config,
94  LocationAttr *sourceFileLoc = nullptr);
95 /// An overload with a source manager that may have references taken during the
96 /// parsing process, and whose lifetime can be freely extended (such that the
97 /// source manager is not destroyed before the parsed IR). This is useful, for
98 /// example, to avoid copying some large resources into the MLIRContext and
99 /// instead referencing the data directly from the input buffers.
100 LogicalResult parseSourceFile(const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
101  Block *block, const ParserConfig &config,
102  LocationAttr *sourceFileLoc = nullptr);
103 
104 /// This parses the file specified by the indicated filename and appends parsed
105 /// operations to the given block. If the block is non-empty, the operations are
106 /// placed before the current terminator. If parsing is successful, success is
107 /// returned. Otherwise, an error message is emitted through the error handler
108 /// registered in the context, and failure is returned. If `sourceFileLoc` is
109 /// non-null, it is populated with a file location representing the start of the
110 /// source file that is being parsed.
111 LogicalResult parseSourceFile(llvm::StringRef filename, Block *block,
112  const ParserConfig &config,
113  LocationAttr *sourceFileLoc = nullptr);
114 
115 /// This parses the file specified by the indicated filename using the provided
116 /// SourceMgr and appends parsed operations to the given block. If the block is
117 /// non-empty, the operations are placed before the current terminator. If
118 /// parsing is successful, success is returned. Otherwise, an error message is
119 /// emitted through the error handler registered in the context, and failure is
120 /// returned. If `sourceFileLoc` is non-null, it is populated with a file
121 /// location representing the start of the source file that is being parsed.
122 LogicalResult parseSourceFile(llvm::StringRef filename,
123  llvm::SourceMgr &sourceMgr, Block *block,
124  const ParserConfig &config,
125  LocationAttr *sourceFileLoc = nullptr);
126 /// An overload with a source manager that may have references taken during the
127 /// parsing process, and whose lifetime can be freely extended (such that the
128 /// source manager is not destroyed before the parsed IR). This is useful, for
129 /// example, to avoid copying some large resources into the MLIRContext and
130 /// instead referencing the data directly from the input buffers.
131 LogicalResult parseSourceFile(llvm::StringRef filename,
132  const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
133  Block *block, const ParserConfig &config,
134  LocationAttr *sourceFileLoc = nullptr);
135 
136 /// This parses the IR string and appends parsed operations to the given block.
137 /// If the block is non-empty, the operations are placed before the current
138 /// terminator. If parsing is successful, success is returned. Otherwise, an
139 /// error message is emitted through the error handler registered in the
140 /// context, and failure is returned.
141 /// `sourceName` is used as the file name of the source; any IR without
142 /// locations will get a `FileLineColLoc` location with `sourceName` as the file
143 /// name. If `sourceFileLoc` is non-null, it is populated with a file location
144 /// representing the start of the source file that is being parsed.
145 LogicalResult parseSourceString(llvm::StringRef sourceStr, Block *block,
146  const ParserConfig &config,
147  StringRef sourceName = "",
148  LocationAttr *sourceFileLoc = nullptr);
149 
150 namespace detail {
151 /// The internal implementation of the templated `parseSourceFile` methods
152 /// below, that simply forwards to the non-templated version.
153 template <typename ContainerOpT, typename... ParserArgs>
155  ParserArgs &&...args) {
156  LocationAttr sourceFileLoc;
157  Block block;
158  if (failed(parseSourceFile(std::forward<ParserArgs>(args)..., &block, config,
159  &sourceFileLoc)))
160  return OwningOpRef<ContainerOpT>();
161  return detail::constructContainerOpForParserIfNecessary<ContainerOpT>(
162  &block, config.getContext(), sourceFileLoc);
163 }
164 } // namespace detail
165 
166 /// This parses the file specified by the indicated SourceMgr. If the source IR
167 /// contained a single instance of `ContainerOpT`, it is returned. Otherwise, a
168 /// new instance of `ContainerOpT` is constructed containing all of the parsed
169 /// operations. If parsing was not successful, null is returned and an error
170 /// message is emitted through the error handler registered in the context, and
171 /// failure is returned. `ContainerOpT` is required to have a single region
172 /// containing a single block, and must implement the
173 /// `SingleBlockImplicitTerminator` trait.
174 template <typename ContainerOpT = Operation *>
175 inline OwningOpRef<ContainerOpT>
176 parseSourceFile(const llvm::SourceMgr &sourceMgr, const ParserConfig &config) {
177  return detail::parseSourceFile<ContainerOpT>(config, sourceMgr);
178 }
179 /// An overload with a source manager that may have references taken during the
180 /// parsing process, and whose lifetime can be freely extended (such that the
181 /// source manager is not destroyed before the parsed IR). This is useful, for
182 /// example, to avoid copying some large resources into the MLIRContext and
183 /// instead referencing the data directly from the input buffers.
184 template <typename ContainerOpT = Operation *>
185 inline OwningOpRef<ContainerOpT>
186 parseSourceFile(const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
187  const ParserConfig &config) {
188  return detail::parseSourceFile<ContainerOpT>(config, sourceMgr);
189 }
190 
191 /// This parses the file specified by the indicated filename. If the source IR
192 /// contained a single instance of `ContainerOpT`, it is returned. Otherwise, a
193 /// new instance of `ContainerOpT` is constructed containing all of the parsed
194 /// operations. If parsing was not successful, null is returned and an error
195 /// message is emitted through the error handler registered in the context, and
196 /// failure is returned. `ContainerOpT` is required to have a single region
197 /// containing a single block, and must implement the
198 /// `SingleBlockImplicitTerminator` trait.
199 template <typename ContainerOpT = Operation *>
200 inline OwningOpRef<ContainerOpT> parseSourceFile(StringRef filename,
201  const ParserConfig &config) {
202  return detail::parseSourceFile<ContainerOpT>(config, filename);
203 }
204 
205 /// This parses the file specified by the indicated filename using the provided
206 /// SourceMgr. If the source IR contained a single instance of `ContainerOpT`,
207 /// it is returned. Otherwise, a new instance of `ContainerOpT` is constructed
208 /// containing all of the parsed operations. If parsing was not successful, null
209 /// is returned and an error message is emitted through the error handler
210 /// registered in the context, and failure is returned. `ContainerOpT` is
211 /// required to have a single region containing a single block, and must
212 /// implement the `SingleBlockImplicitTerminator` trait.
213 template <typename ContainerOpT = Operation *>
214 inline OwningOpRef<ContainerOpT> parseSourceFile(llvm::StringRef filename,
215  llvm::SourceMgr &sourceMgr,
216  const ParserConfig &config) {
217  return detail::parseSourceFile<ContainerOpT>(config, filename, sourceMgr);
218 }
219 /// An overload with a source manager that may have references taken during the
220 /// parsing process, and whose lifetime can be freely extended (such that the
221 /// source manager is not destroyed before the parsed IR). This is useful, for
222 /// example, to avoid copying some large resources into the MLIRContext and
223 /// instead referencing the data directly from the input buffers.
224 template <typename ContainerOpT = Operation *>
225 inline OwningOpRef<ContainerOpT>
226 parseSourceFile(llvm::StringRef filename,
227  const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
228  const ParserConfig &config) {
229  return detail::parseSourceFile<ContainerOpT>(config, filename, sourceMgr);
230 }
231 
232 /// This parses the provided string containing MLIR. If the source IR contained
233 /// a single instance of `ContainerOpT`, it is returned. Otherwise, a new
234 /// instance of `ContainerOpT` is constructed containing all of the parsed
235 /// operations. If parsing was not successful, null is returned and an error
236 /// message is emitted through the error handler registered in the context, and
237 /// failure is returned. `ContainerOpT` is required to have a single region
238 /// containing a single block, and must implement the
239 /// `SingleBlockImplicitTerminator` trait.
240 /// `sourceName` is used as the file name of the source; any IR without
241 /// locations will get a `FileLineColLoc` location with `sourceName` as the file
242 /// name.
243 template <typename ContainerOpT = Operation *>
244 inline OwningOpRef<ContainerOpT> parseSourceString(llvm::StringRef sourceStr,
245  const ParserConfig &config,
246  StringRef sourceName = "") {
247  LocationAttr sourceFileLoc;
248  Block block;
249  if (failed(parseSourceString(sourceStr, &block, config, sourceName,
250  &sourceFileLoc)))
251  return OwningOpRef<ContainerOpT>();
252  return detail::constructContainerOpForParserIfNecessary<ContainerOpT>(
253  &block, config.getContext(), sourceFileLoc);
254 }
255 
256 } // namespace mlir
257 
258 #endif // MLIR_PARSER_PARSER_H
Block represents an ordered list of Operations.
Definition: Block.h:33
OpListType & getOperations()
Definition: Block.h:137
Operation & front()
Definition: Block.h:153
iterator begin()
Definition: Block.h:143
Location objects represent source locations information in MLIR.
Definition: Location.h:32
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:63
This class helps build Operations.
Definition: Builders.h:205
This class acts as an owning reference to an op, and will automatically destroy the held op on destru...
Definition: OwningOpRef.h:29
This class represents a configuration for the MLIR assembly parser.
Definition: AsmState.h:469
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
OwningOpRef< ContainerOpT > constructContainerOpForParserIfNecessary(Block *parsedBlock, MLIRContext *context, Location sourceFileLoc)
Given a block containing operations that have just been parsed, if the block contains a single operat...
Definition: Parser.h:38
OwningOpRef< ContainerOpT > parseSourceFile(const ParserConfig &config, ParserArgs &&...args)
The internal implementation of the templated parseSourceFile methods below, that simply forwards to t...
Definition: Parser.h:154
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition: Remarks.h:491
Include the generated interface declarations.
const FrozenRewritePatternSet GreedyRewriteConfig config
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
LogicalResult parseSourceString(llvm::StringRef sourceStr, Block *block, const ParserConfig &config, StringRef sourceName="", LocationAttr *sourceFileLoc=nullptr)
This parses the IR string and appends parsed operations to the given block.
Definition: Parser.cpp:108
LogicalResult parseSourceFile(const llvm::SourceMgr &sourceMgr, Block *block, const ParserConfig &config, LocationAttr *sourceFileLoc=nullptr)
This parses the file specified by the indicated SourceMgr and appends parsed operations to the given ...
Definition: Parser.cpp:38