MLIR  16.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  static_assert(
41  ContainerOpT::template hasTrait<OpTrait::OneRegion>() &&
42  (ContainerOpT::template hasTrait<OpTrait::NoTerminator>() ||
43  OpTrait::template hasSingleBlockImplicitTerminator<
44  ContainerOpT>::value),
45  "Expected `ContainerOpT` to have a single region with a single "
46  "block that has an implicit terminator or does not require one");
47 
48  // Check to see if we parsed a single instance of this operation.
49  if (llvm::hasSingleElement(*parsedBlock)) {
50  if (ContainerOpT op = dyn_cast<ContainerOpT>(parsedBlock->front())) {
51  op->remove();
52  return op;
53  }
54  }
55 
56  // If not, then build a new one to contain the parsed operations.
57  OpBuilder builder(context);
58  ContainerOpT op = builder.create<ContainerOpT>(sourceFileLoc);
59  OwningOpRef<ContainerOpT> opRef(op);
60  assert(op->getNumRegions() == 1 && llvm::hasSingleElement(op->getRegion(0)) &&
61  "expected generated operation to have a single region with a single "
62  "block");
63  Block *opBlock = &op->getRegion(0).front();
64  opBlock->getOperations().splice(opBlock->begin(),
65  parsedBlock->getOperations());
66 
67  // After splicing, verify just this operation to ensure it can properly
68  // contain the operations inside of it.
69  if (failed(op.verifyInvariants()))
71  return opRef;
72 }
73 } // namespace detail
74 
75 /// This parses the file specified by the indicated SourceMgr and appends parsed
76 /// operations to the given block. If the block is non-empty, the operations are
77 /// placed before the current terminator. If parsing is successful, success is
78 /// returned. Otherwise, an error message is emitted through the error handler
79 /// registered in the context, and failure is returned. If `sourceFileLoc` is
80 /// non-null, it is populated with a file location representing the start of the
81 /// source file that is being parsed.
82 LogicalResult parseSourceFile(const llvm::SourceMgr &sourceMgr, Block *block,
83  const ParserConfig &config,
84  LocationAttr *sourceFileLoc = nullptr);
85 
86 /// This parses the file specified by the indicated filename and appends parsed
87 /// operations to the given block. If the block is non-empty, the operations are
88 /// placed before the current terminator. If parsing is successful, success is
89 /// returned. Otherwise, an error message is emitted through the error handler
90 /// registered in the context, and failure is returned. If `sourceFileLoc` is
91 /// non-null, it is populated with a file location representing the start of the
92 /// source file that is being parsed.
93 LogicalResult parseSourceFile(llvm::StringRef filename, Block *block,
94  const ParserConfig &config,
95  LocationAttr *sourceFileLoc = nullptr);
96 
97 /// This parses the file specified by the indicated filename using the provided
98 /// SourceMgr and appends parsed operations to the given block. If the block is
99 /// non-empty, the operations are placed before the current terminator. If
100 /// parsing is successful, success is returned. Otherwise, an error message is
101 /// emitted through the error handler registered in the context, and failure is
102 /// returned. If `sourceFileLoc` is non-null, it is populated with a file
103 /// location representing the start of the source file that is being parsed.
104 LogicalResult parseSourceFile(llvm::StringRef filename,
105  llvm::SourceMgr &sourceMgr, Block *block,
106  const ParserConfig &config,
107  LocationAttr *sourceFileLoc = nullptr);
108 
109 /// This parses the IR string and appends parsed operations to the given block.
110 /// If the block is non-empty, the operations are placed before the current
111 /// terminator. If parsing is successful, success is returned. Otherwise, an
112 /// error message is emitted through the error handler registered in the
113 /// context, and failure is returned. If `sourceFileLoc` is non-null, it is
114 /// populated with a file location representing the start of the source file
115 /// that is being parsed.
116 LogicalResult parseSourceString(llvm::StringRef sourceStr, Block *block,
117  const ParserConfig &config,
118  LocationAttr *sourceFileLoc = nullptr);
119 
120 namespace detail {
121 /// The internal implementation of the templated `parseSourceFile` methods
122 /// below, that simply forwards to the non-templated version.
123 template <typename ContainerOpT, typename... ParserArgs>
125  ParserArgs &&...args) {
126  LocationAttr sourceFileLoc;
127  Block block;
128  if (failed(parseSourceFile(std::forward<ParserArgs>(args)..., &block, config,
129  &sourceFileLoc)))
130  return OwningOpRef<ContainerOpT>();
131  return detail::constructContainerOpForParserIfNecessary<ContainerOpT>(
132  &block, config.getContext(), sourceFileLoc);
133 }
134 } // namespace detail
135 
136 /// This parses the file specified by the indicated SourceMgr. If the source IR
137 /// contained a single instance of `ContainerOpT`, it is returned. Otherwise, a
138 /// new instance of `ContainerOpT` is constructed containing all of the parsed
139 /// operations. If parsing was not successful, null is returned and an error
140 /// message is emitted through the error handler registered in the context, and
141 /// failure is returned. `ContainerOpT` is required to have a single region
142 /// containing a single block, and must implement the
143 /// `SingleBlockImplicitTerminator` trait.
144 template <typename ContainerOpT>
146 parseSourceFile(const llvm::SourceMgr &sourceMgr, const ParserConfig &config) {
147  return detail::parseSourceFile<ContainerOpT>(config, sourceMgr);
148 }
149 
150 /// This parses the file specified by the indicated filename. If the source IR
151 /// contained a single instance of `ContainerOpT`, it is returned. Otherwise, a
152 /// new instance of `ContainerOpT` is constructed containing all of the parsed
153 /// operations. If parsing was not successful, null is returned and an error
154 /// message is emitted through the error handler registered in the context, and
155 /// failure is returned. `ContainerOpT` is required to have a single region
156 /// containing a single block, and must implement the
157 /// `SingleBlockImplicitTerminator` trait.
158 template <typename ContainerOpT>
159 inline OwningOpRef<ContainerOpT> parseSourceFile(StringRef filename,
160  const ParserConfig &config) {
161  return detail::parseSourceFile<ContainerOpT>(config, filename);
162 }
163 
164 /// This parses the file specified by the indicated filename using the provided
165 /// SourceMgr. If the source IR contained a single instance of `ContainerOpT`,
166 /// it is returned. Otherwise, a new instance of `ContainerOpT` is constructed
167 /// containing all of the parsed operations. If parsing was not successful, null
168 /// is returned and an error message is emitted through the error handler
169 /// registered in the context, and failure is returned. `ContainerOpT` is
170 /// required to have a single region containing a single block, and must
171 /// implement the `SingleBlockImplicitTerminator` trait.
172 template <typename ContainerOpT>
173 inline OwningOpRef<ContainerOpT> parseSourceFile(llvm::StringRef filename,
174  llvm::SourceMgr &sourceMgr,
175  const ParserConfig &config) {
176  return detail::parseSourceFile<ContainerOpT>(config, filename, sourceMgr);
177 }
178 
179 /// This parses the provided string containing MLIR. If the source IR contained
180 /// a single instance of `ContainerOpT`, it is returned. Otherwise, a new
181 /// instance of `ContainerOpT` is constructed containing all of the parsed
182 /// operations. If parsing was not successful, null is returned and an error
183 /// message is emitted through the error handler registered in the context, and
184 /// failure is returned. `ContainerOpT` is required to have a single region
185 /// containing a single block, and must implement the
186 /// `SingleBlockImplicitTerminator` trait.
187 template <typename ContainerOpT>
188 inline OwningOpRef<ContainerOpT> parseSourceString(llvm::StringRef sourceStr,
189  const ParserConfig &config) {
190  LocationAttr sourceFileLoc;
191  Block block;
192  if (failed(parseSourceString(sourceStr, &block, config, &sourceFileLoc)))
193  return OwningOpRef<ContainerOpT>();
194  return detail::constructContainerOpForParserIfNecessary<ContainerOpT>(
195  &block, config.getContext(), sourceFileLoc);
196 }
197 
198 } // namespace mlir
199 
200 #endif // MLIR_PARSER_PARSER_H
Include the generated interface declarations.
iterator begin()
Definition: Block.h:134
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:221
OwningOpRef< ContainerOpT > parseSourceString(llvm::StringRef sourceStr, const ParserConfig &config)
This parses the provided string containing MLIR.
Definition: Parser.h:188
Block represents an ordered list of Operations.
Definition: Block.h:29
MLIRContext * getContext() const
Return the MLIRContext to be used when parsing.
Definition: AsmState.h:402
OpListType & getOperations()
Definition: Block.h:128
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
Definition: LogicalResult.h:72
Location objects represent source locations information in MLIR.
Definition: Location.h:31
Operation & front()
Definition: Block.h:144
static constexpr const bool value
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Definition: Builders.cpp:404
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
OwningOpRef< ContainerOpT > parseSourceFile(llvm::StringRef filename, llvm::SourceMgr &sourceMgr, const ParserConfig &config)
This parses the file specified by the indicated filename using the provided SourceMgr.
Definition: Parser.h:173
This class represents a configuration for the MLIR assembly parser.
Definition: AsmState.h:395
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
This class acts as an owning reference to an op, and will automatically destroy the held op on destru...
Definition: OwningOpRef.h:27
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
This class helps build Operations.
Definition: Builders.h:192