12 #include "llvm/ADT/StringExtras.h" 73 for (
auto &it : *opAndUseMapIt.second) {
76 opAndUseMapIt.first, it.first.cast<SymbolRefAttr>(), symbolOps)))
80 for (
const auto &symIt : llvm::zip(symbolOps, useRange)) {
83 operations[opIt->second]->symbolUses.push_back(std::get<1>(symIt));
97 impl = std::move(other.impl);
105 return llvm::make_pointee_range(llvm::makeArrayRef(
impl->blocks));
110 auto it =
impl->blocksToIdx.find(block);
111 return it ==
impl->blocksToIdx.end() ? nullptr : &*
impl->blocks[it->second];
115 return llvm::make_pointee_range(llvm::makeArrayRef(
impl->operations));
120 auto it =
impl->operationToIdx.find(op);
121 return it ==
impl->operationToIdx.end() ? nullptr
122 : &*
impl->operations[it->second];
129 while (
char c = *curPtr++) {
131 if (StringRef(
"\"\n\v\f").
contains(c))
137 if (*curPtr ==
'"' || *curPtr ==
'\\' || *curPtr ==
'n' || *curPtr ==
't')
139 else if (llvm::isHexDigit(*curPtr) && llvm::isHexDigit(curPtr[1]))
154 const char *curPtr = loc.getPointer();
157 if (*curPtr ==
'"') {
163 auto isIdentifierChar = [](
char c) {
164 return isalnum(c) || c ==
'$' || c ==
'.' || c ==
'_' || c ==
'-';
167 while (*curPtr && isIdentifierChar(*(++curPtr)))
171 return SMRange(loc, SMLoc::getFromPointer(curPtr));
182 if (partialOpDef.isSymbolTable())
183 impl->symbolUseScopes.push_back(partialOpDef.symbolTable.get());
187 assert(!
impl->partialOperations.empty() &&
188 "expected valid partial operation definition");
192 if (partialOpDef.isSymbolTable()) {
193 impl->symbolTableOperations.emplace_back(
194 topLevelOp, std::move(partialOpDef.symbolTable));
196 impl->resolveSymbolUses();
200 impl->partialOperations.emplace_back(opName);
204 Operation *op, SMRange nameLoc, SMLoc endLoc,
205 ArrayRef<std::pair<unsigned, SMLoc>> resultGroups) {
206 assert(!
impl->partialOperations.empty() &&
207 "expected valid partial operation definition");
211 std::unique_ptr<OperationDefinition> def =
212 std::make_unique<OperationDefinition>(op, nameLoc, endLoc);
213 for (
auto &resultGroup : resultGroups)
214 def->resultGroups.emplace_back(resultGroup.first,
216 impl->operationToIdx.try_emplace(op,
impl->operations.size());
217 impl->operations.emplace_back(std::move(def));
220 if (partialOpDef.isSymbolTable()) {
221 impl->symbolTableOperations.emplace_back(
222 op, std::move(partialOpDef.symbolTable));
227 assert(!
impl->partialOperations.empty() &&
228 "expected valid partial operation definition");
233 if (partialOpDef.isSymbolTable())
234 impl->symbolUseScopes.push_back(partialOpDef.symbolTable.get());
238 assert(!
impl->partialOperations.empty() &&
239 "expected valid partial operation definition");
244 if (partialOpDef.isSymbolTable())
245 impl->symbolUseScopes.pop_back();
249 auto it =
impl->blocksToIdx.find(block);
250 if (it ==
impl->blocksToIdx.end()) {
251 impl->blocksToIdx.try_emplace(block,
impl->blocks.size());
252 impl->blocks.emplace_back(std::make_unique<BlockDefinition>(
264 assert(it !=
impl->blocksToIdx.end() &&
265 "expected owner block to have an entry");
269 if (def.arguments.size() <= argIdx)
270 def.arguments.resize(argIdx + 1);
281 auto existingIt =
impl->operationToIdx.find(parentOp);
282 if (existingIt ==
impl->operationToIdx.end()) {
283 impl->placeholderValueUses[
value].append(locations.begin(),
291 unsigned resultNo = result.getResultNumber();
293 for (
auto &resultGroup : llvm::reverse(def.
resultGroups)) {
294 if (resultNo >= resultGroup.startIndex) {
295 for (SMLoc loc : locations)
300 llvm_unreachable(
"expected valid result group for value use");
305 auto existingIt =
impl->blocksToIdx.find(arg.
getOwner());
306 assert(existingIt !=
impl->blocksToIdx.end() &&
307 "expected valid block definition for block argument");
310 for (SMLoc loc : locations)
315 auto it =
impl->blocksToIdx.find(block);
316 if (it ==
impl->blocksToIdx.end()) {
317 it =
impl->blocksToIdx.try_emplace(block,
impl->blocks.size()).first;
318 impl->blocks.emplace_back(std::make_unique<BlockDefinition>(block));
322 for (SMLoc loc : locations)
329 if (
impl->symbolUseScopes.empty())
332 assert((refAttr.getNestedReferences().size() + 1) == locations.size() &&
333 "expected the same number of references as provided locations");
334 (*
impl->symbolUseScopes.back())[refAttr].emplace_back(locations.begin(),
339 auto it =
impl->placeholderValueUses.find(oldValue);
340 assert(it !=
impl->placeholderValueUses.end() &&
341 "expected `oldValue` to be a placeholder");
343 impl->placeholderValueUses.erase(oldValue);
iterator_range< BlockDefIterator > getBlockDefs() const
Return a range of the BlockDefinitions held by the current parser state.
Include the generated interface declarations.
DenseMap< Block *, unsigned > blocksToIdx
void finalizeOperationDefinition(Operation *op, SMRange nameLoc, SMLoc endLoc, ArrayRef< std::pair< unsigned, SMLoc >> resultGroups=llvm::None)
Finalize the most recently started operation definition.
SmallVector< ResultGroupDefinition > resultGroups
Source definitions for any result groups of this operation.
This class represents a definition within the source manager, containing it's defining location and l...
This class represents state from a parsed MLIR textual format string.
Operation is a basic unit of execution within MLIR.
static SMRange convertIdLocToRange(SMLoc loc)
Returns (heuristically) the range of an identifier given a SMLoc corresponding to the start of an ide...
std::unique_ptr< SymbolUseMap > symbolTable
If this operation is a symbol table, the following contains symbol uses within this operation...
This is a value defined by a result of an operation.
Block represents an ordered list of Operations.
const OperationDefinition * getOpDef(Operation *op) const
Return the definition for the given operation, or nullptr if the given operation does not have a defi...
void refineDefinition(Value oldValue, Value newValue)
Add source uses for all the references nested under refAttr.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
void finalize(Operation *topLevelOp)
Finalize any in-progress parser state under the given top-level operation.
void resolveSymbolUses()
Resolve any symbol table uses in the IR.
SmallVector< SMRange > uses
The source location of all uses of the definition.
SymbolTableCollection symbolTable
A symbol table containing all of the symbol table operations in the IR.
llvm::pointee_iterator< ArrayRef< std::unique_ptr< BlockDefinition > >::iterator > BlockDefIterator
void startOperationDefinition(const OperationName &opName)
Start a definition for an operation with the given name.
void addUses(Value value, ArrayRef< SMLoc > locations)
Add a source uses of the given value.
unsigned getArgNumber() const
Returns the number of this argument.
static constexpr const bool value
void startRegionDefinition()
Start a definition for a region nested under the current operation.
Block * getOwner() const
Returns the block that owns this argument.
bool hasTrait() const
Returns true if the operation was registered with a particular trait, e.g.
static const char * lexLocStringTok(const char *curPtr)
Lex a string token whose contents start at the given curPtr.
This class represents a collection of SymbolTables.
void addDefinition(Block *block, SMLoc location)
Add a definition of the given entity.
SmallVector< std::pair< Operation *, std::unique_ptr< SymbolUseMap > > > symbolTableOperations
The symbol table operations within the IR.
llvm::pointee_iterator< ArrayRef< std::unique_ptr< OperationDefinition > >::iterator > OperationDefIterator
SmallVector< PartialOpDef > partialOperations
A stack of partial operation definitions that have been started but not yet finalized.
A trait used to provide symbol table functionalities to a region operation.
SmallVector< SymbolUseMap * > symbolUseScopes
A stack of symbol use scopes.
PartialOpDef(const OperationName &opName)
static bool contains(SMRange range, SMLoc loc)
Returns true if the given range contains the given source location.
This class represents an argument of a Block.
This class represents the information for an operation definition within an input file...
This class represents the information for a block definition within the input file.
AsmParserState & operator=(AsmParserState &&other)
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
SMDefinition definition
The source location for the block, i.e.
bool isSymbolTable() const
Return if this operation is a symbol table.
void finalizeRegionDefinition()
Finalize the most recently started region definition.
iterator_range< OperationDefIterator > getOpDefs() const
Return a range of the OperationDefinitions held by the current parser state.
void initialize(Operation *topLevelOp)
Initialize the state in preparation for populating more parser state under the given top-level operat...
OperationName getName()
The name of an operation is the key identifier for it.
DenseMap< Operation *, unsigned > operationToIdx
const BlockDefinition * getBlockDef(Block *block) const
Return the definition for the given block, or nullptr if the given block does not have a definition...
SmallVector< std::unique_ptr< BlockDefinition > > blocks
A mapping from blocks in the input source file to their parser state.
DenseMap< Value, SmallVector< SMLoc > > placeholderValueUses
A set of value definitions that are placeholders for forward references.
SmallVector< std::unique_ptr< OperationDefinition > > operations
A mapping from operations in the input source file to their parser state.