1 //===- AsmParserState.h -----------------------------------------*- 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 #ifndef MLIR_ASMPARSER_ASMPARSERSTATE_H 10 #define MLIR_ASMPARSER_ASMPARSERSTATE_H 11 12 #include "mlir/Support/LLVM.h" 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/Support/SMLoc.h" 16 #include <cstddef> 17 18 namespace mlir { 19 class Block; 20 class BlockArgument; 21 class FileLineColLoc; 22 class Operation; 23 class OperationName; 24 class SymbolRefAttr; 25 class Value; 26 27 /// This class represents state from a parsed MLIR textual format string. It is 28 /// useful for building additional analysis and language utilities on top of 29 /// textual MLIR. This should generally not be used for traditional compilation. 30 class AsmParserState { 31 public: 32 /// This class represents a definition within the source manager, containing 33 /// it's defining location and locations of any uses. SMDefinitions are only 34 /// provided for entities that have uses within an input file, e.g. SSA 35 /// values, Blocks, and Symbols. 36 struct SMDefinition { 37 SMDefinition() = default; SMDefinitionSMDefinition38 SMDefinition(SMRange loc) : loc(loc) {} 39 40 /// The source location of the definition. 41 SMRange loc; 42 /// The source location of all uses of the definition. 43 SmallVector<SMRange> uses; 44 }; 45 46 /// This class represents the information for an operation definition within 47 /// an input file. 48 struct OperationDefinition { 49 struct ResultGroupDefinition { ResultGroupDefinitionOperationDefinition::ResultGroupDefinition50 ResultGroupDefinition(unsigned index, SMRange loc) 51 : startIndex(index), definition(loc) {} 52 53 /// The result number that starts this group. 54 unsigned startIndex; 55 /// The source definition of the result group. 56 SMDefinition definition; 57 }; 58 OperationDefinitionOperationDefinition59 OperationDefinition(Operation *op, SMRange loc, SMLoc endLoc) 60 : op(op), loc(loc), scopeLoc(loc.Start, endLoc) {} 61 62 /// The operation representing this definition. 63 Operation *op; 64 65 /// The source location for the operation, i.e. the location of its name. 66 SMRange loc; 67 68 /// The full source range of the operation definition, i.e. a range 69 /// encompassing the start and end of the full operation definition. 70 SMRange scopeLoc; 71 72 /// Source definitions for any result groups of this operation. 73 SmallVector<ResultGroupDefinition> resultGroups; 74 75 /// If this operation is a symbol operation, this vector contains symbol 76 /// uses of this operation. 77 SmallVector<SMRange> symbolUses; 78 }; 79 80 /// This class represents the information for a block definition within the 81 /// input file. 82 struct BlockDefinition { 83 BlockDefinition(Block *block, SMRange loc = {}) blockBlockDefinition84 : block(block), definition(loc) {} 85 86 /// The block representing this definition. 87 Block *block; 88 89 /// The source location for the block, i.e. the location of its name, and 90 /// any uses it has. 91 SMDefinition definition; 92 93 /// Source definitions for any arguments of this block. 94 SmallVector<SMDefinition> arguments; 95 }; 96 97 AsmParserState(); 98 ~AsmParserState(); 99 AsmParserState &operator=(AsmParserState &&other); 100 101 //===--------------------------------------------------------------------===// 102 // Access State 103 //===--------------------------------------------------------------------===// 104 105 using BlockDefIterator = llvm::pointee_iterator< 106 ArrayRef<std::unique_ptr<BlockDefinition>>::iterator>; 107 using OperationDefIterator = llvm::pointee_iterator< 108 ArrayRef<std::unique_ptr<OperationDefinition>>::iterator>; 109 110 /// Return a range of the BlockDefinitions held by the current parser state. 111 iterator_range<BlockDefIterator> getBlockDefs() const; 112 113 /// Return the definition for the given block, or nullptr if the given 114 /// block does not have a definition. 115 const BlockDefinition *getBlockDef(Block *block) const; 116 117 /// Return a range of the OperationDefinitions held by the current parser 118 /// state. 119 iterator_range<OperationDefIterator> getOpDefs() const; 120 121 /// Return the definition for the given operation, or nullptr if the given 122 /// operation does not have a definition. 123 const OperationDefinition *getOpDef(Operation *op) const; 124 125 /// Returns (heuristically) the range of an identifier given a SMLoc 126 /// corresponding to the start of an identifier location. 127 static SMRange convertIdLocToRange(SMLoc loc); 128 129 //===--------------------------------------------------------------------===// 130 // Populate State 131 //===--------------------------------------------------------------------===// 132 133 /// Initialize the state in preparation for populating more parser state under 134 /// the given top-level operation. 135 void initialize(Operation *topLevelOp); 136 137 /// Finalize any in-progress parser state under the given top-level operation. 138 void finalize(Operation *topLevelOp); 139 140 /// Start a definition for an operation with the given name. 141 void startOperationDefinition(const OperationName &opName); 142 143 /// Finalize the most recently started operation definition. 144 void finalizeOperationDefinition( 145 Operation *op, SMRange nameLoc, SMLoc endLoc, 146 ArrayRef<std::pair<unsigned, SMLoc>> resultGroups = llvm::None); 147 148 /// Start a definition for a region nested under the current operation. 149 void startRegionDefinition(); 150 151 /// Finalize the most recently started region definition. 152 void finalizeRegionDefinition(); 153 154 /// Add a definition of the given entity. 155 void addDefinition(Block *block, SMLoc location); 156 void addDefinition(BlockArgument blockArg, SMLoc location); 157 158 /// Add a source uses of the given value. 159 void addUses(Value value, ArrayRef<SMLoc> locations); 160 void addUses(Block *block, ArrayRef<SMLoc> locations); 161 162 /// Add source uses for all the references nested under `refAttr`. The 163 /// provided `locations` should match 1-1 with the number of references in 164 /// `refAttr`, i.e.: 165 /// nestedReferences.size() + /*leafReference=*/1 == refLocations.size() 166 void addUses(SymbolRefAttr refAttr, ArrayRef<SMRange> refLocations); 167 168 /// Refine the `oldValue` to the `newValue`. This is used to indicate that 169 /// `oldValue` was a placeholder, and the uses of it should really refer to 170 /// `newValue`. 171 void refineDefinition(Value oldValue, Value newValue); 172 173 private: 174 struct Impl; 175 176 /// A pointer to the internal implementation of this class. 177 std::unique_ptr<Impl> impl; 178 }; 179 180 } // namespace mlir 181 182 #endif // MLIR_ASMPARSER_ASMPARSERSTATE_H 183