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