1 //===- Parser.cpp - MLIR Parser Implementation ----------------------------===// 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 implements the parser for the MLIR textual form. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "Parser.h" 14 #include "AsmParserImpl.h" 15 #include "mlir/IR/AffineMap.h" 16 #include "mlir/IR/AsmState.h" 17 #include "mlir/IR/BuiltinOps.h" 18 #include "mlir/IR/Dialect.h" 19 #include "mlir/IR/Verifier.h" 20 #include "mlir/Parser/AsmParserState.h" 21 #include "mlir/Parser/Parser.h" 22 #include "llvm/ADT/DenseMap.h" 23 #include "llvm/ADT/ScopeExit.h" 24 #include "llvm/ADT/StringSet.h" 25 #include "llvm/ADT/bit.h" 26 #include "llvm/Support/PrettyStackTrace.h" 27 #include "llvm/Support/SourceMgr.h" 28 #include <algorithm> 29 30 using namespace mlir; 31 using namespace mlir::detail; 32 using llvm::MemoryBuffer; 33 using llvm::SourceMgr; 34 35 //===----------------------------------------------------------------------===// 36 // Parser 37 //===----------------------------------------------------------------------===// 38 39 /// Parse a list of comma-separated items with an optional delimiter. If a 40 /// delimiter is provided, then an empty list is allowed. If not, then at 41 /// least one element will be parsed. 42 ParseResult 43 Parser::parseCommaSeparatedList(Delimiter delimiter, 44 function_ref<ParseResult()> parseElementFn, 45 StringRef contextMessage) { 46 switch (delimiter) { 47 case Delimiter::None: 48 break; 49 case Delimiter::OptionalParen: 50 if (getToken().isNot(Token::l_paren)) 51 return success(); 52 LLVM_FALLTHROUGH; 53 case Delimiter::Paren: 54 if (parseToken(Token::l_paren, "expected '('" + contextMessage)) 55 return failure(); 56 // Check for empty list. 57 if (consumeIf(Token::r_paren)) 58 return success(); 59 break; 60 case Delimiter::OptionalLessGreater: 61 // Check for absent list. 62 if (getToken().isNot(Token::less)) 63 return success(); 64 LLVM_FALLTHROUGH; 65 case Delimiter::LessGreater: 66 if (parseToken(Token::less, "expected '<'" + contextMessage)) 67 return success(); 68 // Check for empty list. 69 if (consumeIf(Token::greater)) 70 return success(); 71 break; 72 case Delimiter::OptionalSquare: 73 if (getToken().isNot(Token::l_square)) 74 return success(); 75 LLVM_FALLTHROUGH; 76 case Delimiter::Square: 77 if (parseToken(Token::l_square, "expected '['" + contextMessage)) 78 return failure(); 79 // Check for empty list. 80 if (consumeIf(Token::r_square)) 81 return success(); 82 break; 83 case Delimiter::OptionalBraces: 84 if (getToken().isNot(Token::l_brace)) 85 return success(); 86 LLVM_FALLTHROUGH; 87 case Delimiter::Braces: 88 if (parseToken(Token::l_brace, "expected '{'" + contextMessage)) 89 return failure(); 90 // Check for empty list. 91 if (consumeIf(Token::r_brace)) 92 return success(); 93 break; 94 } 95 96 // Non-empty case starts with an element. 97 if (parseElementFn()) 98 return failure(); 99 100 // Otherwise we have a list of comma separated elements. 101 while (consumeIf(Token::comma)) { 102 if (parseElementFn()) 103 return failure(); 104 } 105 106 switch (delimiter) { 107 case Delimiter::None: 108 return success(); 109 case Delimiter::OptionalParen: 110 case Delimiter::Paren: 111 return parseToken(Token::r_paren, "expected ')'" + contextMessage); 112 case Delimiter::OptionalLessGreater: 113 case Delimiter::LessGreater: 114 return parseToken(Token::greater, "expected '>'" + contextMessage); 115 case Delimiter::OptionalSquare: 116 case Delimiter::Square: 117 return parseToken(Token::r_square, "expected ']'" + contextMessage); 118 case Delimiter::OptionalBraces: 119 case Delimiter::Braces: 120 return parseToken(Token::r_brace, "expected '}'" + contextMessage); 121 } 122 llvm_unreachable("Unknown delimiter"); 123 } 124 125 /// Parse a comma-separated list of elements, terminated with an arbitrary 126 /// token. This allows empty lists if allowEmptyList is true. 127 /// 128 /// abstract-list ::= rightToken // if allowEmptyList == true 129 /// abstract-list ::= element (',' element)* rightToken 130 /// 131 ParseResult 132 Parser::parseCommaSeparatedListUntil(Token::Kind rightToken, 133 function_ref<ParseResult()> parseElement, 134 bool allowEmptyList) { 135 // Handle the empty case. 136 if (getToken().is(rightToken)) { 137 if (!allowEmptyList) 138 return emitWrongTokenError("expected list element"); 139 consumeToken(rightToken); 140 return success(); 141 } 142 143 if (parseCommaSeparatedList(parseElement) || 144 parseToken(rightToken, "expected ',' or '" + 145 Token::getTokenSpelling(rightToken) + "'")) 146 return failure(); 147 148 return success(); 149 } 150 151 InFlightDiagnostic Parser::emitError(const Twine &message) { 152 auto loc = state.curToken.getLoc(); 153 if (state.curToken.isNot(Token::eof)) 154 return emitError(loc, message); 155 156 // If the error is to be emitted at EOF, move it back one character. 157 return emitError(SMLoc::getFromPointer(loc.getPointer() - 1), message); 158 } 159 160 InFlightDiagnostic Parser::emitError(SMLoc loc, const Twine &message) { 161 auto diag = mlir::emitError(getEncodedSourceLocation(loc), message); 162 163 // If we hit a parse error in response to a lexer error, then the lexer 164 // already reported the error. 165 if (getToken().is(Token::error)) 166 diag.abandon(); 167 return diag; 168 } 169 170 /// Emit an error about a "wrong token". If the current token is at the 171 /// start of a source line, this will apply heuristics to back up and report 172 /// the error at the end of the previous line, which is where the expected 173 /// token is supposed to be. 174 InFlightDiagnostic Parser::emitWrongTokenError(const Twine &message) { 175 auto loc = state.curToken.getLoc(); 176 177 // If the error is to be emitted at EOF, move it back one character. 178 if (state.curToken.is(Token::eof)) 179 loc = SMLoc::getFromPointer(loc.getPointer() - 1); 180 181 // This is the location we were originally asked to report the error at. 182 auto originalLoc = loc; 183 184 // Determine if the token is at the start of the current line. 185 const char *bufferStart = state.lex.getBufferBegin(); 186 const char *curPtr = loc.getPointer(); 187 188 // Use this StringRef to keep track of what we are going to back up through, 189 // it provides nicer string search functions etc. 190 StringRef startOfBuffer(bufferStart, curPtr - bufferStart); 191 192 // Back up over entirely blank lines. 193 while (true) { 194 // Back up until we see a \n, but don't look past the buffer start. 195 startOfBuffer = startOfBuffer.rtrim(" \t"); 196 197 // For tokens with no preceding source line, just emit at the original 198 // location. 199 if (startOfBuffer.empty()) 200 return emitError(originalLoc, message); 201 202 // If we found something that isn't the end of line, then we're done. 203 if (startOfBuffer.back() != '\n' && startOfBuffer.back() != '\r') 204 return emitError(SMLoc::getFromPointer(startOfBuffer.end()), message); 205 206 // Drop the \n so we emit the diagnostic at the end of the line. 207 startOfBuffer = startOfBuffer.drop_back(); 208 209 // Check to see if the preceding line has a comment on it. We assume that a 210 // `//` is the start of a comment, which is mostly correct. 211 // TODO: This will do the wrong thing for // in a string literal. 212 auto prevLine = startOfBuffer; 213 size_t newLineIndex = prevLine.find_last_of("\n\r"); 214 if (newLineIndex != StringRef::npos) 215 prevLine = prevLine.drop_front(newLineIndex); 216 217 // If we find a // in the current line, then emit the diagnostic before it. 218 size_t commentStart = prevLine.find("//"); 219 if (commentStart != StringRef::npos) 220 startOfBuffer = startOfBuffer.drop_back(prevLine.size() - commentStart); 221 } 222 } 223 224 /// Consume the specified token if present and return success. On failure, 225 /// output a diagnostic and return failure. 226 ParseResult Parser::parseToken(Token::Kind expectedToken, 227 const Twine &message) { 228 if (consumeIf(expectedToken)) 229 return success(); 230 return emitWrongTokenError(message); 231 } 232 233 /// Parse an optional integer value from the stream. 234 OptionalParseResult Parser::parseOptionalInteger(APInt &result) { 235 Token curToken = getToken(); 236 if (curToken.isNot(Token::integer, Token::minus)) 237 return llvm::None; 238 239 bool negative = consumeIf(Token::minus); 240 Token curTok = getToken(); 241 if (parseToken(Token::integer, "expected integer value")) 242 return failure(); 243 244 StringRef spelling = curTok.getSpelling(); 245 bool isHex = spelling.size() > 1 && spelling[1] == 'x'; 246 if (spelling.getAsInteger(isHex ? 0 : 10, result)) 247 return emitError(curTok.getLoc(), "integer value too large"); 248 249 // Make sure we have a zero at the top so we return the right signedness. 250 if (result.isNegative()) 251 result = result.zext(result.getBitWidth() + 1); 252 253 // Process the negative sign if present. 254 if (negative) 255 result.negate(); 256 257 return success(); 258 } 259 260 /// Parse a floating point value from an integer literal token. 261 ParseResult Parser::parseFloatFromIntegerLiteral( 262 Optional<APFloat> &result, const Token &tok, bool isNegative, 263 const llvm::fltSemantics &semantics, size_t typeSizeInBits) { 264 SMLoc loc = tok.getLoc(); 265 StringRef spelling = tok.getSpelling(); 266 bool isHex = spelling.size() > 1 && spelling[1] == 'x'; 267 if (!isHex) { 268 return emitError(loc, "unexpected decimal integer literal for a " 269 "floating point value") 270 .attachNote() 271 << "add a trailing dot to make the literal a float"; 272 } 273 if (isNegative) { 274 return emitError(loc, "hexadecimal float literal should not have a " 275 "leading minus"); 276 } 277 278 Optional<uint64_t> value = tok.getUInt64IntegerValue(); 279 if (!value) 280 return emitError(loc, "hexadecimal float constant out of range for type"); 281 282 if (&semantics == &APFloat::IEEEdouble()) { 283 result = APFloat(semantics, APInt(typeSizeInBits, *value)); 284 return success(); 285 } 286 287 APInt apInt(typeSizeInBits, *value); 288 if (apInt != *value) 289 return emitError(loc, "hexadecimal float constant out of range for type"); 290 result = APFloat(semantics, apInt); 291 292 return success(); 293 } 294 295 ParseResult Parser::parseOptionalKeyword(StringRef *keyword) { 296 // Check that the current token is a keyword. 297 if (!isCurrentTokenAKeyword()) 298 return failure(); 299 300 *keyword = getTokenSpelling(); 301 consumeToken(); 302 return success(); 303 } 304 305 //===----------------------------------------------------------------------===// 306 // Resource Parsing 307 308 FailureOr<AsmDialectResourceHandle> 309 Parser::parseResourceHandle(const OpAsmDialectInterface *dialect, 310 StringRef &name) { 311 assert(dialect && "expected valid dialect interface"); 312 SMLoc nameLoc = getToken().getLoc(); 313 if (failed(parseOptionalKeyword(&name))) 314 return emitError("expected identifier key for 'resource' entry"); 315 auto &resources = getState().symbols.dialectResources; 316 317 // If this is the first time encountering this handle, ask the dialect to 318 // resolve a reference to this handle. This allows for us to remap the name of 319 // the handle if necessary. 320 std::pair<std::string, AsmDialectResourceHandle> &entry = 321 resources[dialect][name]; 322 if (entry.first.empty()) { 323 FailureOr<AsmDialectResourceHandle> result = dialect->declareResource(name); 324 if (failed(result)) { 325 return emitError(nameLoc) 326 << "unknown 'resource' key '" << name << "' for dialect '" 327 << dialect->getDialect()->getNamespace() << "'"; 328 } 329 entry.first = dialect->getResourceKey(*result); 330 entry.second = *result; 331 } 332 333 name = entry.first; 334 return entry.second; 335 } 336 337 //===----------------------------------------------------------------------===// 338 // OperationParser 339 //===----------------------------------------------------------------------===// 340 341 namespace { 342 /// This class provides support for parsing operations and regions of 343 /// operations. 344 class OperationParser : public Parser { 345 public: 346 OperationParser(ParserState &state, ModuleOp topLevelOp); 347 ~OperationParser(); 348 349 /// After parsing is finished, this function must be called to see if there 350 /// are any remaining issues. 351 ParseResult finalize(); 352 353 //===--------------------------------------------------------------------===// 354 // SSA Value Handling 355 //===--------------------------------------------------------------------===// 356 357 using UnresolvedOperand = OpAsmParser::UnresolvedOperand; 358 using Argument = OpAsmParser::Argument; 359 360 struct DeferredLocInfo { 361 SMLoc loc; 362 StringRef identifier; 363 }; 364 365 /// Push a new SSA name scope to the parser. 366 void pushSSANameScope(bool isIsolated); 367 368 /// Pop the last SSA name scope from the parser. 369 ParseResult popSSANameScope(); 370 371 /// Register a definition of a value with the symbol table. 372 ParseResult addDefinition(UnresolvedOperand useInfo, Value value); 373 374 /// Parse an optional list of SSA uses into 'results'. 375 ParseResult 376 parseOptionalSSAUseList(SmallVectorImpl<UnresolvedOperand> &results); 377 378 /// Parse a single SSA use into 'result'. If 'allowResultNumber' is true then 379 /// we allow #42 syntax. 380 ParseResult parseSSAUse(UnresolvedOperand &result, 381 bool allowResultNumber = true); 382 383 /// Given a reference to an SSA value and its type, return a reference. This 384 /// returns null on failure. 385 Value resolveSSAUse(UnresolvedOperand useInfo, Type type); 386 387 ParseResult parseSSADefOrUseAndType( 388 function_ref<ParseResult(UnresolvedOperand, Type)> action); 389 390 ParseResult parseOptionalSSAUseAndTypeList(SmallVectorImpl<Value> &results); 391 392 /// Return the location of the value identified by its name and number if it 393 /// has been already reference. 394 Optional<SMLoc> getReferenceLoc(StringRef name, unsigned number) { 395 auto &values = isolatedNameScopes.back().values; 396 if (!values.count(name) || number >= values[name].size()) 397 return {}; 398 if (values[name][number].value) 399 return values[name][number].loc; 400 return {}; 401 } 402 403 //===--------------------------------------------------------------------===// 404 // Operation Parsing 405 //===--------------------------------------------------------------------===// 406 407 /// Parse an operation instance. 408 ParseResult parseOperation(); 409 410 /// Parse a single operation successor. 411 ParseResult parseSuccessor(Block *&dest); 412 413 /// Parse a comma-separated list of operation successors in brackets. 414 ParseResult parseSuccessors(SmallVectorImpl<Block *> &destinations); 415 416 /// Parse an operation instance that is in the generic form. 417 Operation *parseGenericOperation(); 418 419 /// Parse different components, viz., use-info of operand(s), successor(s), 420 /// region(s), attribute(s) and function-type, of the generic form of an 421 /// operation instance and populate the input operation-state 'result' with 422 /// those components. If any of the components is explicitly provided, then 423 /// skip parsing that component. 424 ParseResult parseGenericOperationAfterOpName( 425 OperationState &result, 426 Optional<ArrayRef<UnresolvedOperand>> parsedOperandUseInfo = llvm::None, 427 Optional<ArrayRef<Block *>> parsedSuccessors = llvm::None, 428 Optional<MutableArrayRef<std::unique_ptr<Region>>> parsedRegions = 429 llvm::None, 430 Optional<ArrayRef<NamedAttribute>> parsedAttributes = llvm::None, 431 Optional<FunctionType> parsedFnType = llvm::None); 432 433 /// Parse an operation instance that is in the generic form and insert it at 434 /// the provided insertion point. 435 Operation *parseGenericOperation(Block *insertBlock, 436 Block::iterator insertPt); 437 438 /// This type is used to keep track of things that are either an Operation or 439 /// a BlockArgument. We cannot use Value for this, because not all Operations 440 /// have results. 441 using OpOrArgument = llvm::PointerUnion<Operation *, BlockArgument>; 442 443 /// Parse an optional trailing location and add it to the specifier Operation 444 /// or `UnresolvedOperand` if present. 445 /// 446 /// trailing-location ::= (`loc` (`(` location `)` | attribute-alias))? 447 /// 448 ParseResult parseTrailingLocationSpecifier(OpOrArgument opOrArgument); 449 450 /// Parse a location alias, that is a sequence looking like: #loc42 451 /// The alias may have already be defined or may be defined later, in which 452 /// case an OpaqueLoc is used a placeholder. 453 ParseResult parseLocationAlias(LocationAttr &loc); 454 455 /// This is the structure of a result specifier in the assembly syntax, 456 /// including the name, number of results, and location. 457 using ResultRecord = std::tuple<StringRef, unsigned, SMLoc>; 458 459 /// Parse an operation instance that is in the op-defined custom form. 460 /// resultInfo specifies information about the "%name =" specifiers. 461 Operation *parseCustomOperation(ArrayRef<ResultRecord> resultIDs); 462 463 /// Parse the name of an operation, in the custom form. On success, return a 464 /// an object of type 'OperationName'. Otherwise, failure is returned. 465 FailureOr<OperationName> parseCustomOperationName(); 466 467 //===--------------------------------------------------------------------===// 468 // Region Parsing 469 //===--------------------------------------------------------------------===// 470 471 /// Parse a region into 'region' with the provided entry block arguments. 472 /// 'isIsolatedNameScope' indicates if the naming scope of this region is 473 /// isolated from those above. 474 ParseResult parseRegion(Region ®ion, ArrayRef<Argument> entryArguments, 475 bool isIsolatedNameScope = false); 476 477 /// Parse a region body into 'region'. 478 ParseResult parseRegionBody(Region ®ion, SMLoc startLoc, 479 ArrayRef<Argument> entryArguments, 480 bool isIsolatedNameScope); 481 482 //===--------------------------------------------------------------------===// 483 // Block Parsing 484 //===--------------------------------------------------------------------===// 485 486 /// Parse a new block into 'block'. 487 ParseResult parseBlock(Block *&block); 488 489 /// Parse a list of operations into 'block'. 490 ParseResult parseBlockBody(Block *block); 491 492 /// Parse a (possibly empty) list of block arguments. 493 ParseResult parseOptionalBlockArgList(Block *owner); 494 495 /// Get the block with the specified name, creating it if it doesn't 496 /// already exist. The location specified is the point of use, which allows 497 /// us to diagnose references to blocks that are not defined precisely. 498 Block *getBlockNamed(StringRef name, SMLoc loc); 499 500 private: 501 /// This class represents a definition of a Block. 502 struct BlockDefinition { 503 /// A pointer to the defined Block. 504 Block *block; 505 /// The location that the Block was defined at. 506 SMLoc loc; 507 }; 508 /// This class represents a definition of a Value. 509 struct ValueDefinition { 510 /// A pointer to the defined Value. 511 Value value; 512 /// The location that the Value was defined at. 513 SMLoc loc; 514 }; 515 516 /// Returns the info for a block at the current scope for the given name. 517 BlockDefinition &getBlockInfoByName(StringRef name) { 518 return blocksByName.back()[name]; 519 } 520 521 /// Insert a new forward reference to the given block. 522 void insertForwardRef(Block *block, SMLoc loc) { 523 forwardRef.back().try_emplace(block, loc); 524 } 525 526 /// Erase any forward reference to the given block. 527 bool eraseForwardRef(Block *block) { return forwardRef.back().erase(block); } 528 529 /// Record that a definition was added at the current scope. 530 void recordDefinition(StringRef def); 531 532 /// Get the value entry for the given SSA name. 533 SmallVectorImpl<ValueDefinition> &getSSAValueEntry(StringRef name); 534 535 /// Create a forward reference placeholder value with the given location and 536 /// result type. 537 Value createForwardRefPlaceholder(SMLoc loc, Type type); 538 539 /// Return true if this is a forward reference. 540 bool isForwardRefPlaceholder(Value value) { 541 return forwardRefPlaceholders.count(value); 542 } 543 544 /// This struct represents an isolated SSA name scope. This scope may contain 545 /// other nested non-isolated scopes. These scopes are used for operations 546 /// that are known to be isolated to allow for reusing names within their 547 /// regions, even if those names are used above. 548 struct IsolatedSSANameScope { 549 /// Record that a definition was added at the current scope. 550 void recordDefinition(StringRef def) { 551 definitionsPerScope.back().insert(def); 552 } 553 554 /// Push a nested name scope. 555 void pushSSANameScope() { definitionsPerScope.push_back({}); } 556 557 /// Pop a nested name scope. 558 void popSSANameScope() { 559 for (auto &def : definitionsPerScope.pop_back_val()) 560 values.erase(def.getKey()); 561 } 562 563 /// This keeps track of all of the SSA values we are tracking for each name 564 /// scope, indexed by their name. This has one entry per result number. 565 llvm::StringMap<SmallVector<ValueDefinition, 1>> values; 566 567 /// This keeps track of all of the values defined by a specific name scope. 568 SmallVector<llvm::StringSet<>, 2> definitionsPerScope; 569 }; 570 571 /// A list of isolated name scopes. 572 SmallVector<IsolatedSSANameScope, 2> isolatedNameScopes; 573 574 /// This keeps track of the block names as well as the location of the first 575 /// reference for each nested name scope. This is used to diagnose invalid 576 /// block references and memorize them. 577 SmallVector<DenseMap<StringRef, BlockDefinition>, 2> blocksByName; 578 SmallVector<DenseMap<Block *, SMLoc>, 2> forwardRef; 579 580 /// These are all of the placeholders we've made along with the location of 581 /// their first reference, to allow checking for use of undefined values. 582 DenseMap<Value, SMLoc> forwardRefPlaceholders; 583 584 /// Deffered locations: when parsing `loc(#loc42)` we add an entry to this 585 /// map. After parsing the definition `#loc42 = ...` we'll patch back users 586 /// of this location. 587 std::vector<DeferredLocInfo> deferredLocsReferences; 588 589 /// The builder used when creating parsed operation instances. 590 OpBuilder opBuilder; 591 592 /// The top level operation that holds all of the parsed operations. 593 Operation *topLevelOp; 594 }; 595 } // namespace 596 597 MLIR_DECLARE_EXPLICIT_TYPE_ID(OperationParser::DeferredLocInfo *) 598 MLIR_DEFINE_EXPLICIT_TYPE_ID(OperationParser::DeferredLocInfo *) 599 600 OperationParser::OperationParser(ParserState &state, ModuleOp topLevelOp) 601 : Parser(state), opBuilder(topLevelOp.getRegion()), topLevelOp(topLevelOp) { 602 // The top level operation starts a new name scope. 603 pushSSANameScope(/*isIsolated=*/true); 604 605 // If we are populating the parser state, prepare it for parsing. 606 if (state.asmState) 607 state.asmState->initialize(topLevelOp); 608 } 609 610 OperationParser::~OperationParser() { 611 for (auto &fwd : forwardRefPlaceholders) { 612 // Drop all uses of undefined forward declared reference and destroy 613 // defining operation. 614 fwd.first.dropAllUses(); 615 fwd.first.getDefiningOp()->destroy(); 616 } 617 for (const auto &scope : forwardRef) { 618 for (const auto &fwd : scope) { 619 // Delete all blocks that were created as forward references but never 620 // included into a region. 621 fwd.first->dropAllUses(); 622 delete fwd.first; 623 } 624 } 625 } 626 627 /// After parsing is finished, this function must be called to see if there are 628 /// any remaining issues. 629 ParseResult OperationParser::finalize() { 630 // Check for any forward references that are left. If we find any, error 631 // out. 632 if (!forwardRefPlaceholders.empty()) { 633 SmallVector<const char *, 4> errors; 634 // Iteration over the map isn't deterministic, so sort by source location. 635 for (auto entry : forwardRefPlaceholders) 636 errors.push_back(entry.second.getPointer()); 637 llvm::array_pod_sort(errors.begin(), errors.end()); 638 639 for (const char *entry : errors) { 640 auto loc = SMLoc::getFromPointer(entry); 641 emitError(loc, "use of undeclared SSA value name"); 642 } 643 return failure(); 644 } 645 646 // Resolve the locations of any deferred operations. 647 auto &attributeAliases = state.symbols.attributeAliasDefinitions; 648 auto locID = TypeID::get<DeferredLocInfo *>(); 649 auto resolveLocation = [&, this](auto &opOrArgument) -> LogicalResult { 650 auto fwdLoc = opOrArgument.getLoc().template dyn_cast<OpaqueLoc>(); 651 if (!fwdLoc || fwdLoc.getUnderlyingTypeID() != locID) 652 return success(); 653 auto locInfo = deferredLocsReferences[fwdLoc.getUnderlyingLocation()]; 654 Attribute attr = attributeAliases.lookup(locInfo.identifier); 655 if (!attr) 656 return this->emitError(locInfo.loc) 657 << "operation location alias was never defined"; 658 auto locAttr = attr.dyn_cast<LocationAttr>(); 659 if (!locAttr) 660 return this->emitError(locInfo.loc) 661 << "expected location, but found '" << attr << "'"; 662 opOrArgument.setLoc(locAttr); 663 return success(); 664 }; 665 666 auto walkRes = topLevelOp->walk([&](Operation *op) { 667 if (failed(resolveLocation(*op))) 668 return WalkResult::interrupt(); 669 for (Region ®ion : op->getRegions()) 670 for (Block &block : region.getBlocks()) 671 for (BlockArgument arg : block.getArguments()) 672 if (failed(resolveLocation(arg))) 673 return WalkResult::interrupt(); 674 return WalkResult::advance(); 675 }); 676 if (walkRes.wasInterrupted()) 677 return failure(); 678 679 // Pop the top level name scope. 680 if (failed(popSSANameScope())) 681 return failure(); 682 683 // Verify that the parsed operations are valid. 684 if (failed(verify(topLevelOp))) 685 return failure(); 686 687 // If we are populating the parser state, finalize the top-level operation. 688 if (state.asmState) 689 state.asmState->finalize(topLevelOp); 690 return success(); 691 } 692 693 //===----------------------------------------------------------------------===// 694 // SSA Value Handling 695 //===----------------------------------------------------------------------===// 696 697 void OperationParser::pushSSANameScope(bool isIsolated) { 698 blocksByName.push_back(DenseMap<StringRef, BlockDefinition>()); 699 forwardRef.push_back(DenseMap<Block *, SMLoc>()); 700 701 // Push back a new name definition scope. 702 if (isIsolated) 703 isolatedNameScopes.push_back({}); 704 isolatedNameScopes.back().pushSSANameScope(); 705 } 706 707 ParseResult OperationParser::popSSANameScope() { 708 auto forwardRefInCurrentScope = forwardRef.pop_back_val(); 709 710 // Verify that all referenced blocks were defined. 711 if (!forwardRefInCurrentScope.empty()) { 712 SmallVector<std::pair<const char *, Block *>, 4> errors; 713 // Iteration over the map isn't deterministic, so sort by source location. 714 for (auto entry : forwardRefInCurrentScope) { 715 errors.push_back({entry.second.getPointer(), entry.first}); 716 // Add this block to the top-level region to allow for automatic cleanup. 717 topLevelOp->getRegion(0).push_back(entry.first); 718 } 719 llvm::array_pod_sort(errors.begin(), errors.end()); 720 721 for (auto entry : errors) { 722 auto loc = SMLoc::getFromPointer(entry.first); 723 emitError(loc, "reference to an undefined block"); 724 } 725 return failure(); 726 } 727 728 // Pop the next nested namescope. If there is only one internal namescope, 729 // just pop the isolated scope. 730 auto ¤tNameScope = isolatedNameScopes.back(); 731 if (currentNameScope.definitionsPerScope.size() == 1) 732 isolatedNameScopes.pop_back(); 733 else 734 currentNameScope.popSSANameScope(); 735 736 blocksByName.pop_back(); 737 return success(); 738 } 739 740 /// Register a definition of a value with the symbol table. 741 ParseResult OperationParser::addDefinition(UnresolvedOperand useInfo, 742 Value value) { 743 auto &entries = getSSAValueEntry(useInfo.name); 744 745 // Make sure there is a slot for this value. 746 if (entries.size() <= useInfo.number) 747 entries.resize(useInfo.number + 1); 748 749 // If we already have an entry for this, check to see if it was a definition 750 // or a forward reference. 751 if (auto existing = entries[useInfo.number].value) { 752 if (!isForwardRefPlaceholder(existing)) { 753 return emitError(useInfo.location) 754 .append("redefinition of SSA value '", useInfo.name, "'") 755 .attachNote(getEncodedSourceLocation(entries[useInfo.number].loc)) 756 .append("previously defined here"); 757 } 758 759 if (existing.getType() != value.getType()) { 760 return emitError(useInfo.location) 761 .append("definition of SSA value '", useInfo.name, "#", 762 useInfo.number, "' has type ", value.getType()) 763 .attachNote(getEncodedSourceLocation(entries[useInfo.number].loc)) 764 .append("previously used here with type ", existing.getType()); 765 } 766 767 // If it was a forward reference, update everything that used it to use 768 // the actual definition instead, delete the forward ref, and remove it 769 // from our set of forward references we track. 770 existing.replaceAllUsesWith(value); 771 existing.getDefiningOp()->destroy(); 772 forwardRefPlaceholders.erase(existing); 773 774 // If a definition of the value already exists, replace it in the assembly 775 // state. 776 if (state.asmState) 777 state.asmState->refineDefinition(existing, value); 778 } 779 780 /// Record this definition for the current scope. 781 entries[useInfo.number] = {value, useInfo.location}; 782 recordDefinition(useInfo.name); 783 return success(); 784 } 785 786 /// Parse a (possibly empty) list of SSA operands. 787 /// 788 /// ssa-use-list ::= ssa-use (`,` ssa-use)* 789 /// ssa-use-list-opt ::= ssa-use-list? 790 /// 791 ParseResult OperationParser::parseOptionalSSAUseList( 792 SmallVectorImpl<UnresolvedOperand> &results) { 793 if (getToken().isNot(Token::percent_identifier)) 794 return success(); 795 return parseCommaSeparatedList([&]() -> ParseResult { 796 UnresolvedOperand result; 797 if (parseSSAUse(result)) 798 return failure(); 799 results.push_back(result); 800 return success(); 801 }); 802 } 803 804 /// Parse a SSA operand for an operation. 805 /// 806 /// ssa-use ::= ssa-id 807 /// 808 ParseResult OperationParser::parseSSAUse(UnresolvedOperand &result, 809 bool allowResultNumber) { 810 result.name = getTokenSpelling(); 811 result.number = 0; 812 result.location = getToken().getLoc(); 813 if (parseToken(Token::percent_identifier, "expected SSA operand")) 814 return failure(); 815 816 // If we have an attribute ID, it is a result number. 817 if (getToken().is(Token::hash_identifier)) { 818 if (!allowResultNumber) 819 return emitError("result number not allowed in argument list"); 820 821 if (auto value = getToken().getHashIdentifierNumber()) 822 result.number = *value; 823 else 824 return emitError("invalid SSA value result number"); 825 consumeToken(Token::hash_identifier); 826 } 827 828 return success(); 829 } 830 831 /// Given an unbound reference to an SSA value and its type, return the value 832 /// it specifies. This returns null on failure. 833 Value OperationParser::resolveSSAUse(UnresolvedOperand useInfo, Type type) { 834 auto &entries = getSSAValueEntry(useInfo.name); 835 836 // Functor used to record the use of the given value if the assembly state 837 // field is populated. 838 auto maybeRecordUse = [&](Value value) { 839 if (state.asmState) 840 state.asmState->addUses(value, useInfo.location); 841 return value; 842 }; 843 844 // If we have already seen a value of this name, return it. 845 if (useInfo.number < entries.size() && entries[useInfo.number].value) { 846 Value result = entries[useInfo.number].value; 847 // Check that the type matches the other uses. 848 if (result.getType() == type) 849 return maybeRecordUse(result); 850 851 emitError(useInfo.location, "use of value '") 852 .append(useInfo.name, 853 "' expects different type than prior uses: ", type, " vs ", 854 result.getType()) 855 .attachNote(getEncodedSourceLocation(entries[useInfo.number].loc)) 856 .append("prior use here"); 857 return nullptr; 858 } 859 860 // Make sure we have enough slots for this. 861 if (entries.size() <= useInfo.number) 862 entries.resize(useInfo.number + 1); 863 864 // If the value has already been defined and this is an overly large result 865 // number, diagnose that. 866 if (entries[0].value && !isForwardRefPlaceholder(entries[0].value)) 867 return (emitError(useInfo.location, "reference to invalid result number"), 868 nullptr); 869 870 // Otherwise, this is a forward reference. Create a placeholder and remember 871 // that we did so. 872 Value result = createForwardRefPlaceholder(useInfo.location, type); 873 entries[useInfo.number] = {result, useInfo.location}; 874 return maybeRecordUse(result); 875 } 876 877 /// Parse an SSA use with an associated type. 878 /// 879 /// ssa-use-and-type ::= ssa-use `:` type 880 ParseResult OperationParser::parseSSADefOrUseAndType( 881 function_ref<ParseResult(UnresolvedOperand, Type)> action) { 882 UnresolvedOperand useInfo; 883 if (parseSSAUse(useInfo) || 884 parseToken(Token::colon, "expected ':' and type for SSA operand")) 885 return failure(); 886 887 auto type = parseType(); 888 if (!type) 889 return failure(); 890 891 return action(useInfo, type); 892 } 893 894 /// Parse a (possibly empty) list of SSA operands, followed by a colon, then 895 /// followed by a type list. 896 /// 897 /// ssa-use-and-type-list 898 /// ::= ssa-use-list ':' type-list-no-parens 899 /// 900 ParseResult OperationParser::parseOptionalSSAUseAndTypeList( 901 SmallVectorImpl<Value> &results) { 902 SmallVector<UnresolvedOperand, 4> valueIDs; 903 if (parseOptionalSSAUseList(valueIDs)) 904 return failure(); 905 906 // If there were no operands, then there is no colon or type lists. 907 if (valueIDs.empty()) 908 return success(); 909 910 SmallVector<Type, 4> types; 911 if (parseToken(Token::colon, "expected ':' in operand list") || 912 parseTypeListNoParens(types)) 913 return failure(); 914 915 if (valueIDs.size() != types.size()) 916 return emitError("expected ") 917 << valueIDs.size() << " types to match operand list"; 918 919 results.reserve(valueIDs.size()); 920 for (unsigned i = 0, e = valueIDs.size(); i != e; ++i) { 921 if (auto value = resolveSSAUse(valueIDs[i], types[i])) 922 results.push_back(value); 923 else 924 return failure(); 925 } 926 927 return success(); 928 } 929 930 /// Record that a definition was added at the current scope. 931 void OperationParser::recordDefinition(StringRef def) { 932 isolatedNameScopes.back().recordDefinition(def); 933 } 934 935 /// Get the value entry for the given SSA name. 936 auto OperationParser::getSSAValueEntry(StringRef name) 937 -> SmallVectorImpl<ValueDefinition> & { 938 return isolatedNameScopes.back().values[name]; 939 } 940 941 /// Create and remember a new placeholder for a forward reference. 942 Value OperationParser::createForwardRefPlaceholder(SMLoc loc, Type type) { 943 // Forward references are always created as operations, because we just need 944 // something with a def/use chain. 945 // 946 // We create these placeholders as having an empty name, which we know 947 // cannot be created through normal user input, allowing us to distinguish 948 // them. 949 auto name = OperationName("builtin.unrealized_conversion_cast", getContext()); 950 auto *op = Operation::create( 951 getEncodedSourceLocation(loc), name, type, /*operands=*/{}, 952 /*attributes=*/llvm::None, /*successors=*/{}, /*numRegions=*/0); 953 forwardRefPlaceholders[op->getResult(0)] = loc; 954 return op->getResult(0); 955 } 956 957 //===----------------------------------------------------------------------===// 958 // Operation Parsing 959 //===----------------------------------------------------------------------===// 960 961 /// Parse an operation. 962 /// 963 /// operation ::= op-result-list? 964 /// (generic-operation | custom-operation) 965 /// trailing-location? 966 /// generic-operation ::= string-literal `(` ssa-use-list? `)` 967 /// successor-list? (`(` region-list `)`)? 968 /// attribute-dict? `:` function-type 969 /// custom-operation ::= bare-id custom-operation-format 970 /// op-result-list ::= op-result (`,` op-result)* `=` 971 /// op-result ::= ssa-id (`:` integer-literal) 972 /// 973 ParseResult OperationParser::parseOperation() { 974 auto loc = getToken().getLoc(); 975 SmallVector<ResultRecord, 1> resultIDs; 976 size_t numExpectedResults = 0; 977 if (getToken().is(Token::percent_identifier)) { 978 // Parse the group of result ids. 979 auto parseNextResult = [&]() -> ParseResult { 980 // Parse the next result id. 981 Token nameTok = getToken(); 982 if (parseToken(Token::percent_identifier, 983 "expected valid ssa identifier")) 984 return failure(); 985 986 // If the next token is a ':', we parse the expected result count. 987 size_t expectedSubResults = 1; 988 if (consumeIf(Token::colon)) { 989 // Check that the next token is an integer. 990 if (!getToken().is(Token::integer)) 991 return emitWrongTokenError("expected integer number of results"); 992 993 // Check that number of results is > 0. 994 auto val = getToken().getUInt64IntegerValue(); 995 if (!val || *val < 1) 996 return emitError( 997 "expected named operation to have at least 1 result"); 998 consumeToken(Token::integer); 999 expectedSubResults = *val; 1000 } 1001 1002 resultIDs.emplace_back(nameTok.getSpelling(), expectedSubResults, 1003 nameTok.getLoc()); 1004 numExpectedResults += expectedSubResults; 1005 return success(); 1006 }; 1007 if (parseCommaSeparatedList(parseNextResult)) 1008 return failure(); 1009 1010 if (parseToken(Token::equal, "expected '=' after SSA name")) 1011 return failure(); 1012 } 1013 1014 Operation *op; 1015 Token nameTok = getToken(); 1016 if (nameTok.is(Token::bare_identifier) || nameTok.isKeyword()) 1017 op = parseCustomOperation(resultIDs); 1018 else if (nameTok.is(Token::string)) 1019 op = parseGenericOperation(); 1020 else 1021 return emitWrongTokenError("expected operation name in quotes"); 1022 1023 // If parsing of the basic operation failed, then this whole thing fails. 1024 if (!op) 1025 return failure(); 1026 1027 // If the operation had a name, register it. 1028 if (!resultIDs.empty()) { 1029 if (op->getNumResults() == 0) 1030 return emitError(loc, "cannot name an operation with no results"); 1031 if (numExpectedResults != op->getNumResults()) 1032 return emitError(loc, "operation defines ") 1033 << op->getNumResults() << " results but was provided " 1034 << numExpectedResults << " to bind"; 1035 1036 // Add this operation to the assembly state if it was provided to populate. 1037 if (state.asmState) { 1038 unsigned resultIt = 0; 1039 SmallVector<std::pair<unsigned, SMLoc>> asmResultGroups; 1040 asmResultGroups.reserve(resultIDs.size()); 1041 for (ResultRecord &record : resultIDs) { 1042 asmResultGroups.emplace_back(resultIt, std::get<2>(record)); 1043 resultIt += std::get<1>(record); 1044 } 1045 state.asmState->finalizeOperationDefinition( 1046 op, nameTok.getLocRange(), /*endLoc=*/getToken().getLoc(), 1047 asmResultGroups); 1048 } 1049 1050 // Add definitions for each of the result groups. 1051 unsigned opResI = 0; 1052 for (ResultRecord &resIt : resultIDs) { 1053 for (unsigned subRes : llvm::seq<unsigned>(0, std::get<1>(resIt))) { 1054 if (addDefinition({std::get<2>(resIt), std::get<0>(resIt), subRes}, 1055 op->getResult(opResI++))) 1056 return failure(); 1057 } 1058 } 1059 1060 // Add this operation to the assembly state if it was provided to populate. 1061 } else if (state.asmState) { 1062 state.asmState->finalizeOperationDefinition(op, nameTok.getLocRange(), 1063 /*endLoc=*/getToken().getLoc()); 1064 } 1065 1066 return success(); 1067 } 1068 1069 /// Parse a single operation successor. 1070 /// 1071 /// successor ::= block-id 1072 /// 1073 ParseResult OperationParser::parseSuccessor(Block *&dest) { 1074 // Verify branch is identifier and get the matching block. 1075 if (!getToken().is(Token::caret_identifier)) 1076 return emitWrongTokenError("expected block name"); 1077 dest = getBlockNamed(getTokenSpelling(), getToken().getLoc()); 1078 consumeToken(); 1079 return success(); 1080 } 1081 1082 /// Parse a comma-separated list of operation successors in brackets. 1083 /// 1084 /// successor-list ::= `[` successor (`,` successor )* `]` 1085 /// 1086 ParseResult 1087 OperationParser::parseSuccessors(SmallVectorImpl<Block *> &destinations) { 1088 if (parseToken(Token::l_square, "expected '['")) 1089 return failure(); 1090 1091 auto parseElt = [this, &destinations] { 1092 Block *dest; 1093 ParseResult res = parseSuccessor(dest); 1094 destinations.push_back(dest); 1095 return res; 1096 }; 1097 return parseCommaSeparatedListUntil(Token::r_square, parseElt, 1098 /*allowEmptyList=*/false); 1099 } 1100 1101 namespace { 1102 // RAII-style guard for cleaning up the regions in the operation state before 1103 // deleting them. Within the parser, regions may get deleted if parsing failed, 1104 // and other errors may be present, in particular undominated uses. This makes 1105 // sure such uses are deleted. 1106 struct CleanupOpStateRegions { 1107 ~CleanupOpStateRegions() { 1108 SmallVector<Region *, 4> regionsToClean; 1109 regionsToClean.reserve(state.regions.size()); 1110 for (auto ®ion : state.regions) 1111 if (region) 1112 for (auto &block : *region) 1113 block.dropAllDefinedValueUses(); 1114 } 1115 OperationState &state; 1116 }; 1117 } // namespace 1118 1119 ParseResult OperationParser::parseGenericOperationAfterOpName( 1120 OperationState &result, 1121 Optional<ArrayRef<UnresolvedOperand>> parsedOperandUseInfo, 1122 Optional<ArrayRef<Block *>> parsedSuccessors, 1123 Optional<MutableArrayRef<std::unique_ptr<Region>>> parsedRegions, 1124 Optional<ArrayRef<NamedAttribute>> parsedAttributes, 1125 Optional<FunctionType> parsedFnType) { 1126 1127 // Parse the operand list, if not explicitly provided. 1128 SmallVector<UnresolvedOperand, 8> opInfo; 1129 if (!parsedOperandUseInfo) { 1130 if (parseToken(Token::l_paren, "expected '(' to start operand list") || 1131 parseOptionalSSAUseList(opInfo) || 1132 parseToken(Token::r_paren, "expected ')' to end operand list")) { 1133 return failure(); 1134 } 1135 parsedOperandUseInfo = opInfo; 1136 } 1137 1138 // Parse the successor list, if not explicitly provided. 1139 if (!parsedSuccessors) { 1140 if (getToken().is(Token::l_square)) { 1141 // Check if the operation is not a known terminator. 1142 if (!result.name.mightHaveTrait<OpTrait::IsTerminator>()) 1143 return emitError("successors in non-terminator"); 1144 1145 SmallVector<Block *, 2> successors; 1146 if (parseSuccessors(successors)) 1147 return failure(); 1148 result.addSuccessors(successors); 1149 } 1150 } else { 1151 result.addSuccessors(*parsedSuccessors); 1152 } 1153 1154 // Parse the region list, if not explicitly provided. 1155 if (!parsedRegions) { 1156 if (consumeIf(Token::l_paren)) { 1157 do { 1158 // Create temporary regions with the top level region as parent. 1159 result.regions.emplace_back(new Region(topLevelOp)); 1160 if (parseRegion(*result.regions.back(), /*entryArguments=*/{})) 1161 return failure(); 1162 } while (consumeIf(Token::comma)); 1163 if (parseToken(Token::r_paren, "expected ')' to end region list")) 1164 return failure(); 1165 } 1166 } else { 1167 result.addRegions(*parsedRegions); 1168 } 1169 1170 // Parse the attributes, if not explicitly provided. 1171 if (!parsedAttributes) { 1172 if (getToken().is(Token::l_brace)) { 1173 if (parseAttributeDict(result.attributes)) 1174 return failure(); 1175 } 1176 } else { 1177 result.addAttributes(*parsedAttributes); 1178 } 1179 1180 // Parse the operation type, if not explicitly provided. 1181 Location typeLoc = result.location; 1182 if (!parsedFnType) { 1183 if (parseToken(Token::colon, "expected ':' followed by operation type")) 1184 return failure(); 1185 1186 typeLoc = getEncodedSourceLocation(getToken().getLoc()); 1187 auto type = parseType(); 1188 if (!type) 1189 return failure(); 1190 auto fnType = type.dyn_cast<FunctionType>(); 1191 if (!fnType) 1192 return mlir::emitError(typeLoc, "expected function type"); 1193 1194 parsedFnType = fnType; 1195 } 1196 1197 result.addTypes(parsedFnType->getResults()); 1198 1199 // Check that we have the right number of types for the operands. 1200 ArrayRef<Type> operandTypes = parsedFnType->getInputs(); 1201 if (operandTypes.size() != parsedOperandUseInfo->size()) { 1202 auto plural = "s"[parsedOperandUseInfo->size() == 1]; 1203 return mlir::emitError(typeLoc, "expected ") 1204 << parsedOperandUseInfo->size() << " operand type" << plural 1205 << " but had " << operandTypes.size(); 1206 } 1207 1208 // Resolve all of the operands. 1209 for (unsigned i = 0, e = parsedOperandUseInfo->size(); i != e; ++i) { 1210 result.operands.push_back( 1211 resolveSSAUse((*parsedOperandUseInfo)[i], operandTypes[i])); 1212 if (!result.operands.back()) 1213 return failure(); 1214 } 1215 1216 return success(); 1217 } 1218 1219 Operation *OperationParser::parseGenericOperation() { 1220 // Get location information for the operation. 1221 auto srcLocation = getEncodedSourceLocation(getToken().getLoc()); 1222 1223 std::string name = getToken().getStringValue(); 1224 if (name.empty()) 1225 return (emitError("empty operation name is invalid"), nullptr); 1226 if (name.find('\0') != StringRef::npos) 1227 return (emitError("null character not allowed in operation name"), nullptr); 1228 1229 consumeToken(Token::string); 1230 1231 OperationState result(srcLocation, name); 1232 CleanupOpStateRegions guard{result}; 1233 1234 // Lazy load dialects in the context as needed. 1235 if (!result.name.isRegistered()) { 1236 StringRef dialectName = StringRef(name).split('.').first; 1237 if (!getContext()->getLoadedDialect(dialectName) && 1238 !getContext()->getOrLoadDialect(dialectName) && 1239 !getContext()->allowsUnregisteredDialects()) { 1240 // Emit an error if the dialect couldn't be loaded (i.e., it was not 1241 // registered) and unregistered dialects aren't allowed. 1242 emitError("operation being parsed with an unregistered dialect. If " 1243 "this is intended, please use -allow-unregistered-dialect " 1244 "with the MLIR tool used"); 1245 return nullptr; 1246 } 1247 } 1248 1249 // If we are populating the parser state, start a new operation definition. 1250 if (state.asmState) 1251 state.asmState->startOperationDefinition(result.name); 1252 1253 if (parseGenericOperationAfterOpName(result)) 1254 return nullptr; 1255 1256 // Create the operation and try to parse a location for it. 1257 Operation *op = opBuilder.create(result); 1258 if (parseTrailingLocationSpecifier(op)) 1259 return nullptr; 1260 return op; 1261 } 1262 1263 Operation *OperationParser::parseGenericOperation(Block *insertBlock, 1264 Block::iterator insertPt) { 1265 Token nameToken = getToken(); 1266 1267 OpBuilder::InsertionGuard restoreInsertionPoint(opBuilder); 1268 opBuilder.setInsertionPoint(insertBlock, insertPt); 1269 Operation *op = parseGenericOperation(); 1270 if (!op) 1271 return nullptr; 1272 1273 // If we are populating the parser asm state, finalize this operation 1274 // definition. 1275 if (state.asmState) 1276 state.asmState->finalizeOperationDefinition(op, nameToken.getLocRange(), 1277 /*endLoc=*/getToken().getLoc()); 1278 return op; 1279 } 1280 1281 namespace { 1282 class CustomOpAsmParser : public AsmParserImpl<OpAsmParser> { 1283 public: 1284 CustomOpAsmParser( 1285 SMLoc nameLoc, ArrayRef<OperationParser::ResultRecord> resultIDs, 1286 function_ref<ParseResult(OpAsmParser &, OperationState &)> parseAssembly, 1287 bool isIsolatedFromAbove, StringRef opName, OperationParser &parser) 1288 : AsmParserImpl<OpAsmParser>(nameLoc, parser), resultIDs(resultIDs), 1289 parseAssembly(parseAssembly), isIsolatedFromAbove(isIsolatedFromAbove), 1290 opName(opName), parser(parser) { 1291 (void)isIsolatedFromAbove; // Only used in assert, silence unused warning. 1292 } 1293 1294 /// Parse an instance of the operation described by 'opDefinition' into the 1295 /// provided operation state. 1296 ParseResult parseOperation(OperationState &opState) { 1297 if (parseAssembly(*this, opState)) 1298 return failure(); 1299 // Verify that the parsed attributes does not have duplicate attributes. 1300 // This can happen if an attribute set during parsing is also specified in 1301 // the attribute dictionary in the assembly, or the attribute is set 1302 // multiple during parsing. 1303 Optional<NamedAttribute> duplicate = opState.attributes.findDuplicate(); 1304 if (duplicate) 1305 return emitError(getNameLoc(), "attribute '") 1306 << duplicate->getName().getValue() 1307 << "' occurs more than once in the attribute list"; 1308 return success(); 1309 } 1310 1311 Operation *parseGenericOperation(Block *insertBlock, 1312 Block::iterator insertPt) final { 1313 return parser.parseGenericOperation(insertBlock, insertPt); 1314 } 1315 1316 FailureOr<OperationName> parseCustomOperationName() final { 1317 return parser.parseCustomOperationName(); 1318 } 1319 1320 ParseResult parseGenericOperationAfterOpName( 1321 OperationState &result, 1322 Optional<ArrayRef<UnresolvedOperand>> parsedUnresolvedOperands, 1323 Optional<ArrayRef<Block *>> parsedSuccessors, 1324 Optional<MutableArrayRef<std::unique_ptr<Region>>> parsedRegions, 1325 Optional<ArrayRef<NamedAttribute>> parsedAttributes, 1326 Optional<FunctionType> parsedFnType) final { 1327 return parser.parseGenericOperationAfterOpName( 1328 result, parsedUnresolvedOperands, parsedSuccessors, parsedRegions, 1329 parsedAttributes, parsedFnType); 1330 } 1331 //===--------------------------------------------------------------------===// 1332 // Utilities 1333 //===--------------------------------------------------------------------===// 1334 1335 /// Return the name of the specified result in the specified syntax, as well 1336 /// as the subelement in the name. For example, in this operation: 1337 /// 1338 /// %x, %y:2, %z = foo.op 1339 /// 1340 /// getResultName(0) == {"x", 0 } 1341 /// getResultName(1) == {"y", 0 } 1342 /// getResultName(2) == {"y", 1 } 1343 /// getResultName(3) == {"z", 0 } 1344 std::pair<StringRef, unsigned> 1345 getResultName(unsigned resultNo) const override { 1346 // Scan for the resultID that contains this result number. 1347 for (const auto &entry : resultIDs) { 1348 if (resultNo < std::get<1>(entry)) { 1349 // Don't pass on the leading %. 1350 StringRef name = std::get<0>(entry).drop_front(); 1351 return {name, resultNo}; 1352 } 1353 resultNo -= std::get<1>(entry); 1354 } 1355 1356 // Invalid result number. 1357 return {"", ~0U}; 1358 } 1359 1360 /// Return the number of declared SSA results. This returns 4 for the foo.op 1361 /// example in the comment for getResultName. 1362 size_t getNumResults() const override { 1363 size_t count = 0; 1364 for (auto &entry : resultIDs) 1365 count += std::get<1>(entry); 1366 return count; 1367 } 1368 1369 /// Emit a diagnostic at the specified location and return failure. 1370 InFlightDiagnostic emitError(SMLoc loc, const Twine &message) override { 1371 return AsmParserImpl<OpAsmParser>::emitError(loc, "custom op '" + opName + 1372 "' " + message); 1373 } 1374 1375 //===--------------------------------------------------------------------===// 1376 // Operand Parsing 1377 //===--------------------------------------------------------------------===// 1378 1379 /// Parse a single operand. 1380 ParseResult parseOperand(UnresolvedOperand &result, 1381 bool allowResultNumber = true) override { 1382 OperationParser::UnresolvedOperand useInfo; 1383 if (parser.parseSSAUse(useInfo, allowResultNumber)) 1384 return failure(); 1385 1386 result = {useInfo.location, useInfo.name, useInfo.number}; 1387 return success(); 1388 } 1389 1390 /// Parse a single operand if present. 1391 OptionalParseResult 1392 parseOptionalOperand(UnresolvedOperand &result, 1393 bool allowResultNumber = true) override { 1394 if (parser.getToken().is(Token::percent_identifier)) 1395 return parseOperand(result, allowResultNumber); 1396 return llvm::None; 1397 } 1398 1399 /// Parse zero or more SSA comma-separated operand references with a specified 1400 /// surrounding delimiter, and an optional required operand count. 1401 ParseResult parseOperandList(SmallVectorImpl<UnresolvedOperand> &result, 1402 Delimiter delimiter = Delimiter::None, 1403 bool allowResultNumber = true, 1404 int requiredOperandCount = -1) override { 1405 // The no-delimiter case has some special handling for better diagnostics. 1406 if (delimiter == Delimiter::None) { 1407 // parseCommaSeparatedList doesn't handle the missing case for "none", 1408 // so we handle it custom here. 1409 if (parser.getToken().isNot(Token::percent_identifier)) { 1410 // If we didn't require any operands or required exactly zero (weird) 1411 // then this is success. 1412 if (requiredOperandCount == -1 || requiredOperandCount == 0) 1413 return success(); 1414 1415 // Otherwise, try to produce a nice error message. 1416 if (parser.getToken().isAny(Token::l_paren, Token::l_square)) 1417 return parser.emitError("unexpected delimiter"); 1418 return parser.emitWrongTokenError("expected operand"); 1419 } 1420 } 1421 1422 auto parseOneOperand = [&]() -> ParseResult { 1423 return parseOperand(result.emplace_back(), allowResultNumber); 1424 }; 1425 1426 auto startLoc = parser.getToken().getLoc(); 1427 if (parseCommaSeparatedList(delimiter, parseOneOperand, " in operand list")) 1428 return failure(); 1429 1430 // Check that we got the expected # of elements. 1431 if (requiredOperandCount != -1 && 1432 result.size() != static_cast<size_t>(requiredOperandCount)) 1433 return emitError(startLoc, "expected ") 1434 << requiredOperandCount << " operands"; 1435 return success(); 1436 } 1437 1438 /// Resolve an operand to an SSA value, emitting an error on failure. 1439 ParseResult resolveOperand(const UnresolvedOperand &operand, Type type, 1440 SmallVectorImpl<Value> &result) override { 1441 if (auto value = parser.resolveSSAUse(operand, type)) { 1442 result.push_back(value); 1443 return success(); 1444 } 1445 return failure(); 1446 } 1447 1448 /// Parse an AffineMap of SSA ids. 1449 ParseResult 1450 parseAffineMapOfSSAIds(SmallVectorImpl<UnresolvedOperand> &operands, 1451 Attribute &mapAttr, StringRef attrName, 1452 NamedAttrList &attrs, Delimiter delimiter) override { 1453 SmallVector<UnresolvedOperand, 2> dimOperands; 1454 SmallVector<UnresolvedOperand, 1> symOperands; 1455 1456 auto parseElement = [&](bool isSymbol) -> ParseResult { 1457 UnresolvedOperand operand; 1458 if (parseOperand(operand)) 1459 return failure(); 1460 if (isSymbol) 1461 symOperands.push_back(operand); 1462 else 1463 dimOperands.push_back(operand); 1464 return success(); 1465 }; 1466 1467 AffineMap map; 1468 if (parser.parseAffineMapOfSSAIds(map, parseElement, delimiter)) 1469 return failure(); 1470 // Add AffineMap attribute. 1471 if (map) { 1472 mapAttr = AffineMapAttr::get(map); 1473 attrs.push_back(parser.builder.getNamedAttr(attrName, mapAttr)); 1474 } 1475 1476 // Add dim operands before symbol operands in 'operands'. 1477 operands.assign(dimOperands.begin(), dimOperands.end()); 1478 operands.append(symOperands.begin(), symOperands.end()); 1479 return success(); 1480 } 1481 1482 /// Parse an AffineExpr of SSA ids. 1483 ParseResult 1484 parseAffineExprOfSSAIds(SmallVectorImpl<UnresolvedOperand> &dimOperands, 1485 SmallVectorImpl<UnresolvedOperand> &symbOperands, 1486 AffineExpr &expr) override { 1487 auto parseElement = [&](bool isSymbol) -> ParseResult { 1488 UnresolvedOperand operand; 1489 if (parseOperand(operand)) 1490 return failure(); 1491 if (isSymbol) 1492 symbOperands.push_back(operand); 1493 else 1494 dimOperands.push_back(operand); 1495 return success(); 1496 }; 1497 1498 return parser.parseAffineExprOfSSAIds(expr, parseElement); 1499 } 1500 1501 //===--------------------------------------------------------------------===// 1502 // Argument Parsing 1503 //===--------------------------------------------------------------------===// 1504 1505 /// Parse a single argument with the following syntax: 1506 /// 1507 /// `%ssaname : !type { optionalAttrDict} loc(optionalSourceLoc)` 1508 /// 1509 /// If `allowType` is false or `allowAttrs` are false then the respective 1510 /// parts of the grammar are not parsed. 1511 ParseResult parseArgument(Argument &result, bool allowType = false, 1512 bool allowAttrs = false) override { 1513 NamedAttrList attrs; 1514 if (parseOperand(result.ssaName, /*allowResultNumber=*/false) || 1515 (allowType && parseColonType(result.type)) || 1516 (allowAttrs && parseOptionalAttrDict(attrs)) || 1517 parseOptionalLocationSpecifier(result.sourceLoc)) 1518 return failure(); 1519 result.attrs = attrs.getDictionary(getContext()); 1520 return success(); 1521 } 1522 1523 /// Parse a single argument if present. 1524 OptionalParseResult parseOptionalArgument(Argument &result, bool allowType, 1525 bool allowAttrs) override { 1526 if (parser.getToken().is(Token::percent_identifier)) 1527 return parseArgument(result, allowType, allowAttrs); 1528 return llvm::None; 1529 } 1530 1531 ParseResult parseArgumentList(SmallVectorImpl<Argument> &result, 1532 Delimiter delimiter, bool allowType, 1533 bool allowAttrs) override { 1534 // The no-delimiter case has some special handling for the empty case. 1535 if (delimiter == Delimiter::None && 1536 parser.getToken().isNot(Token::percent_identifier)) 1537 return success(); 1538 1539 auto parseOneArgument = [&]() -> ParseResult { 1540 return parseArgument(result.emplace_back(), allowType, allowAttrs); 1541 }; 1542 return parseCommaSeparatedList(delimiter, parseOneArgument, 1543 " in argument list"); 1544 } 1545 1546 //===--------------------------------------------------------------------===// 1547 // Region Parsing 1548 //===--------------------------------------------------------------------===// 1549 1550 /// Parse a region that takes `arguments` of `argTypes` types. This 1551 /// effectively defines the SSA values of `arguments` and assigns their type. 1552 ParseResult parseRegion(Region ®ion, ArrayRef<Argument> arguments, 1553 bool enableNameShadowing) override { 1554 // Try to parse the region. 1555 (void)isIsolatedFromAbove; 1556 assert((!enableNameShadowing || isIsolatedFromAbove) && 1557 "name shadowing is only allowed on isolated regions"); 1558 if (parser.parseRegion(region, arguments, enableNameShadowing)) 1559 return failure(); 1560 return success(); 1561 } 1562 1563 /// Parses a region if present. 1564 OptionalParseResult parseOptionalRegion(Region ®ion, 1565 ArrayRef<Argument> arguments, 1566 bool enableNameShadowing) override { 1567 if (parser.getToken().isNot(Token::l_brace)) 1568 return llvm::None; 1569 return parseRegion(region, arguments, enableNameShadowing); 1570 } 1571 1572 /// Parses a region if present. If the region is present, a new region is 1573 /// allocated and placed in `region`. If no region is present, `region` 1574 /// remains untouched. 1575 OptionalParseResult 1576 parseOptionalRegion(std::unique_ptr<Region> ®ion, 1577 ArrayRef<Argument> arguments, 1578 bool enableNameShadowing = false) override { 1579 if (parser.getToken().isNot(Token::l_brace)) 1580 return llvm::None; 1581 std::unique_ptr<Region> newRegion = std::make_unique<Region>(); 1582 if (parseRegion(*newRegion, arguments, enableNameShadowing)) 1583 return failure(); 1584 1585 region = std::move(newRegion); 1586 return success(); 1587 } 1588 1589 //===--------------------------------------------------------------------===// 1590 // Successor Parsing 1591 //===--------------------------------------------------------------------===// 1592 1593 /// Parse a single operation successor. 1594 ParseResult parseSuccessor(Block *&dest) override { 1595 return parser.parseSuccessor(dest); 1596 } 1597 1598 /// Parse an optional operation successor and its operand list. 1599 OptionalParseResult parseOptionalSuccessor(Block *&dest) override { 1600 if (parser.getToken().isNot(Token::caret_identifier)) 1601 return llvm::None; 1602 return parseSuccessor(dest); 1603 } 1604 1605 /// Parse a single operation successor and its operand list. 1606 ParseResult 1607 parseSuccessorAndUseList(Block *&dest, 1608 SmallVectorImpl<Value> &operands) override { 1609 if (parseSuccessor(dest)) 1610 return failure(); 1611 1612 // Handle optional arguments. 1613 if (succeeded(parseOptionalLParen()) && 1614 (parser.parseOptionalSSAUseAndTypeList(operands) || parseRParen())) { 1615 return failure(); 1616 } 1617 return success(); 1618 } 1619 1620 //===--------------------------------------------------------------------===// 1621 // Type Parsing 1622 //===--------------------------------------------------------------------===// 1623 1624 /// Parse a list of assignments of the form 1625 /// (%x1 = %y1, %x2 = %y2, ...). 1626 OptionalParseResult parseOptionalAssignmentList( 1627 SmallVectorImpl<Argument> &lhs, 1628 SmallVectorImpl<UnresolvedOperand> &rhs) override { 1629 if (failed(parseOptionalLParen())) 1630 return llvm::None; 1631 1632 auto parseElt = [&]() -> ParseResult { 1633 if (parseArgument(lhs.emplace_back()) || parseEqual() || 1634 parseOperand(rhs.emplace_back())) 1635 return failure(); 1636 return success(); 1637 }; 1638 return parser.parseCommaSeparatedListUntil(Token::r_paren, parseElt); 1639 } 1640 1641 /// Parse a loc(...) specifier if present, filling in result if so. 1642 ParseResult 1643 parseOptionalLocationSpecifier(Optional<Location> &result) override { 1644 // If there is a 'loc' we parse a trailing location. 1645 if (!parser.consumeIf(Token::kw_loc)) 1646 return success(); 1647 LocationAttr directLoc; 1648 if (parser.parseToken(Token::l_paren, "expected '(' in location")) 1649 return failure(); 1650 1651 Token tok = parser.getToken(); 1652 1653 // Check to see if we are parsing a location alias. 1654 // Otherwise, we parse the location directly. 1655 if (tok.is(Token::hash_identifier)) { 1656 if (parser.parseLocationAlias(directLoc)) 1657 return failure(); 1658 } else if (parser.parseLocationInstance(directLoc)) { 1659 return failure(); 1660 } 1661 1662 if (parser.parseToken(Token::r_paren, "expected ')' in location")) 1663 return failure(); 1664 1665 result = directLoc; 1666 return success(); 1667 } 1668 1669 private: 1670 /// Information about the result name specifiers. 1671 ArrayRef<OperationParser::ResultRecord> resultIDs; 1672 1673 /// The abstract information of the operation. 1674 function_ref<ParseResult(OpAsmParser &, OperationState &)> parseAssembly; 1675 bool isIsolatedFromAbove; 1676 StringRef opName; 1677 1678 /// The backing operation parser. 1679 OperationParser &parser; 1680 }; 1681 } // namespace 1682 1683 FailureOr<OperationName> OperationParser::parseCustomOperationName() { 1684 std::string opName = getTokenSpelling().str(); 1685 if (opName.empty()) 1686 return (emitError("empty operation name is invalid"), failure()); 1687 consumeToken(); 1688 1689 // Check to see if this operation name is already registered. 1690 Optional<RegisteredOperationName> opInfo = 1691 RegisteredOperationName::lookup(opName, getContext()); 1692 if (opInfo) 1693 return *opInfo; 1694 1695 // If the operation doesn't have a dialect prefix try using the default 1696 // dialect. 1697 auto opNameSplit = StringRef(opName).split('.'); 1698 StringRef dialectName = opNameSplit.first; 1699 if (opNameSplit.second.empty()) { 1700 dialectName = getState().defaultDialectStack.back(); 1701 opName = (dialectName + "." + opName).str(); 1702 } 1703 1704 // Try to load the dialect before returning the operation name to make sure 1705 // the operation has a chance to be registered. 1706 getContext()->getOrLoadDialect(dialectName); 1707 return OperationName(opName, getContext()); 1708 } 1709 1710 Operation * 1711 OperationParser::parseCustomOperation(ArrayRef<ResultRecord> resultIDs) { 1712 SMLoc opLoc = getToken().getLoc(); 1713 StringRef originalOpName = getTokenSpelling(); 1714 1715 FailureOr<OperationName> opNameInfo = parseCustomOperationName(); 1716 if (failed(opNameInfo)) 1717 return nullptr; 1718 StringRef opName = opNameInfo->getStringRef(); 1719 1720 // This is the actual hook for the custom op parsing, usually implemented by 1721 // the op itself (`Op::parse()`). We retrieve it either from the 1722 // RegisteredOperationName or from the Dialect. 1723 function_ref<ParseResult(OpAsmParser &, OperationState &)> parseAssemblyFn; 1724 bool isIsolatedFromAbove = false; 1725 1726 StringRef defaultDialect = ""; 1727 if (auto opInfo = opNameInfo->getRegisteredInfo()) { 1728 parseAssemblyFn = opInfo->getParseAssemblyFn(); 1729 isIsolatedFromAbove = opInfo->hasTrait<OpTrait::IsIsolatedFromAbove>(); 1730 auto *iface = opInfo->getInterface<OpAsmOpInterface>(); 1731 if (iface && !iface->getDefaultDialect().empty()) 1732 defaultDialect = iface->getDefaultDialect(); 1733 } else { 1734 Optional<Dialect::ParseOpHook> dialectHook; 1735 if (Dialect *dialect = opNameInfo->getDialect()) 1736 dialectHook = dialect->getParseOperationHook(opName); 1737 if (!dialectHook) { 1738 InFlightDiagnostic diag = 1739 emitError(opLoc) << "custom op '" << originalOpName << "' is unknown"; 1740 if (originalOpName != opName) 1741 diag << " (tried '" << opName << "' as well)"; 1742 return nullptr; 1743 } 1744 parseAssemblyFn = *dialectHook; 1745 } 1746 getState().defaultDialectStack.push_back(defaultDialect); 1747 auto restoreDefaultDialect = llvm::make_scope_exit( 1748 [&]() { getState().defaultDialectStack.pop_back(); }); 1749 1750 // If the custom op parser crashes, produce some indication to help 1751 // debugging. 1752 llvm::PrettyStackTraceFormat fmt("MLIR Parser: custom op parser '%s'", 1753 opNameInfo->getIdentifier().data()); 1754 1755 // Get location information for the operation. 1756 auto srcLocation = getEncodedSourceLocation(opLoc); 1757 OperationState opState(srcLocation, *opNameInfo); 1758 1759 // If we are populating the parser state, start a new operation definition. 1760 if (state.asmState) 1761 state.asmState->startOperationDefinition(opState.name); 1762 1763 // Have the op implementation take a crack and parsing this. 1764 CleanupOpStateRegions guard{opState}; 1765 CustomOpAsmParser opAsmParser(opLoc, resultIDs, parseAssemblyFn, 1766 isIsolatedFromAbove, opName, *this); 1767 if (opAsmParser.parseOperation(opState)) 1768 return nullptr; 1769 1770 // If it emitted an error, we failed. 1771 if (opAsmParser.didEmitError()) 1772 return nullptr; 1773 1774 // Otherwise, create the operation and try to parse a location for it. 1775 Operation *op = opBuilder.create(opState); 1776 if (parseTrailingLocationSpecifier(op)) 1777 return nullptr; 1778 return op; 1779 } 1780 1781 ParseResult OperationParser::parseLocationAlias(LocationAttr &loc) { 1782 Token tok = getToken(); 1783 consumeToken(Token::hash_identifier); 1784 StringRef identifier = tok.getSpelling().drop_front(); 1785 if (identifier.contains('.')) { 1786 return emitError(tok.getLoc()) 1787 << "expected location, but found dialect attribute: '#" << identifier 1788 << "'"; 1789 } 1790 1791 // If this alias can be resolved, do it now. 1792 Attribute attr = state.symbols.attributeAliasDefinitions.lookup(identifier); 1793 if (attr) { 1794 if (!(loc = attr.dyn_cast<LocationAttr>())) 1795 return emitError(tok.getLoc()) 1796 << "expected location, but found '" << attr << "'"; 1797 } else { 1798 // Otherwise, remember this operation and resolve its location later. 1799 // In the meantime, use a special OpaqueLoc as a marker. 1800 loc = OpaqueLoc::get(deferredLocsReferences.size(), 1801 TypeID::get<DeferredLocInfo *>(), 1802 UnknownLoc::get(getContext())); 1803 deferredLocsReferences.push_back(DeferredLocInfo{tok.getLoc(), identifier}); 1804 } 1805 return success(); 1806 } 1807 1808 ParseResult 1809 OperationParser::parseTrailingLocationSpecifier(OpOrArgument opOrArgument) { 1810 // If there is a 'loc' we parse a trailing location. 1811 if (!consumeIf(Token::kw_loc)) 1812 return success(); 1813 if (parseToken(Token::l_paren, "expected '(' in location")) 1814 return failure(); 1815 Token tok = getToken(); 1816 1817 // Check to see if we are parsing a location alias. 1818 // Otherwise, we parse the location directly. 1819 LocationAttr directLoc; 1820 if (tok.is(Token::hash_identifier)) { 1821 if (parseLocationAlias(directLoc)) 1822 return failure(); 1823 } else if (parseLocationInstance(directLoc)) { 1824 return failure(); 1825 } 1826 1827 if (parseToken(Token::r_paren, "expected ')' in location")) 1828 return failure(); 1829 1830 if (auto *op = opOrArgument.dyn_cast<Operation *>()) 1831 op->setLoc(directLoc); 1832 else 1833 opOrArgument.get<BlockArgument>().setLoc(directLoc); 1834 return success(); 1835 } 1836 1837 //===----------------------------------------------------------------------===// 1838 // Region Parsing 1839 //===----------------------------------------------------------------------===// 1840 1841 ParseResult OperationParser::parseRegion(Region ®ion, 1842 ArrayRef<Argument> entryArguments, 1843 bool isIsolatedNameScope) { 1844 // Parse the '{'. 1845 Token lBraceTok = getToken(); 1846 if (parseToken(Token::l_brace, "expected '{' to begin a region")) 1847 return failure(); 1848 1849 // If we are populating the parser state, start a new region definition. 1850 if (state.asmState) 1851 state.asmState->startRegionDefinition(); 1852 1853 // Parse the region body. 1854 if ((!entryArguments.empty() || getToken().isNot(Token::r_brace)) && 1855 parseRegionBody(region, lBraceTok.getLoc(), entryArguments, 1856 isIsolatedNameScope)) { 1857 return failure(); 1858 } 1859 consumeToken(Token::r_brace); 1860 1861 // If we are populating the parser state, finalize this region. 1862 if (state.asmState) 1863 state.asmState->finalizeRegionDefinition(); 1864 1865 return success(); 1866 } 1867 1868 ParseResult OperationParser::parseRegionBody(Region ®ion, SMLoc startLoc, 1869 ArrayRef<Argument> entryArguments, 1870 bool isIsolatedNameScope) { 1871 auto currentPt = opBuilder.saveInsertionPoint(); 1872 1873 // Push a new named value scope. 1874 pushSSANameScope(isIsolatedNameScope); 1875 1876 // Parse the first block directly to allow for it to be unnamed. 1877 auto owningBlock = std::make_unique<Block>(); 1878 Block *block = owningBlock.get(); 1879 1880 // If this block is not defined in the source file, add a definition for it 1881 // now in the assembly state. Blocks with a name will be defined when the name 1882 // is parsed. 1883 if (state.asmState && getToken().isNot(Token::caret_identifier)) 1884 state.asmState->addDefinition(block, startLoc); 1885 1886 // Add arguments to the entry block if we had the form with explicit names. 1887 if (!entryArguments.empty() && !entryArguments[0].ssaName.name.empty()) { 1888 // If we had named arguments, then don't allow a block name. 1889 if (getToken().is(Token::caret_identifier)) 1890 return emitError("invalid block name in region with named arguments"); 1891 1892 for (auto &entryArg : entryArguments) { 1893 auto &argInfo = entryArg.ssaName; 1894 1895 // Ensure that the argument was not already defined. 1896 if (auto defLoc = getReferenceLoc(argInfo.name, argInfo.number)) { 1897 return emitError(argInfo.location, "region entry argument '" + 1898 argInfo.name + 1899 "' is already in use") 1900 .attachNote(getEncodedSourceLocation(*defLoc)) 1901 << "previously referenced here"; 1902 } 1903 Location loc = entryArg.sourceLoc.hasValue() 1904 ? entryArg.sourceLoc.getValue() 1905 : getEncodedSourceLocation(argInfo.location); 1906 BlockArgument arg = block->addArgument(entryArg.type, loc); 1907 1908 // Add a definition of this arg to the assembly state if provided. 1909 if (state.asmState) 1910 state.asmState->addDefinition(arg, argInfo.location); 1911 1912 // Record the definition for this argument. 1913 if (addDefinition(argInfo, arg)) 1914 return failure(); 1915 } 1916 } 1917 1918 if (parseBlock(block)) 1919 return failure(); 1920 1921 // Verify that no other arguments were parsed. 1922 if (!entryArguments.empty() && 1923 block->getNumArguments() > entryArguments.size()) { 1924 return emitError("entry block arguments were already defined"); 1925 } 1926 1927 // Parse the rest of the region. 1928 region.push_back(owningBlock.release()); 1929 while (getToken().isNot(Token::r_brace)) { 1930 Block *newBlock = nullptr; 1931 if (parseBlock(newBlock)) 1932 return failure(); 1933 region.push_back(newBlock); 1934 } 1935 1936 // Pop the SSA value scope for this region. 1937 if (popSSANameScope()) 1938 return failure(); 1939 1940 // Reset the original insertion point. 1941 opBuilder.restoreInsertionPoint(currentPt); 1942 return success(); 1943 } 1944 1945 //===----------------------------------------------------------------------===// 1946 // Block Parsing 1947 //===----------------------------------------------------------------------===// 1948 1949 /// Block declaration. 1950 /// 1951 /// block ::= block-label? operation* 1952 /// block-label ::= block-id block-arg-list? `:` 1953 /// block-id ::= caret-id 1954 /// block-arg-list ::= `(` ssa-id-and-type-list? `)` 1955 /// 1956 ParseResult OperationParser::parseBlock(Block *&block) { 1957 // The first block of a region may already exist, if it does the caret 1958 // identifier is optional. 1959 if (block && getToken().isNot(Token::caret_identifier)) 1960 return parseBlockBody(block); 1961 1962 SMLoc nameLoc = getToken().getLoc(); 1963 auto name = getTokenSpelling(); 1964 if (parseToken(Token::caret_identifier, "expected block name")) 1965 return failure(); 1966 1967 // Define the block with the specified name. 1968 auto &blockAndLoc = getBlockInfoByName(name); 1969 blockAndLoc.loc = nameLoc; 1970 1971 // Use a unique pointer for in-flight block being parsed. Release ownership 1972 // only in the case of a successful parse. This ensures that the Block 1973 // allocated is released if the parse fails and control returns early. 1974 std::unique_ptr<Block> inflightBlock; 1975 1976 // If a block has yet to be set, this is a new definition. If the caller 1977 // provided a block, use it. Otherwise create a new one. 1978 if (!blockAndLoc.block) { 1979 if (block) { 1980 blockAndLoc.block = block; 1981 } else { 1982 inflightBlock = std::make_unique<Block>(); 1983 blockAndLoc.block = inflightBlock.get(); 1984 } 1985 1986 // Otherwise, the block has a forward declaration. Forward declarations are 1987 // removed once defined, so if we are defining a existing block and it is 1988 // not a forward declaration, then it is a redeclaration. Fail if the block 1989 // was already defined. 1990 } else if (!eraseForwardRef(blockAndLoc.block)) { 1991 return emitError(nameLoc, "redefinition of block '") << name << "'"; 1992 } 1993 1994 // Populate the high level assembly state if necessary. 1995 if (state.asmState) 1996 state.asmState->addDefinition(blockAndLoc.block, nameLoc); 1997 1998 block = blockAndLoc.block; 1999 2000 // If an argument list is present, parse it. 2001 if (getToken().is(Token::l_paren)) 2002 if (parseOptionalBlockArgList(block)) 2003 return failure(); 2004 2005 if (parseToken(Token::colon, "expected ':' after block name")) 2006 return failure(); 2007 2008 ParseResult res = parseBlockBody(block); 2009 if (succeeded(res)) 2010 inflightBlock.release(); 2011 return res; 2012 } 2013 2014 ParseResult OperationParser::parseBlockBody(Block *block) { 2015 // Set the insertion point to the end of the block to parse. 2016 opBuilder.setInsertionPointToEnd(block); 2017 2018 // Parse the list of operations that make up the body of the block. 2019 while (getToken().isNot(Token::caret_identifier, Token::r_brace)) 2020 if (parseOperation()) 2021 return failure(); 2022 2023 return success(); 2024 } 2025 2026 /// Get the block with the specified name, creating it if it doesn't already 2027 /// exist. The location specified is the point of use, which allows 2028 /// us to diagnose references to blocks that are not defined precisely. 2029 Block *OperationParser::getBlockNamed(StringRef name, SMLoc loc) { 2030 BlockDefinition &blockDef = getBlockInfoByName(name); 2031 if (!blockDef.block) { 2032 blockDef = {new Block(), loc}; 2033 insertForwardRef(blockDef.block, blockDef.loc); 2034 } 2035 2036 // Populate the high level assembly state if necessary. 2037 if (state.asmState) 2038 state.asmState->addUses(blockDef.block, loc); 2039 2040 return blockDef.block; 2041 } 2042 2043 /// Parse a (possibly empty) list of SSA operands with types as block arguments 2044 /// enclosed in parentheses. 2045 /// 2046 /// value-id-and-type-list ::= value-id-and-type (`,` ssa-id-and-type)* 2047 /// block-arg-list ::= `(` value-id-and-type-list? `)` 2048 /// 2049 ParseResult OperationParser::parseOptionalBlockArgList(Block *owner) { 2050 if (getToken().is(Token::r_brace)) 2051 return success(); 2052 2053 // If the block already has arguments, then we're handling the entry block. 2054 // Parse and register the names for the arguments, but do not add them. 2055 bool definingExistingArgs = owner->getNumArguments() != 0; 2056 unsigned nextArgument = 0; 2057 2058 return parseCommaSeparatedList(Delimiter::Paren, [&]() -> ParseResult { 2059 return parseSSADefOrUseAndType( 2060 [&](UnresolvedOperand useInfo, Type type) -> ParseResult { 2061 BlockArgument arg; 2062 2063 // If we are defining existing arguments, ensure that the argument 2064 // has already been created with the right type. 2065 if (definingExistingArgs) { 2066 // Otherwise, ensure that this argument has already been created. 2067 if (nextArgument >= owner->getNumArguments()) 2068 return emitError("too many arguments specified in argument list"); 2069 2070 // Finally, make sure the existing argument has the correct type. 2071 arg = owner->getArgument(nextArgument++); 2072 if (arg.getType() != type) 2073 return emitError("argument and block argument type mismatch"); 2074 } else { 2075 auto loc = getEncodedSourceLocation(useInfo.location); 2076 arg = owner->addArgument(type, loc); 2077 } 2078 2079 // If the argument has an explicit loc(...) specifier, parse and apply 2080 // it. 2081 if (parseTrailingLocationSpecifier(arg)) 2082 return failure(); 2083 2084 // Mark this block argument definition in the parser state if it was 2085 // provided. 2086 if (state.asmState) 2087 state.asmState->addDefinition(arg, useInfo.location); 2088 2089 return addDefinition(useInfo, arg); 2090 }); 2091 }); 2092 } 2093 2094 //===----------------------------------------------------------------------===// 2095 // Top-level entity parsing. 2096 //===----------------------------------------------------------------------===// 2097 2098 namespace { 2099 /// This parser handles entities that are only valid at the top level of the 2100 /// file. 2101 class TopLevelOperationParser : public Parser { 2102 public: 2103 explicit TopLevelOperationParser(ParserState &state) : Parser(state) {} 2104 2105 /// Parse a set of operations into the end of the given Block. 2106 ParseResult parse(Block *topLevelBlock, Location parserLoc); 2107 2108 private: 2109 /// Parse an attribute alias declaration. 2110 /// 2111 /// attribute-alias-def ::= '#' alias-name `=` attribute-value 2112 /// 2113 ParseResult parseAttributeAliasDef(); 2114 2115 /// Parse a type alias declaration. 2116 /// 2117 /// type-alias-def ::= '!' alias-name `=` type 2118 /// 2119 ParseResult parseTypeAliasDef(); 2120 2121 /// Parse a top-level file metadata dictionary. 2122 /// 2123 /// file-metadata-dict ::= '{-#' file-metadata-entry* `#-}' 2124 /// 2125 ParseResult parseFileMetadataDictionary(); 2126 2127 /// Parse a resource metadata dictionary. 2128 ParseResult parseResourceFileMetadata( 2129 function_ref<ParseResult(StringRef, SMLoc)> parseBody); 2130 ParseResult parseDialectResourceFileMetadata(); 2131 ParseResult parseExternalResourceFileMetadata(); 2132 }; 2133 2134 /// This class represents an implementation of a resource entry for the MLIR 2135 /// textual format. 2136 class ParsedResourceEntry : public AsmParsedResourceEntry { 2137 public: 2138 ParsedResourceEntry(StringRef key, SMLoc keyLoc, Token value, Parser &p) 2139 : key(key), keyLoc(keyLoc), value(value), p(p) {} 2140 ~ParsedResourceEntry() override = default; 2141 2142 StringRef getKey() const final { return key; } 2143 2144 InFlightDiagnostic emitError() const final { return p.emitError(keyLoc); } 2145 2146 FailureOr<bool> parseAsBool() const final { 2147 if (value.is(Token::kw_true)) 2148 return true; 2149 if (value.is(Token::kw_false)) 2150 return false; 2151 return p.emitError(value.getLoc(), 2152 "expected 'true' or 'false' value for key '" + key + 2153 "'"); 2154 } 2155 2156 FailureOr<std::string> parseAsString() const final { 2157 if (value.isNot(Token::string)) 2158 return p.emitError(value.getLoc(), 2159 "expected string value for key '" + key + "'"); 2160 return value.getStringValue(); 2161 } 2162 2163 FailureOr<AsmResourceBlob> 2164 parseAsBlob(BlobAllocatorFn allocator) const final { 2165 // Blob data within then textual format is represented as a hex string. 2166 // TODO: We could avoid an additional alloc+copy here if we pre-allocated 2167 // the buffer to use during hex processing. 2168 Optional<std::string> blobData = 2169 value.is(Token::string) ? value.getHexStringValue() : llvm::None; 2170 if (!blobData) 2171 return p.emitError(value.getLoc(), 2172 "expected hex string blob for key '" + key + "'"); 2173 2174 // Extract the alignment of the blob data, which gets stored at the 2175 // beginning of the string. 2176 if (blobData->size() < sizeof(uint32_t)) { 2177 return p.emitError(value.getLoc(), 2178 "expected hex string blob for key '" + key + 2179 "' to encode alignment in first 4 bytes"); 2180 } 2181 uint32_t align = 0; 2182 memcpy(&align, blobData->data(), sizeof(uint32_t)); 2183 2184 // Get the data portion of the blob. 2185 StringRef data = StringRef(*blobData).drop_front(sizeof(uint32_t)); 2186 if (data.empty()) 2187 return AsmResourceBlob(); 2188 2189 // Allocate memory for the blob using the provided allocator and copy the 2190 // data into it. 2191 AsmResourceBlob blob = allocator(data.size(), align); 2192 assert(llvm::isAddrAligned(llvm::Align(align), blob.getData().data()) && 2193 blob.isMutable() && 2194 "blob allocator did not return a properly aligned address"); 2195 memcpy(blob.getMutableData().data(), data.data(), data.size()); 2196 return blob; 2197 } 2198 2199 private: 2200 StringRef key; 2201 SMLoc keyLoc; 2202 Token value; 2203 Parser &p; 2204 }; 2205 } // namespace 2206 2207 ParseResult TopLevelOperationParser::parseAttributeAliasDef() { 2208 assert(getToken().is(Token::hash_identifier)); 2209 StringRef aliasName = getTokenSpelling().drop_front(); 2210 2211 // Check for redefinitions. 2212 if (state.symbols.attributeAliasDefinitions.count(aliasName) > 0) 2213 return emitError("redefinition of attribute alias id '" + aliasName + "'"); 2214 2215 // Make sure this isn't invading the dialect attribute namespace. 2216 if (aliasName.contains('.')) 2217 return emitError("attribute names with a '.' are reserved for " 2218 "dialect-defined names"); 2219 2220 consumeToken(Token::hash_identifier); 2221 2222 // Parse the '='. 2223 if (parseToken(Token::equal, "expected '=' in attribute alias definition")) 2224 return failure(); 2225 2226 // Parse the attribute value. 2227 Attribute attr = parseAttribute(); 2228 if (!attr) 2229 return failure(); 2230 2231 state.symbols.attributeAliasDefinitions[aliasName] = attr; 2232 return success(); 2233 } 2234 2235 ParseResult TopLevelOperationParser::parseTypeAliasDef() { 2236 assert(getToken().is(Token::exclamation_identifier)); 2237 StringRef aliasName = getTokenSpelling().drop_front(); 2238 2239 // Check for redefinitions. 2240 if (state.symbols.typeAliasDefinitions.count(aliasName) > 0) 2241 return emitError("redefinition of type alias id '" + aliasName + "'"); 2242 2243 // Make sure this isn't invading the dialect type namespace. 2244 if (aliasName.contains('.')) 2245 return emitError("type names with a '.' are reserved for " 2246 "dialect-defined names"); 2247 consumeToken(Token::exclamation_identifier); 2248 2249 // Parse the '='. 2250 if (parseToken(Token::equal, "expected '=' in type alias definition")) 2251 return failure(); 2252 2253 // Parse the type. 2254 Type aliasedType = parseType(); 2255 if (!aliasedType) 2256 return failure(); 2257 2258 // Register this alias with the parser state. 2259 state.symbols.typeAliasDefinitions.try_emplace(aliasName, aliasedType); 2260 return success(); 2261 } 2262 2263 ParseResult TopLevelOperationParser::parseFileMetadataDictionary() { 2264 consumeToken(Token::file_metadata_begin); 2265 return parseCommaSeparatedListUntil( 2266 Token::file_metadata_end, [&]() -> ParseResult { 2267 // Parse the key of the metadata dictionary. 2268 SMLoc keyLoc = getToken().getLoc(); 2269 StringRef key; 2270 if (failed(parseOptionalKeyword(&key))) 2271 return emitError("expected identifier key in file " 2272 "metadata dictionary"); 2273 if (parseToken(Token::colon, "expected ':'")) 2274 return failure(); 2275 2276 // Process the metadata entry. 2277 if (key == "dialect_resources") 2278 return parseDialectResourceFileMetadata(); 2279 if (key == "external_resources") 2280 return parseExternalResourceFileMetadata(); 2281 return emitError(keyLoc, "unknown key '" + key + 2282 "' in file metadata dictionary"); 2283 }); 2284 } 2285 2286 ParseResult TopLevelOperationParser::parseResourceFileMetadata( 2287 function_ref<ParseResult(StringRef, SMLoc)> parseBody) { 2288 if (parseToken(Token::l_brace, "expected '{'")) 2289 return failure(); 2290 2291 return parseCommaSeparatedListUntil(Token::r_brace, [&]() -> ParseResult { 2292 // Parse the top-level name entry. 2293 SMLoc nameLoc = getToken().getLoc(); 2294 StringRef name; 2295 if (failed(parseOptionalKeyword(&name))) 2296 return emitError("expected identifier key for 'resource' entry"); 2297 2298 if (parseToken(Token::colon, "expected ':'") || 2299 parseToken(Token::l_brace, "expected '{'")) 2300 return failure(); 2301 return parseBody(name, nameLoc); 2302 }); 2303 } 2304 2305 ParseResult TopLevelOperationParser::parseDialectResourceFileMetadata() { 2306 return parseResourceFileMetadata([&](StringRef name, 2307 SMLoc nameLoc) -> ParseResult { 2308 // Lookup the dialect and check that it can handle a resource entry. 2309 Dialect *dialect = getContext()->getOrLoadDialect(name); 2310 if (!dialect) 2311 return emitError(nameLoc, "dialect '" + name + "' is unknown"); 2312 const auto *handler = dyn_cast<OpAsmDialectInterface>(dialect); 2313 if (!handler) { 2314 return emitError() << "unexpected 'resource' section for dialect '" 2315 << dialect->getNamespace() << "'"; 2316 } 2317 2318 return parseCommaSeparatedListUntil(Token::r_brace, [&]() -> ParseResult { 2319 // Parse the name of the resource entry. 2320 SMLoc keyLoc = getToken().getLoc(); 2321 StringRef key; 2322 if (failed(parseResourceHandle(handler, key)) || 2323 parseToken(Token::colon, "expected ':'")) 2324 return failure(); 2325 Token valueTok = getToken(); 2326 consumeToken(); 2327 2328 ParsedResourceEntry entry(key, keyLoc, valueTok, *this); 2329 return handler->parseResource(entry); 2330 }); 2331 }); 2332 } 2333 2334 ParseResult TopLevelOperationParser::parseExternalResourceFileMetadata() { 2335 return parseResourceFileMetadata([&](StringRef name, 2336 SMLoc nameLoc) -> ParseResult { 2337 AsmResourceParser *handler = state.config.getResourceParser(name); 2338 2339 // TODO: Should we require handling external resources in some scenarios? 2340 if (!handler) { 2341 emitWarning(getEncodedSourceLocation(nameLoc)) 2342 << "ignoring unknown external resources for '" << name << "'"; 2343 } 2344 2345 return parseCommaSeparatedListUntil(Token::r_brace, [&]() -> ParseResult { 2346 // Parse the name of the resource entry. 2347 SMLoc keyLoc = getToken().getLoc(); 2348 StringRef key; 2349 if (failed(parseOptionalKeyword(&key))) 2350 return emitError( 2351 "expected identifier key for 'external_resources' entry"); 2352 if (parseToken(Token::colon, "expected ':'")) 2353 return failure(); 2354 Token valueTok = getToken(); 2355 consumeToken(); 2356 2357 if (!handler) 2358 return success(); 2359 ParsedResourceEntry entry(key, keyLoc, valueTok, *this); 2360 return handler->parseResource(entry); 2361 }); 2362 }); 2363 } 2364 2365 ParseResult TopLevelOperationParser::parse(Block *topLevelBlock, 2366 Location parserLoc) { 2367 // Create a top-level operation to contain the parsed state. 2368 OwningOpRef<ModuleOp> topLevelOp(ModuleOp::create(parserLoc)); 2369 OperationParser opParser(state, topLevelOp.get()); 2370 while (true) { 2371 switch (getToken().getKind()) { 2372 default: 2373 // Parse a top-level operation. 2374 if (opParser.parseOperation()) 2375 return failure(); 2376 break; 2377 2378 // If we got to the end of the file, then we're done. 2379 case Token::eof: { 2380 if (opParser.finalize()) 2381 return failure(); 2382 2383 // Splice the blocks of the parsed operation over to the provided 2384 // top-level block. 2385 auto &parsedOps = topLevelOp->getBody()->getOperations(); 2386 auto &destOps = topLevelBlock->getOperations(); 2387 destOps.splice(destOps.empty() ? destOps.end() : std::prev(destOps.end()), 2388 parsedOps, parsedOps.begin(), parsedOps.end()); 2389 return success(); 2390 } 2391 2392 // If we got an error token, then the lexer already emitted an error, just 2393 // stop. Someday we could introduce error recovery if there was demand 2394 // for it. 2395 case Token::error: 2396 return failure(); 2397 2398 // Parse an attribute alias. 2399 case Token::hash_identifier: 2400 if (parseAttributeAliasDef()) 2401 return failure(); 2402 break; 2403 2404 // Parse a type alias. 2405 case Token::exclamation_identifier: 2406 if (parseTypeAliasDef()) 2407 return failure(); 2408 break; 2409 2410 // Parse a file-level metadata dictionary. 2411 case Token::file_metadata_begin: 2412 if (parseFileMetadataDictionary()) 2413 return failure(); 2414 break; 2415 } 2416 } 2417 } 2418 2419 //===----------------------------------------------------------------------===// 2420 2421 LogicalResult mlir::parseSourceFile(const llvm::SourceMgr &sourceMgr, 2422 Block *block, const ParserConfig &config, 2423 LocationAttr *sourceFileLoc, 2424 AsmParserState *asmState) { 2425 const auto *sourceBuf = sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()); 2426 2427 Location parserLoc = 2428 FileLineColLoc::get(config.getContext(), sourceBuf->getBufferIdentifier(), 2429 /*line=*/0, /*column=*/0); 2430 if (sourceFileLoc) 2431 *sourceFileLoc = parserLoc; 2432 2433 SymbolState aliasState; 2434 ParserState state(sourceMgr, config, aliasState, asmState); 2435 return TopLevelOperationParser(state).parse(block, parserLoc); 2436 } 2437 2438 LogicalResult mlir::parseSourceFile(llvm::StringRef filename, Block *block, 2439 const ParserConfig &config, 2440 LocationAttr *sourceFileLoc) { 2441 llvm::SourceMgr sourceMgr; 2442 return parseSourceFile(filename, sourceMgr, block, config, sourceFileLoc); 2443 } 2444 2445 LogicalResult mlir::parseSourceFile(llvm::StringRef filename, 2446 llvm::SourceMgr &sourceMgr, Block *block, 2447 const ParserConfig &config, 2448 LocationAttr *sourceFileLoc, 2449 AsmParserState *asmState) { 2450 if (sourceMgr.getNumBuffers() != 0) { 2451 // TODO: Extend to support multiple buffers. 2452 return emitError(mlir::UnknownLoc::get(config.getContext()), 2453 "only main buffer parsed at the moment"); 2454 } 2455 auto fileOrErr = llvm::MemoryBuffer::getFileOrSTDIN(filename); 2456 if (std::error_code error = fileOrErr.getError()) 2457 return emitError(mlir::UnknownLoc::get(config.getContext()), 2458 "could not open input file " + filename); 2459 2460 // Load the MLIR source file. 2461 sourceMgr.AddNewSourceBuffer(std::move(*fileOrErr), SMLoc()); 2462 return parseSourceFile(sourceMgr, block, config, sourceFileLoc, asmState); 2463 } 2464 2465 LogicalResult mlir::parseSourceString(llvm::StringRef sourceStr, Block *block, 2466 const ParserConfig &config, 2467 LocationAttr *sourceFileLoc) { 2468 auto memBuffer = MemoryBuffer::getMemBuffer(sourceStr); 2469 if (!memBuffer) 2470 return failure(); 2471 2472 SourceMgr sourceMgr; 2473 sourceMgr.AddNewSourceBuffer(std::move(memBuffer), SMLoc()); 2474 return parseSourceFile(sourceMgr, block, config, sourceFileLoc); 2475 } 2476