1 //===- AsmPrinter.cpp - MLIR Assembly Printer 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 MLIR AsmPrinter class, which is used to implement 10 // the various print() methods on the core IR objects. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "mlir/IR/AffineExpr.h" 15 #include "mlir/IR/AffineMap.h" 16 #include "mlir/IR/AsmState.h" 17 #include "mlir/IR/Attributes.h" 18 #include "mlir/IR/Dialect.h" 19 #include "mlir/IR/DialectImplementation.h" 20 #include "mlir/IR/Function.h" 21 #include "mlir/IR/IntegerSet.h" 22 #include "mlir/IR/MLIRContext.h" 23 #include "mlir/IR/Module.h" 24 #include "mlir/IR/OpImplementation.h" 25 #include "mlir/IR/Operation.h" 26 #include "mlir/IR/StandardTypes.h" 27 #include "llvm/ADT/APFloat.h" 28 #include "llvm/ADT/DenseMap.h" 29 #include "llvm/ADT/MapVector.h" 30 #include "llvm/ADT/STLExtras.h" 31 #include "llvm/ADT/ScopedHashTable.h" 32 #include "llvm/ADT/SetVector.h" 33 #include "llvm/ADT/SmallString.h" 34 #include "llvm/ADT/StringExtras.h" 35 #include "llvm/ADT/StringSet.h" 36 #include "llvm/Support/CommandLine.h" 37 #include "llvm/Support/Regex.h" 38 #include "llvm/Support/SaveAndRestore.h" 39 using namespace mlir; 40 using namespace mlir::detail; 41 42 void Identifier::print(raw_ostream &os) const { os << str(); } 43 44 void Identifier::dump() const { print(llvm::errs()); } 45 46 void OperationName::print(raw_ostream &os) const { os << getStringRef(); } 47 48 void OperationName::dump() const { print(llvm::errs()); } 49 50 DialectAsmPrinter::~DialectAsmPrinter() {} 51 52 OpAsmPrinter::~OpAsmPrinter() {} 53 54 //===--------------------------------------------------------------------===// 55 // Operation OpAsm interface. 56 //===--------------------------------------------------------------------===// 57 58 /// The OpAsmOpInterface, see OpAsmInterface.td for more details. 59 #include "mlir/IR/OpAsmInterface.cpp.inc" 60 61 //===----------------------------------------------------------------------===// 62 // OpPrintingFlags 63 //===----------------------------------------------------------------------===// 64 65 namespace { 66 /// This struct contains command line options that can be used to initialize 67 /// various bits of the AsmPrinter. This uses a struct wrapper to avoid the need 68 /// for global command line options. 69 struct AsmPrinterOptions { 70 llvm::cl::opt<int64_t> printElementsAttrWithHexIfLarger{ 71 "mlir-print-elementsattrs-with-hex-if-larger", 72 llvm::cl::desc( 73 "Print DenseElementsAttrs with a hex string that have " 74 "more elements than the given upper limit (use -1 to disable)")}; 75 76 llvm::cl::opt<unsigned> elideElementsAttrIfLarger{ 77 "mlir-elide-elementsattrs-if-larger", 78 llvm::cl::desc("Elide ElementsAttrs with \"...\" that have " 79 "more elements than the given upper limit")}; 80 81 llvm::cl::opt<bool> printDebugInfoOpt{ 82 "mlir-print-debuginfo", llvm::cl::init(false), 83 llvm::cl::desc("Print debug info in MLIR output")}; 84 85 llvm::cl::opt<bool> printPrettyDebugInfoOpt{ 86 "mlir-pretty-debuginfo", llvm::cl::init(false), 87 llvm::cl::desc("Print pretty debug info in MLIR output")}; 88 89 // Use the generic op output form in the operation printer even if the custom 90 // form is defined. 91 llvm::cl::opt<bool> printGenericOpFormOpt{ 92 "mlir-print-op-generic", llvm::cl::init(false), 93 llvm::cl::desc("Print the generic op form"), llvm::cl::Hidden}; 94 95 llvm::cl::opt<bool> printLocalScopeOpt{ 96 "mlir-print-local-scope", llvm::cl::init(false), 97 llvm::cl::desc("Print assuming in local scope by default"), 98 llvm::cl::Hidden}; 99 }; 100 } // end anonymous namespace 101 102 static llvm::ManagedStatic<AsmPrinterOptions> clOptions; 103 104 /// Register a set of useful command-line options that can be used to configure 105 /// various flags within the AsmPrinter. 106 void mlir::registerAsmPrinterCLOptions() { 107 // Make sure that the options struct has been initialized. 108 *clOptions; 109 } 110 111 /// Initialize the printing flags with default supplied by the cl::opts above. 112 OpPrintingFlags::OpPrintingFlags() 113 : printDebugInfoFlag(false), printDebugInfoPrettyFormFlag(false), 114 printGenericOpFormFlag(false), printLocalScope(false) { 115 // Initialize based upon command line options, if they are available. 116 if (!clOptions.isConstructed()) 117 return; 118 if (clOptions->elideElementsAttrIfLarger.getNumOccurrences()) 119 elementsAttrElementLimit = clOptions->elideElementsAttrIfLarger; 120 printDebugInfoFlag = clOptions->printDebugInfoOpt; 121 printDebugInfoPrettyFormFlag = clOptions->printPrettyDebugInfoOpt; 122 printGenericOpFormFlag = clOptions->printGenericOpFormOpt; 123 printLocalScope = clOptions->printLocalScopeOpt; 124 } 125 126 /// Enable the elision of large elements attributes, by printing a '...' 127 /// instead of the element data, when the number of elements is greater than 128 /// `largeElementLimit`. Note: The IR generated with this option is not 129 /// parsable. 130 OpPrintingFlags & 131 OpPrintingFlags::elideLargeElementsAttrs(int64_t largeElementLimit) { 132 elementsAttrElementLimit = largeElementLimit; 133 return *this; 134 } 135 136 /// Enable printing of debug information. If 'prettyForm' is set to true, 137 /// debug information is printed in a more readable 'pretty' form. 138 OpPrintingFlags &OpPrintingFlags::enableDebugInfo(bool prettyForm) { 139 printDebugInfoFlag = true; 140 printDebugInfoPrettyFormFlag = prettyForm; 141 return *this; 142 } 143 144 /// Always print operations in the generic form. 145 OpPrintingFlags &OpPrintingFlags::printGenericOpForm() { 146 printGenericOpFormFlag = true; 147 return *this; 148 } 149 150 /// Use local scope when printing the operation. This allows for using the 151 /// printer in a more localized and thread-safe setting, but may not necessarily 152 /// be identical of what the IR will look like when dumping the full module. 153 OpPrintingFlags &OpPrintingFlags::useLocalScope() { 154 printLocalScope = true; 155 return *this; 156 } 157 158 /// Return if the given ElementsAttr should be elided. 159 bool OpPrintingFlags::shouldElideElementsAttr(ElementsAttr attr) const { 160 return elementsAttrElementLimit.hasValue() && 161 *elementsAttrElementLimit < int64_t(attr.getNumElements()); 162 } 163 164 /// Return the size limit for printing large ElementsAttr. 165 Optional<int64_t> OpPrintingFlags::getLargeElementsAttrLimit() const { 166 return elementsAttrElementLimit; 167 } 168 169 /// Return if debug information should be printed. 170 bool OpPrintingFlags::shouldPrintDebugInfo() const { 171 return printDebugInfoFlag; 172 } 173 174 /// Return if debug information should be printed in the pretty form. 175 bool OpPrintingFlags::shouldPrintDebugInfoPrettyForm() const { 176 return printDebugInfoPrettyFormFlag; 177 } 178 179 /// Return if operations should be printed in the generic form. 180 bool OpPrintingFlags::shouldPrintGenericOpForm() const { 181 return printGenericOpFormFlag; 182 } 183 184 /// Return if the printer should use local scope when dumping the IR. 185 bool OpPrintingFlags::shouldUseLocalScope() const { return printLocalScope; } 186 187 /// Returns true if an ElementsAttr with the given number of elements should be 188 /// printed with hex. 189 static bool shouldPrintElementsAttrWithHex(int64_t numElements) { 190 // Check to see if a command line option was provided for the limit. 191 if (clOptions.isConstructed()) { 192 if (clOptions->printElementsAttrWithHexIfLarger.getNumOccurrences()) { 193 // -1 is used to disable hex printing. 194 if (clOptions->printElementsAttrWithHexIfLarger == -1) 195 return false; 196 return numElements > clOptions->printElementsAttrWithHexIfLarger; 197 } 198 } 199 200 // Otherwise, default to printing with hex if the number of elements is >100. 201 return numElements > 100; 202 } 203 204 //===----------------------------------------------------------------------===// 205 // NewLineCounter 206 //===----------------------------------------------------------------------===// 207 208 namespace { 209 /// This class is a simple formatter that emits a new line when inputted into a 210 /// stream, that enables counting the number of newlines emitted. This class 211 /// should be used whenever emitting newlines in the printer. 212 struct NewLineCounter { 213 unsigned curLine = 1; 214 }; 215 } // end anonymous namespace 216 217 static raw_ostream &operator<<(raw_ostream &os, NewLineCounter &newLine) { 218 ++newLine.curLine; 219 return os << '\n'; 220 } 221 222 //===----------------------------------------------------------------------===// 223 // AliasState 224 //===----------------------------------------------------------------------===// 225 226 namespace { 227 /// This class manages the state for type and attribute aliases. 228 class AliasState { 229 public: 230 // Initialize the internal aliases. 231 void 232 initialize(Operation *op, 233 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces); 234 235 /// Return a name used for an attribute alias, or empty if there is no alias. 236 Twine getAttributeAlias(Attribute attr) const; 237 238 /// Print all of the referenced attribute aliases. 239 void printAttributeAliases(raw_ostream &os, NewLineCounter &newLine) const; 240 241 /// Return a string to use as an alias for the given type, or empty if there 242 /// is no alias recorded. 243 StringRef getTypeAlias(Type ty) const; 244 245 /// Print all of the referenced type aliases. 246 void printTypeAliases(raw_ostream &os, NewLineCounter &newLine) const; 247 248 private: 249 /// A special index constant used for non-kind attribute aliases. 250 enum { NonAttrKindAlias = -1 }; 251 252 /// Record a reference to the given attribute. 253 void recordAttributeReference(Attribute attr); 254 255 /// Record a reference to the given type. 256 void recordTypeReference(Type ty); 257 258 // Visit functions. 259 void visitOperation(Operation *op); 260 void visitType(Type type); 261 void visitAttribute(Attribute attr); 262 263 /// Set of attributes known to be used within the module. 264 llvm::SetVector<Attribute> usedAttributes; 265 266 /// Mapping between attribute and a pair comprised of a base alias name and a 267 /// count suffix. If the suffix is set to -1, it is not displayed. 268 llvm::MapVector<Attribute, std::pair<StringRef, int>> attrToAlias; 269 270 /// Mapping between attribute kind and a pair comprised of a base alias name 271 /// and a unique list of attributes belonging to this kind sorted by location 272 /// seen in the module. 273 llvm::MapVector<unsigned, std::pair<StringRef, std::vector<Attribute>>> 274 attrKindToAlias; 275 276 /// Set of types known to be used within the module. 277 llvm::SetVector<Type> usedTypes; 278 279 /// A mapping between a type and a given alias. 280 DenseMap<Type, StringRef> typeToAlias; 281 }; 282 } // end anonymous namespace 283 284 // Utility to generate a function to register a symbol alias. 285 static bool canRegisterAlias(StringRef name, llvm::StringSet<> &usedAliases) { 286 assert(!name.empty() && "expected alias name to be non-empty"); 287 // TODO(riverriddle) Assert that the provided alias name can be lexed as 288 // an identifier. 289 290 // Check that the alias doesn't contain a '.' character and the name is not 291 // already in use. 292 return !name.contains('.') && usedAliases.insert(name).second; 293 } 294 295 void AliasState::initialize( 296 Operation *op, 297 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces) { 298 // Track the identifiers in use for each symbol so that the same identifier 299 // isn't used twice. 300 llvm::StringSet<> usedAliases; 301 302 // Collect the set of aliases from each dialect. 303 SmallVector<std::pair<unsigned, StringRef>, 8> attributeKindAliases; 304 SmallVector<std::pair<Attribute, StringRef>, 8> attributeAliases; 305 SmallVector<std::pair<Type, StringRef>, 16> typeAliases; 306 307 // AffineMap/Integer set have specific kind aliases. 308 attributeKindAliases.emplace_back(StandardAttributes::AffineMap, "map"); 309 attributeKindAliases.emplace_back(StandardAttributes::IntegerSet, "set"); 310 311 for (auto &interface : interfaces) { 312 interface.getAttributeKindAliases(attributeKindAliases); 313 interface.getAttributeAliases(attributeAliases); 314 interface.getTypeAliases(typeAliases); 315 } 316 317 // Setup the attribute kind aliases. 318 StringRef alias; 319 unsigned attrKind; 320 for (auto &attrAliasPair : attributeKindAliases) { 321 std::tie(attrKind, alias) = attrAliasPair; 322 assert(!alias.empty() && "expected non-empty alias string"); 323 if (!usedAliases.count(alias) && !alias.contains('.')) 324 attrKindToAlias.insert({attrKind, {alias, {}}}); 325 } 326 327 // Clear the set of used identifiers so that the attribute kind aliases are 328 // just a prefix and not the full alias, i.e. there may be some overlap. 329 usedAliases.clear(); 330 331 // Register the attribute aliases. 332 // Create a regex for the attribute kind alias names, these have a prefix with 333 // a counter appended to the end. We prevent normal aliases from having these 334 // names to avoid collisions. 335 llvm::Regex reservedAttrNames("[0-9]+$"); 336 337 // Attribute value aliases. 338 Attribute attr; 339 for (auto &attrAliasPair : attributeAliases) { 340 std::tie(attr, alias) = attrAliasPair; 341 if (!reservedAttrNames.match(alias) && canRegisterAlias(alias, usedAliases)) 342 attrToAlias.insert({attr, {alias, NonAttrKindAlias}}); 343 } 344 345 // Clear the set of used identifiers as types can have the same identifiers as 346 // affine structures. 347 usedAliases.clear(); 348 349 // Type aliases. 350 for (auto &typeAliasPair : typeAliases) 351 if (canRegisterAlias(typeAliasPair.second, usedAliases)) 352 typeToAlias.insert(typeAliasPair); 353 354 // Traverse the given IR to generate the set of used attributes/types. 355 op->walk([&](Operation *op) { visitOperation(op); }); 356 } 357 358 /// Return a name used for an attribute alias, or empty if there is no alias. 359 Twine AliasState::getAttributeAlias(Attribute attr) const { 360 auto alias = attrToAlias.find(attr); 361 if (alias == attrToAlias.end()) 362 return Twine(); 363 364 // Return the alias for this attribute, along with the index if this was 365 // generated by a kind alias. 366 int kindIndex = alias->second.second; 367 return alias->second.first + 368 (kindIndex == NonAttrKindAlias ? Twine() : Twine(kindIndex)); 369 } 370 371 /// Print all of the referenced attribute aliases. 372 void AliasState::printAttributeAliases(raw_ostream &os, 373 NewLineCounter &newLine) const { 374 auto printAlias = [&](StringRef alias, Attribute attr, int index) { 375 os << '#' << alias; 376 if (index != NonAttrKindAlias) 377 os << index; 378 os << " = " << attr << newLine; 379 }; 380 381 // Print all of the attribute kind aliases. 382 for (auto &kindAlias : attrKindToAlias) { 383 auto &aliasAttrsPair = kindAlias.second; 384 for (unsigned i = 0, e = aliasAttrsPair.second.size(); i != e; ++i) 385 printAlias(aliasAttrsPair.first, aliasAttrsPair.second[i], i); 386 os << newLine; 387 } 388 389 // In a second pass print all of the remaining attribute aliases that aren't 390 // kind aliases. 391 for (Attribute attr : usedAttributes) { 392 auto alias = attrToAlias.find(attr); 393 if (alias != attrToAlias.end() && alias->second.second == NonAttrKindAlias) 394 printAlias(alias->second.first, attr, alias->second.second); 395 } 396 } 397 398 /// Return a string to use as an alias for the given type, or empty if there 399 /// is no alias recorded. 400 StringRef AliasState::getTypeAlias(Type ty) const { 401 return typeToAlias.lookup(ty); 402 } 403 404 /// Print all of the referenced type aliases. 405 void AliasState::printTypeAliases(raw_ostream &os, 406 NewLineCounter &newLine) const { 407 for (Type type : usedTypes) { 408 auto alias = typeToAlias.find(type); 409 if (alias != typeToAlias.end()) 410 os << '!' << alias->second << " = type " << type << newLine; 411 } 412 } 413 414 /// Record a reference to the given attribute. 415 void AliasState::recordAttributeReference(Attribute attr) { 416 // Don't recheck attributes that have already been seen or those that 417 // already have an alias. 418 if (!usedAttributes.insert(attr) || attrToAlias.count(attr)) 419 return; 420 421 // If this attribute kind has an alias, then record one for this attribute. 422 auto alias = attrKindToAlias.find(static_cast<unsigned>(attr.getKind())); 423 if (alias == attrKindToAlias.end()) 424 return; 425 std::pair<StringRef, int> attrAlias(alias->second.first, 426 alias->second.second.size()); 427 attrToAlias.insert({attr, attrAlias}); 428 alias->second.second.push_back(attr); 429 } 430 431 /// Record a reference to the given type. 432 void AliasState::recordTypeReference(Type ty) { usedTypes.insert(ty); } 433 434 // TODO Support visiting other types/operations when implemented. 435 void AliasState::visitType(Type type) { 436 recordTypeReference(type); 437 438 if (auto funcType = type.dyn_cast<FunctionType>()) { 439 // Visit input and result types for functions. 440 for (auto input : funcType.getInputs()) 441 visitType(input); 442 for (auto result : funcType.getResults()) 443 visitType(result); 444 } else if (auto shapedType = type.dyn_cast<ShapedType>()) { 445 visitType(shapedType.getElementType()); 446 447 // Visit affine maps in memref type. 448 if (auto memref = type.dyn_cast<MemRefType>()) 449 for (auto map : memref.getAffineMaps()) 450 recordAttributeReference(AffineMapAttr::get(map)); 451 } 452 } 453 454 void AliasState::visitAttribute(Attribute attr) { 455 recordAttributeReference(attr); 456 457 if (auto arrayAttr = attr.dyn_cast<ArrayAttr>()) { 458 for (auto elt : arrayAttr.getValue()) 459 visitAttribute(elt); 460 } else if (auto typeAttr = attr.dyn_cast<TypeAttr>()) { 461 visitType(typeAttr.getValue()); 462 } 463 } 464 465 void AliasState::visitOperation(Operation *op) { 466 // Visit all the types used in the operation. 467 for (auto type : op->getOperandTypes()) 468 visitType(type); 469 for (auto type : op->getResultTypes()) 470 visitType(type); 471 for (auto ®ion : op->getRegions()) 472 for (auto &block : region) 473 for (auto arg : block.getArguments()) 474 visitType(arg.getType()); 475 476 // Visit each of the attributes. 477 for (auto elt : op->getAttrs()) 478 visitAttribute(elt.second); 479 } 480 481 //===----------------------------------------------------------------------===// 482 // SSANameState 483 //===----------------------------------------------------------------------===// 484 485 namespace { 486 /// This class manages the state of SSA value names. 487 class SSANameState { 488 public: 489 /// A sentinel value used for values with names set. 490 enum : unsigned { NameSentinel = ~0U }; 491 492 SSANameState(Operation *op, 493 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces); 494 495 /// Print the SSA identifier for the given value to 'stream'. If 496 /// 'printResultNo' is true, it also presents the result number ('#' number) 497 /// of this value. 498 void printValueID(Value value, bool printResultNo, raw_ostream &stream) const; 499 500 /// Return the result indices for each of the result groups registered by this 501 /// operation, or empty if none exist. 502 ArrayRef<int> getOpResultGroups(Operation *op); 503 504 /// Get the ID for the given block. 505 unsigned getBlockID(Block *block); 506 507 /// Renumber the arguments for the specified region to the same names as the 508 /// SSA values in namesToUse. See OperationPrinter::shadowRegionArgs for 509 /// details. 510 void shadowRegionArgs(Region ®ion, ValueRange namesToUse); 511 512 private: 513 /// Number the SSA values within the given IR unit. 514 void numberValuesInRegion( 515 Region ®ion, 516 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces); 517 void numberValuesInBlock( 518 Block &block, 519 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces); 520 void numberValuesInOp( 521 Operation &op, 522 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces); 523 524 /// Given a result of an operation 'result', find the result group head 525 /// 'lookupValue' and the result of 'result' within that group in 526 /// 'lookupResultNo'. 'lookupResultNo' is only filled in if the result group 527 /// has more than 1 result. 528 void getResultIDAndNumber(OpResult result, Value &lookupValue, 529 Optional<int> &lookupResultNo) const; 530 531 /// Set a special value name for the given value. 532 void setValueName(Value value, StringRef name); 533 534 /// Uniques the given value name within the printer. If the given name 535 /// conflicts, it is automatically renamed. 536 StringRef uniqueValueName(StringRef name); 537 538 /// This is the value ID for each SSA value. If this returns NameSentinel, 539 /// then the valueID has an entry in valueNames. 540 DenseMap<Value, unsigned> valueIDs; 541 DenseMap<Value, StringRef> valueNames; 542 543 /// This is a map of operations that contain multiple named result groups, 544 /// i.e. there may be multiple names for the results of the operation. The 545 /// value of this map are the result numbers that start a result group. 546 DenseMap<Operation *, SmallVector<int, 1>> opResultGroups; 547 548 /// This is the block ID for each block in the current. 549 DenseMap<Block *, unsigned> blockIDs; 550 551 /// This keeps track of all of the non-numeric names that are in flight, 552 /// allowing us to check for duplicates. 553 /// Note: the value of the map is unused. 554 llvm::ScopedHashTable<StringRef, char> usedNames; 555 llvm::BumpPtrAllocator usedNameAllocator; 556 557 /// This is the next value ID to assign in numbering. 558 unsigned nextValueID = 0; 559 /// This is the next ID to assign to a region entry block argument. 560 unsigned nextArgumentID = 0; 561 /// This is the next ID to assign when a name conflict is detected. 562 unsigned nextConflictID = 0; 563 }; 564 } // end anonymous namespace 565 566 SSANameState::SSANameState( 567 Operation *op, 568 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces) { 569 llvm::ScopedHashTable<StringRef, char>::ScopeTy usedNamesScope(usedNames); 570 numberValuesInOp(*op, interfaces); 571 572 for (auto ®ion : op->getRegions()) 573 numberValuesInRegion(region, interfaces); 574 } 575 576 void SSANameState::printValueID(Value value, bool printResultNo, 577 raw_ostream &stream) const { 578 if (!value) { 579 stream << "<<NULL>>"; 580 return; 581 } 582 583 Optional<int> resultNo; 584 auto lookupValue = value; 585 586 // If this is an operation result, collect the head lookup value of the result 587 // group and the result number of 'result' within that group. 588 if (OpResult result = value.dyn_cast<OpResult>()) 589 getResultIDAndNumber(result, lookupValue, resultNo); 590 591 auto it = valueIDs.find(lookupValue); 592 if (it == valueIDs.end()) { 593 stream << "<<UNKNOWN SSA VALUE>>"; 594 return; 595 } 596 597 stream << '%'; 598 if (it->second != NameSentinel) { 599 stream << it->second; 600 } else { 601 auto nameIt = valueNames.find(lookupValue); 602 assert(nameIt != valueNames.end() && "Didn't have a name entry?"); 603 stream << nameIt->second; 604 } 605 606 if (resultNo.hasValue() && printResultNo) 607 stream << '#' << resultNo; 608 } 609 610 ArrayRef<int> SSANameState::getOpResultGroups(Operation *op) { 611 auto it = opResultGroups.find(op); 612 return it == opResultGroups.end() ? ArrayRef<int>() : it->second; 613 } 614 615 unsigned SSANameState::getBlockID(Block *block) { 616 auto it = blockIDs.find(block); 617 return it != blockIDs.end() ? it->second : NameSentinel; 618 } 619 620 void SSANameState::shadowRegionArgs(Region ®ion, ValueRange namesToUse) { 621 assert(!region.empty() && "cannot shadow arguments of an empty region"); 622 assert(region.front().getNumArguments() == namesToUse.size() && 623 "incorrect number of names passed in"); 624 assert(region.getParentOp()->isKnownIsolatedFromAbove() && 625 "only KnownIsolatedFromAbove ops can shadow names"); 626 627 SmallVector<char, 16> nameStr; 628 for (unsigned i = 0, e = namesToUse.size(); i != e; ++i) { 629 auto nameToUse = namesToUse[i]; 630 if (nameToUse == nullptr) 631 continue; 632 auto nameToReplace = region.front().getArgument(i); 633 634 nameStr.clear(); 635 llvm::raw_svector_ostream nameStream(nameStr); 636 printValueID(nameToUse, /*printResultNo=*/true, nameStream); 637 638 // Entry block arguments should already have a pretty "arg" name. 639 assert(valueIDs[nameToReplace] == NameSentinel); 640 641 // Use the name without the leading %. 642 auto name = StringRef(nameStream.str()).drop_front(); 643 644 // Overwrite the name. 645 valueNames[nameToReplace] = name.copy(usedNameAllocator); 646 } 647 } 648 649 void SSANameState::numberValuesInRegion( 650 Region ®ion, 651 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces) { 652 // Save the current value ids to allow for numbering values in sibling regions 653 // the same. 654 llvm::SaveAndRestore<unsigned> valueIDSaver(nextValueID); 655 llvm::SaveAndRestore<unsigned> argumentIDSaver(nextArgumentID); 656 llvm::SaveAndRestore<unsigned> conflictIDSaver(nextConflictID); 657 658 // Push a new used names scope. 659 llvm::ScopedHashTable<StringRef, char>::ScopeTy usedNamesScope(usedNames); 660 661 // Number the values within this region in a breadth-first order. 662 unsigned nextBlockID = 0; 663 for (auto &block : region) { 664 // Each block gets a unique ID, and all of the operations within it get 665 // numbered as well. 666 blockIDs[&block] = nextBlockID++; 667 numberValuesInBlock(block, interfaces); 668 } 669 670 // After that we traverse the nested regions. 671 // TODO: Rework this loop to not use recursion. 672 for (auto &block : region) { 673 for (auto &op : block) 674 for (auto &nestedRegion : op.getRegions()) 675 numberValuesInRegion(nestedRegion, interfaces); 676 } 677 } 678 679 void SSANameState::numberValuesInBlock( 680 Block &block, 681 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces) { 682 auto setArgNameFn = [&](Value arg, StringRef name) { 683 assert(!valueIDs.count(arg) && "arg numbered multiple times"); 684 assert(arg.cast<BlockArgument>().getOwner() == &block && 685 "arg not defined in 'block'"); 686 setValueName(arg, name); 687 }; 688 689 bool isEntryBlock = block.isEntryBlock(); 690 if (isEntryBlock) { 691 if (auto *op = block.getParentOp()) { 692 if (auto asmInterface = interfaces.getInterfaceFor(op->getDialect())) 693 asmInterface->getAsmBlockArgumentNames(&block, setArgNameFn); 694 } 695 } 696 697 // Number the block arguments. We give entry block arguments a special name 698 // 'arg'. 699 SmallString<32> specialNameBuffer(isEntryBlock ? "arg" : ""); 700 llvm::raw_svector_ostream specialName(specialNameBuffer); 701 for (auto arg : block.getArguments()) { 702 if (valueIDs.count(arg)) 703 continue; 704 if (isEntryBlock) { 705 specialNameBuffer.resize(strlen("arg")); 706 specialName << nextArgumentID++; 707 } 708 setValueName(arg, specialName.str()); 709 } 710 711 // Number the operations in this block. 712 for (auto &op : block) 713 numberValuesInOp(op, interfaces); 714 } 715 716 void SSANameState::numberValuesInOp( 717 Operation &op, 718 DialectInterfaceCollection<OpAsmDialectInterface> &interfaces) { 719 unsigned numResults = op.getNumResults(); 720 if (numResults == 0) 721 return; 722 Value resultBegin = op.getResult(0); 723 724 // Function used to set the special result names for the operation. 725 SmallVector<int, 2> resultGroups(/*Size=*/1, /*Value=*/0); 726 auto setResultNameFn = [&](Value result, StringRef name) { 727 assert(!valueIDs.count(result) && "result numbered multiple times"); 728 assert(result.getDefiningOp() == &op && "result not defined by 'op'"); 729 setValueName(result, name); 730 731 // Record the result number for groups not anchored at 0. 732 if (int resultNo = result.cast<OpResult>().getResultNumber()) 733 resultGroups.push_back(resultNo); 734 }; 735 if (OpAsmOpInterface asmInterface = dyn_cast<OpAsmOpInterface>(&op)) 736 asmInterface.getAsmResultNames(setResultNameFn); 737 else if (auto *asmInterface = interfaces.getInterfaceFor(op.getDialect())) 738 asmInterface->getAsmResultNames(&op, setResultNameFn); 739 740 // If the first result wasn't numbered, give it a default number. 741 if (valueIDs.try_emplace(resultBegin, nextValueID).second) 742 ++nextValueID; 743 744 // If this operation has multiple result groups, mark it. 745 if (resultGroups.size() != 1) { 746 llvm::array_pod_sort(resultGroups.begin(), resultGroups.end()); 747 opResultGroups.try_emplace(&op, std::move(resultGroups)); 748 } 749 } 750 751 void SSANameState::getResultIDAndNumber(OpResult result, Value &lookupValue, 752 Optional<int> &lookupResultNo) const { 753 Operation *owner = result.getOwner(); 754 if (owner->getNumResults() == 1) 755 return; 756 int resultNo = result.getResultNumber(); 757 758 // If this operation has multiple result groups, we will need to find the 759 // one corresponding to this result. 760 auto resultGroupIt = opResultGroups.find(owner); 761 if (resultGroupIt == opResultGroups.end()) { 762 // If not, just use the first result. 763 lookupResultNo = resultNo; 764 lookupValue = owner->getResult(0); 765 return; 766 } 767 768 // Find the correct index using a binary search, as the groups are ordered. 769 ArrayRef<int> resultGroups = resultGroupIt->second; 770 auto it = llvm::upper_bound(resultGroups, resultNo); 771 int groupResultNo = 0, groupSize = 0; 772 773 // If there are no smaller elements, the last result group is the lookup. 774 if (it == resultGroups.end()) { 775 groupResultNo = resultGroups.back(); 776 groupSize = static_cast<int>(owner->getNumResults()) - resultGroups.back(); 777 } else { 778 // Otherwise, the previous element is the lookup. 779 groupResultNo = *std::prev(it); 780 groupSize = *it - groupResultNo; 781 } 782 783 // We only record the result number for a group of size greater than 1. 784 if (groupSize != 1) 785 lookupResultNo = resultNo - groupResultNo; 786 lookupValue = owner->getResult(groupResultNo); 787 } 788 789 void SSANameState::setValueName(Value value, StringRef name) { 790 // If the name is empty, the value uses the default numbering. 791 if (name.empty()) { 792 valueIDs[value] = nextValueID++; 793 return; 794 } 795 796 valueIDs[value] = NameSentinel; 797 valueNames[value] = uniqueValueName(name); 798 } 799 800 /// Returns true if 'c' is an allowable punctuation character: [$._-] 801 /// Returns false otherwise. 802 static bool isPunct(char c) { 803 return c == '$' || c == '.' || c == '_' || c == '-'; 804 } 805 806 StringRef SSANameState::uniqueValueName(StringRef name) { 807 assert(!name.empty() && "Shouldn't have an empty name here"); 808 809 // Check to see if this name is valid. If it starts with a digit, then it 810 // could conflict with the autogenerated numeric ID's (we unique them in a 811 // different map), so add an underscore prefix to avoid problems. 812 if (isdigit(name[0])) { 813 SmallString<16> tmpName("_"); 814 tmpName += name; 815 return uniqueValueName(tmpName); 816 } 817 818 // Check to see if the name consists of all-valid identifiers. If not, we 819 // need to escape them. 820 for (char ch : name) { 821 if (isalpha(ch) || isPunct(ch) || isdigit(ch)) 822 continue; 823 824 SmallString<16> tmpName; 825 for (char ch : name) { 826 if (isalpha(ch) || isPunct(ch) || isdigit(ch)) 827 tmpName += ch; 828 else if (ch == ' ') 829 tmpName += '_'; 830 else { 831 tmpName += llvm::utohexstr((unsigned char)ch); 832 } 833 } 834 return uniqueValueName(tmpName); 835 } 836 837 // Check to see if this name is already unique. 838 if (!usedNames.count(name)) { 839 name = name.copy(usedNameAllocator); 840 } else { 841 // Otherwise, we had a conflict - probe until we find a unique name. This 842 // is guaranteed to terminate (and usually in a single iteration) because it 843 // generates new names by incrementing nextConflictID. 844 SmallString<64> probeName(name); 845 probeName.push_back('_'); 846 while (true) { 847 probeName.resize(name.size() + 1); 848 probeName += llvm::utostr(nextConflictID++); 849 if (!usedNames.count(probeName)) { 850 name = StringRef(probeName).copy(usedNameAllocator); 851 break; 852 } 853 } 854 } 855 856 usedNames.insert(name, char()); 857 return name; 858 } 859 860 //===----------------------------------------------------------------------===// 861 // AsmState 862 //===----------------------------------------------------------------------===// 863 864 namespace mlir { 865 namespace detail { 866 class AsmStateImpl { 867 public: 868 explicit AsmStateImpl(Operation *op, AsmState::LocationMap *locationMap) 869 : interfaces(op->getContext()), nameState(op, interfaces), 870 locationMap(locationMap) {} 871 872 /// Initialize the alias state to enable the printing of aliases. 873 void initializeAliases(Operation *op) { 874 aliasState.initialize(op, interfaces); 875 } 876 877 /// Get an instance of the OpAsmDialectInterface for the given dialect, or 878 /// null if one wasn't registered. 879 const OpAsmDialectInterface *getOpAsmInterface(Dialect *dialect) { 880 return interfaces.getInterfaceFor(dialect); 881 } 882 883 /// Get the state used for aliases. 884 AliasState &getAliasState() { return aliasState; } 885 886 /// Get the state used for SSA names. 887 SSANameState &getSSANameState() { return nameState; } 888 889 /// Register the location, line and column, within the buffer that the given 890 /// operation was printed at. 891 void registerOperationLocation(Operation *op, unsigned line, unsigned col) { 892 if (locationMap) 893 (*locationMap)[op] = std::make_pair(line, col); 894 } 895 896 private: 897 /// Collection of OpAsm interfaces implemented in the context. 898 DialectInterfaceCollection<OpAsmDialectInterface> interfaces; 899 900 /// The state used for attribute and type aliases. 901 AliasState aliasState; 902 903 /// The state used for SSA value names. 904 SSANameState nameState; 905 906 /// An optional location map to be populated. 907 AsmState::LocationMap *locationMap; 908 }; 909 } // end namespace detail 910 } // end namespace mlir 911 912 AsmState::AsmState(Operation *op, LocationMap *locationMap) 913 : impl(std::make_unique<AsmStateImpl>(op, locationMap)) {} 914 AsmState::~AsmState() {} 915 916 //===----------------------------------------------------------------------===// 917 // ModulePrinter 918 //===----------------------------------------------------------------------===// 919 920 namespace { 921 class ModulePrinter { 922 public: 923 ModulePrinter(raw_ostream &os, OpPrintingFlags flags = llvm::None, 924 AsmStateImpl *state = nullptr) 925 : os(os), printerFlags(flags), state(state) {} 926 explicit ModulePrinter(ModulePrinter &printer) 927 : os(printer.os), printerFlags(printer.printerFlags), 928 state(printer.state) {} 929 930 /// Returns the output stream of the printer. 931 raw_ostream &getStream() { return os; } 932 933 template <typename Container, typename UnaryFunctor> 934 inline void interleaveComma(const Container &c, UnaryFunctor each_fn) const { 935 llvm::interleaveComma(c, os, each_fn); 936 } 937 938 /// This enum describes the different kinds of elision for the type of an 939 /// attribute when printing it. 940 enum class AttrTypeElision { 941 /// The type must not be elided, 942 Never, 943 /// The type may be elided when it matches the default used in the parser 944 /// (for example i64 is the default for integer attributes). 945 May, 946 /// The type must be elided. 947 Must 948 }; 949 950 /// Print the given attribute. 951 void printAttribute(Attribute attr, 952 AttrTypeElision typeElision = AttrTypeElision::Never); 953 954 void printType(Type type); 955 void printLocation(LocationAttr loc); 956 957 void printAffineMap(AffineMap map); 958 void 959 printAffineExpr(AffineExpr expr, 960 function_ref<void(unsigned, bool)> printValueName = nullptr); 961 void printAffineConstraint(AffineExpr expr, bool isEq); 962 void printIntegerSet(IntegerSet set); 963 964 protected: 965 void printOptionalAttrDict(ArrayRef<NamedAttribute> attrs, 966 ArrayRef<StringRef> elidedAttrs = {}, 967 bool withKeyword = false); 968 void printNamedAttribute(NamedAttribute attr); 969 void printTrailingLocation(Location loc); 970 void printLocationInternal(LocationAttr loc, bool pretty = false); 971 972 /// Print a dense elements attribute. If 'allowHex' is true, a hex string is 973 /// used instead of individual elements when the elements attr is large. 974 void printDenseElementsAttr(DenseElementsAttr attr, bool allowHex); 975 976 /// Print a dense string elements attribute. 977 void printDenseStringElementsAttr(DenseStringElementsAttr attr); 978 979 /// Print a dense elements attribute. If 'allowHex' is true, a hex string is 980 /// used instead of individual elements when the elements attr is large. 981 void printDenseIntOrFPElementsAttr(DenseIntOrFPElementsAttr attr, 982 bool allowHex); 983 984 void printDialectAttribute(Attribute attr); 985 void printDialectType(Type type); 986 987 /// This enum is used to represent the binding strength of the enclosing 988 /// context that an AffineExprStorage is being printed in, so we can 989 /// intelligently produce parens. 990 enum class BindingStrength { 991 Weak, // + and - 992 Strong, // All other binary operators. 993 }; 994 void printAffineExprInternal( 995 AffineExpr expr, BindingStrength enclosingTightness, 996 function_ref<void(unsigned, bool)> printValueName = nullptr); 997 998 /// The output stream for the printer. 999 raw_ostream &os; 1000 1001 /// A set of flags to control the printer's behavior. 1002 OpPrintingFlags printerFlags; 1003 1004 /// An optional printer state for the module. 1005 AsmStateImpl *state; 1006 1007 /// A tracker for the number of new lines emitted during printing. 1008 NewLineCounter newLine; 1009 }; 1010 } // end anonymous namespace 1011 1012 void ModulePrinter::printTrailingLocation(Location loc) { 1013 // Check to see if we are printing debug information. 1014 if (!printerFlags.shouldPrintDebugInfo()) 1015 return; 1016 1017 os << " "; 1018 printLocation(loc); 1019 } 1020 1021 void ModulePrinter::printLocationInternal(LocationAttr loc, bool pretty) { 1022 switch (loc.getKind()) { 1023 case StandardAttributes::OpaqueLocation: 1024 printLocationInternal(loc.cast<OpaqueLoc>().getFallbackLocation(), pretty); 1025 break; 1026 case StandardAttributes::UnknownLocation: 1027 if (pretty) 1028 os << "[unknown]"; 1029 else 1030 os << "unknown"; 1031 break; 1032 case StandardAttributes::FileLineColLocation: { 1033 auto fileLoc = loc.cast<FileLineColLoc>(); 1034 auto mayQuote = pretty ? "" : "\""; 1035 os << mayQuote << fileLoc.getFilename() << mayQuote << ':' 1036 << fileLoc.getLine() << ':' << fileLoc.getColumn(); 1037 break; 1038 } 1039 case StandardAttributes::NameLocation: { 1040 auto nameLoc = loc.cast<NameLoc>(); 1041 os << '\"' << nameLoc.getName() << '\"'; 1042 1043 // Print the child if it isn't unknown. 1044 auto childLoc = nameLoc.getChildLoc(); 1045 if (!childLoc.isa<UnknownLoc>()) { 1046 os << '('; 1047 printLocationInternal(childLoc, pretty); 1048 os << ')'; 1049 } 1050 break; 1051 } 1052 case StandardAttributes::CallSiteLocation: { 1053 auto callLocation = loc.cast<CallSiteLoc>(); 1054 auto caller = callLocation.getCaller(); 1055 auto callee = callLocation.getCallee(); 1056 if (!pretty) 1057 os << "callsite("; 1058 printLocationInternal(callee, pretty); 1059 if (pretty) { 1060 if (callee.isa<NameLoc>()) { 1061 if (caller.isa<FileLineColLoc>()) { 1062 os << " at "; 1063 } else { 1064 os << newLine << " at "; 1065 } 1066 } else { 1067 os << newLine << " at "; 1068 } 1069 } else { 1070 os << " at "; 1071 } 1072 printLocationInternal(caller, pretty); 1073 if (!pretty) 1074 os << ")"; 1075 break; 1076 } 1077 case StandardAttributes::FusedLocation: { 1078 auto fusedLoc = loc.cast<FusedLoc>(); 1079 if (!pretty) 1080 os << "fused"; 1081 if (auto metadata = fusedLoc.getMetadata()) 1082 os << '<' << metadata << '>'; 1083 os << '['; 1084 interleave( 1085 fusedLoc.getLocations(), 1086 [&](Location loc) { printLocationInternal(loc, pretty); }, 1087 [&]() { os << ", "; }); 1088 os << ']'; 1089 break; 1090 } 1091 } 1092 } 1093 1094 /// Print a floating point value in a way that the parser will be able to 1095 /// round-trip losslessly. 1096 static void printFloatValue(const APFloat &apValue, raw_ostream &os) { 1097 // We would like to output the FP constant value in exponential notation, 1098 // but we cannot do this if doing so will lose precision. Check here to 1099 // make sure that we only output it in exponential format if we can parse 1100 // the value back and get the same value. 1101 bool isInf = apValue.isInfinity(); 1102 bool isNaN = apValue.isNaN(); 1103 if (!isInf && !isNaN) { 1104 SmallString<128> strValue; 1105 apValue.toString(strValue, /*FormatPrecision=*/6, /*FormatMaxPadding=*/0, 1106 /*TruncateZero=*/false); 1107 1108 // Check to make sure that the stringized number is not some string like 1109 // "Inf" or NaN, that atof will accept, but the lexer will not. Check 1110 // that the string matches the "[-+]?[0-9]" regex. 1111 assert(((strValue[0] >= '0' && strValue[0] <= '9') || 1112 ((strValue[0] == '-' || strValue[0] == '+') && 1113 (strValue[1] >= '0' && strValue[1] <= '9'))) && 1114 "[-+]?[0-9] regex does not match!"); 1115 1116 // Parse back the stringized version and check that the value is equal 1117 // (i.e., there is no precision loss). 1118 if (APFloat(apValue.getSemantics(), strValue).bitwiseIsEqual(apValue)) { 1119 os << strValue; 1120 return; 1121 } 1122 1123 // If it is not, use the default format of APFloat instead of the 1124 // exponential notation. 1125 strValue.clear(); 1126 apValue.toString(strValue); 1127 1128 // Make sure that we can parse the default form as a float. 1129 if (StringRef(strValue).contains('.')) { 1130 os << strValue; 1131 return; 1132 } 1133 } 1134 1135 // Print special values in hexadecimal format. The sign bit should be included 1136 // in the literal. 1137 SmallVector<char, 16> str; 1138 APInt apInt = apValue.bitcastToAPInt(); 1139 apInt.toString(str, /*Radix=*/16, /*Signed=*/false, 1140 /*formatAsCLiteral=*/true); 1141 os << str; 1142 } 1143 1144 void ModulePrinter::printLocation(LocationAttr loc) { 1145 if (printerFlags.shouldPrintDebugInfoPrettyForm()) { 1146 printLocationInternal(loc, /*pretty=*/true); 1147 } else { 1148 os << "loc("; 1149 printLocationInternal(loc); 1150 os << ')'; 1151 } 1152 } 1153 1154 /// Returns if the given dialect symbol data is simple enough to print in the 1155 /// pretty form, i.e. without the enclosing "". 1156 static bool isDialectSymbolSimpleEnoughForPrettyForm(StringRef symName) { 1157 // The name must start with an identifier. 1158 if (symName.empty() || !isalpha(symName.front())) 1159 return false; 1160 1161 // Ignore all the characters that are valid in an identifier in the symbol 1162 // name. 1163 symName = symName.drop_while( 1164 [](char c) { return llvm::isAlnum(c) || c == '.' || c == '_'; }); 1165 if (symName.empty()) 1166 return true; 1167 1168 // If we got to an unexpected character, then it must be a <>. Check those 1169 // recursively. 1170 if (symName.front() != '<' || symName.back() != '>') 1171 return false; 1172 1173 SmallVector<char, 8> nestedPunctuation; 1174 do { 1175 // If we ran out of characters, then we had a punctuation mismatch. 1176 if (symName.empty()) 1177 return false; 1178 1179 auto c = symName.front(); 1180 symName = symName.drop_front(); 1181 1182 switch (c) { 1183 // We never allow null characters. This is an EOF indicator for the lexer 1184 // which we could handle, but isn't important for any known dialect. 1185 case '\0': 1186 return false; 1187 case '<': 1188 case '[': 1189 case '(': 1190 case '{': 1191 nestedPunctuation.push_back(c); 1192 continue; 1193 case '-': 1194 // Treat `->` as a special token. 1195 if (!symName.empty() && symName.front() == '>') { 1196 symName = symName.drop_front(); 1197 continue; 1198 } 1199 break; 1200 // Reject types with mismatched brackets. 1201 case '>': 1202 if (nestedPunctuation.pop_back_val() != '<') 1203 return false; 1204 break; 1205 case ']': 1206 if (nestedPunctuation.pop_back_val() != '[') 1207 return false; 1208 break; 1209 case ')': 1210 if (nestedPunctuation.pop_back_val() != '(') 1211 return false; 1212 break; 1213 case '}': 1214 if (nestedPunctuation.pop_back_val() != '{') 1215 return false; 1216 break; 1217 default: 1218 continue; 1219 } 1220 1221 // We're done when the punctuation is fully matched. 1222 } while (!nestedPunctuation.empty()); 1223 1224 // If there were extra characters, then we failed. 1225 return symName.empty(); 1226 } 1227 1228 /// Print the given dialect symbol to the stream. 1229 static void printDialectSymbol(raw_ostream &os, StringRef symPrefix, 1230 StringRef dialectName, StringRef symString) { 1231 os << symPrefix << dialectName; 1232 1233 // If this symbol name is simple enough, print it directly in pretty form, 1234 // otherwise, we print it as an escaped string. 1235 if (isDialectSymbolSimpleEnoughForPrettyForm(symString)) { 1236 os << '.' << symString; 1237 return; 1238 } 1239 1240 // TODO: escape the symbol name, it could contain " characters. 1241 os << "<\"" << symString << "\">"; 1242 } 1243 1244 /// Returns if the given string can be represented as a bare identifier. 1245 static bool isBareIdentifier(StringRef name) { 1246 assert(!name.empty() && "invalid name"); 1247 1248 // By making this unsigned, the value passed in to isalnum will always be 1249 // in the range 0-255. This is important when building with MSVC because 1250 // its implementation will assert. This situation can arise when dealing 1251 // with UTF-8 multibyte characters. 1252 unsigned char firstChar = static_cast<unsigned char>(name[0]); 1253 if (!isalpha(firstChar) && firstChar != '_') 1254 return false; 1255 return llvm::all_of(name.drop_front(), [](unsigned char c) { 1256 return isalnum(c) || c == '_' || c == '$' || c == '.'; 1257 }); 1258 } 1259 1260 /// Print the given string as a symbol reference. A symbol reference is 1261 /// represented as a string prefixed with '@'. The reference is surrounded with 1262 /// ""'s and escaped if it has any special or non-printable characters in it. 1263 static void printSymbolReference(StringRef symbolRef, raw_ostream &os) { 1264 assert(!symbolRef.empty() && "expected valid symbol reference"); 1265 1266 // If the symbol can be represented as a bare identifier, write it directly. 1267 if (isBareIdentifier(symbolRef)) { 1268 os << '@' << symbolRef; 1269 return; 1270 } 1271 1272 // Otherwise, output the reference wrapped in quotes with proper escaping. 1273 os << "@\""; 1274 printEscapedString(symbolRef, os); 1275 os << '"'; 1276 } 1277 1278 // Print out a valid ElementsAttr that is succinct and can represent any 1279 // potential shape/type, for use when eliding a large ElementsAttr. 1280 // 1281 // We choose to use an opaque ElementsAttr literal with conspicuous content to 1282 // hopefully alert readers to the fact that this has been elided. 1283 // 1284 // Unfortunately, neither of the strings of an opaque ElementsAttr literal will 1285 // accept the string "elided". The first string must be a registered dialect 1286 // name and the latter must be a hex constant. 1287 static void printElidedElementsAttr(raw_ostream &os) { 1288 os << R"(opaque<"", "0xDEADBEEF">)"; 1289 } 1290 1291 void ModulePrinter::printAttribute(Attribute attr, 1292 AttrTypeElision typeElision) { 1293 if (!attr) { 1294 os << "<<NULL ATTRIBUTE>>"; 1295 return; 1296 } 1297 1298 // Check for an alias for this attribute. 1299 if (state) { 1300 Twine alias = state->getAliasState().getAttributeAlias(attr); 1301 if (!alias.isTriviallyEmpty()) { 1302 os << '#' << alias; 1303 return; 1304 } 1305 } 1306 1307 auto attrType = attr.getType(); 1308 switch (attr.getKind()) { 1309 default: 1310 return printDialectAttribute(attr); 1311 1312 case StandardAttributes::Opaque: { 1313 auto opaqueAttr = attr.cast<OpaqueAttr>(); 1314 printDialectSymbol(os, "#", opaqueAttr.getDialectNamespace(), 1315 opaqueAttr.getAttrData()); 1316 break; 1317 } 1318 case StandardAttributes::Unit: 1319 os << "unit"; 1320 break; 1321 case StandardAttributes::Dictionary: 1322 os << '{'; 1323 interleaveComma(attr.cast<DictionaryAttr>().getValue(), 1324 [&](NamedAttribute attr) { printNamedAttribute(attr); }); 1325 os << '}'; 1326 break; 1327 case StandardAttributes::Integer: { 1328 auto intAttr = attr.cast<IntegerAttr>(); 1329 if (attrType.isSignlessInteger(1)) { 1330 os << (intAttr.getValue().getBoolValue() ? "true" : "false"); 1331 1332 // Boolean integer attributes always elides the type. 1333 return; 1334 } 1335 1336 // Only print attributes as unsigned if they are explicitly unsigned or are 1337 // signless 1-bit values. Indexes, signed values, and multi-bit signless 1338 // values print as signed. 1339 bool isUnsigned = 1340 attrType.isUnsignedInteger() || attrType.isSignlessInteger(1); 1341 intAttr.getValue().print(os, !isUnsigned); 1342 1343 // IntegerAttr elides the type if I64. 1344 if (typeElision == AttrTypeElision::May && attrType.isSignlessInteger(64)) 1345 return; 1346 break; 1347 } 1348 case StandardAttributes::Float: { 1349 auto floatAttr = attr.cast<FloatAttr>(); 1350 printFloatValue(floatAttr.getValue(), os); 1351 1352 // FloatAttr elides the type if F64. 1353 if (typeElision == AttrTypeElision::May && attrType.isF64()) 1354 return; 1355 break; 1356 } 1357 case StandardAttributes::String: 1358 os << '"'; 1359 printEscapedString(attr.cast<StringAttr>().getValue(), os); 1360 os << '"'; 1361 break; 1362 case StandardAttributes::Array: 1363 os << '['; 1364 interleaveComma(attr.cast<ArrayAttr>().getValue(), [&](Attribute attr) { 1365 printAttribute(attr, AttrTypeElision::May); 1366 }); 1367 os << ']'; 1368 break; 1369 case StandardAttributes::AffineMap: 1370 os << "affine_map<"; 1371 attr.cast<AffineMapAttr>().getValue().print(os); 1372 os << '>'; 1373 1374 // AffineMap always elides the type. 1375 return; 1376 case StandardAttributes::IntegerSet: 1377 os << "affine_set<"; 1378 attr.cast<IntegerSetAttr>().getValue().print(os); 1379 os << '>'; 1380 1381 // IntegerSet always elides the type. 1382 return; 1383 case StandardAttributes::Type: 1384 printType(attr.cast<TypeAttr>().getValue()); 1385 break; 1386 case StandardAttributes::SymbolRef: { 1387 auto refAttr = attr.dyn_cast<SymbolRefAttr>(); 1388 printSymbolReference(refAttr.getRootReference(), os); 1389 for (FlatSymbolRefAttr nestedRef : refAttr.getNestedReferences()) { 1390 os << "::"; 1391 printSymbolReference(nestedRef.getValue(), os); 1392 } 1393 break; 1394 } 1395 case StandardAttributes::OpaqueElements: { 1396 auto eltsAttr = attr.cast<OpaqueElementsAttr>(); 1397 if (printerFlags.shouldElideElementsAttr(eltsAttr)) { 1398 printElidedElementsAttr(os); 1399 break; 1400 } 1401 os << "opaque<\"" << eltsAttr.getDialect()->getNamespace() << "\", "; 1402 os << '"' << "0x" << llvm::toHex(eltsAttr.getValue()) << "\">"; 1403 break; 1404 } 1405 case StandardAttributes::DenseIntOrFPElements: { 1406 auto eltsAttr = attr.cast<DenseIntOrFPElementsAttr>(); 1407 if (printerFlags.shouldElideElementsAttr(eltsAttr)) { 1408 printElidedElementsAttr(os); 1409 break; 1410 } 1411 os << "dense<"; 1412 printDenseIntOrFPElementsAttr(eltsAttr, /*allowHex=*/true); 1413 os << '>'; 1414 break; 1415 } 1416 case StandardAttributes::DenseStringElements: { 1417 auto eltsAttr = attr.cast<DenseStringElementsAttr>(); 1418 if (printerFlags.shouldElideElementsAttr(eltsAttr)) { 1419 printElidedElementsAttr(os); 1420 break; 1421 } 1422 os << "dense<"; 1423 printDenseStringElementsAttr(eltsAttr); 1424 os << '>'; 1425 break; 1426 } 1427 case StandardAttributes::SparseElements: { 1428 auto elementsAttr = attr.cast<SparseElementsAttr>(); 1429 if (printerFlags.shouldElideElementsAttr(elementsAttr.getIndices()) || 1430 printerFlags.shouldElideElementsAttr(elementsAttr.getValues())) { 1431 printElidedElementsAttr(os); 1432 break; 1433 } 1434 os << "sparse<"; 1435 printDenseIntOrFPElementsAttr(elementsAttr.getIndices(), 1436 /*allowHex=*/false); 1437 os << ", "; 1438 printDenseElementsAttr(elementsAttr.getValues(), /*allowHex=*/true); 1439 os << '>'; 1440 break; 1441 } 1442 1443 // Location attributes. 1444 case StandardAttributes::CallSiteLocation: 1445 case StandardAttributes::FileLineColLocation: 1446 case StandardAttributes::FusedLocation: 1447 case StandardAttributes::NameLocation: 1448 case StandardAttributes::OpaqueLocation: 1449 case StandardAttributes::UnknownLocation: 1450 printLocation(attr.cast<LocationAttr>()); 1451 break; 1452 } 1453 1454 // Don't print the type if we must elide it, or if it is a None type. 1455 if (typeElision != AttrTypeElision::Must && !attrType.isa<NoneType>()) { 1456 os << " : "; 1457 printType(attrType); 1458 } 1459 } 1460 1461 /// Print the integer element of a DenseElementsAttr. 1462 static void printDenseIntElement(const APInt &value, raw_ostream &os, 1463 bool isSigned) { 1464 if (value.getBitWidth() == 1) 1465 os << (value.getBoolValue() ? "true" : "false"); 1466 else 1467 value.print(os, isSigned); 1468 } 1469 1470 static void 1471 printDenseElementsAttrImpl(bool isSplat, ShapedType type, raw_ostream &os, 1472 function_ref<void(unsigned)> printEltFn) { 1473 // Special case for 0-d and splat tensors. 1474 if (isSplat) 1475 return printEltFn(0); 1476 1477 // Special case for degenerate tensors. 1478 auto numElements = type.getNumElements(); 1479 int64_t rank = type.getRank(); 1480 if (numElements == 0) { 1481 for (int i = 0; i < rank; ++i) 1482 os << '['; 1483 for (int i = 0; i < rank; ++i) 1484 os << ']'; 1485 return; 1486 } 1487 1488 // We use a mixed-radix counter to iterate through the shape. When we bump a 1489 // non-least-significant digit, we emit a close bracket. When we next emit an 1490 // element we re-open all closed brackets. 1491 1492 // The mixed-radix counter, with radices in 'shape'. 1493 SmallVector<unsigned, 4> counter(rank, 0); 1494 // The number of brackets that have been opened and not closed. 1495 unsigned openBrackets = 0; 1496 1497 auto shape = type.getShape(); 1498 auto bumpCounter = [&] { 1499 // Bump the least significant digit. 1500 ++counter[rank - 1]; 1501 // Iterate backwards bubbling back the increment. 1502 for (unsigned i = rank - 1; i > 0; --i) 1503 if (counter[i] >= shape[i]) { 1504 // Index 'i' is rolled over. Bump (i-1) and close a bracket. 1505 counter[i] = 0; 1506 ++counter[i - 1]; 1507 --openBrackets; 1508 os << ']'; 1509 } 1510 }; 1511 1512 for (unsigned idx = 0, e = numElements; idx != e; ++idx) { 1513 if (idx != 0) 1514 os << ", "; 1515 while (openBrackets++ < rank) 1516 os << '['; 1517 openBrackets = rank; 1518 printEltFn(idx); 1519 bumpCounter(); 1520 } 1521 while (openBrackets-- > 0) 1522 os << ']'; 1523 } 1524 1525 void ModulePrinter::printDenseElementsAttr(DenseElementsAttr attr, 1526 bool allowHex) { 1527 if (auto stringAttr = attr.dyn_cast<DenseStringElementsAttr>()) 1528 return printDenseStringElementsAttr(stringAttr); 1529 1530 printDenseIntOrFPElementsAttr(attr.cast<DenseIntOrFPElementsAttr>(), 1531 allowHex); 1532 } 1533 1534 void ModulePrinter::printDenseIntOrFPElementsAttr(DenseIntOrFPElementsAttr attr, 1535 bool allowHex) { 1536 auto type = attr.getType(); 1537 auto elementType = type.getElementType(); 1538 1539 // Check to see if we should format this attribute as a hex string. 1540 auto numElements = type.getNumElements(); 1541 if (!attr.isSplat() && allowHex && 1542 shouldPrintElementsAttrWithHex(numElements)) { 1543 ArrayRef<char> rawData = attr.getRawData(); 1544 os << '"' << "0x" << llvm::toHex(StringRef(rawData.data(), rawData.size())) 1545 << "\""; 1546 return; 1547 } 1548 1549 if (ComplexType complexTy = elementType.dyn_cast<ComplexType>()) { 1550 auto printComplexValue = [&](auto complexValues, auto printFn, 1551 raw_ostream &os, auto &&... params) { 1552 printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) { 1553 auto complexValue = *(complexValues.begin() + index); 1554 os << "("; 1555 printFn(complexValue.real(), os, params...); 1556 os << ","; 1557 printFn(complexValue.imag(), os, params...); 1558 os << ")"; 1559 }); 1560 }; 1561 1562 Type complexElementType = complexTy.getElementType(); 1563 if (complexElementType.isa<IntegerType>()) 1564 printComplexValue(attr.getComplexIntValues(), printDenseIntElement, os, 1565 /*isSigned=*/!complexElementType.isUnsignedInteger()); 1566 else 1567 printComplexValue(attr.getComplexFloatValues(), printFloatValue, os); 1568 } else if (elementType.isIntOrIndex()) { 1569 bool isSigned = !elementType.isUnsignedInteger(); 1570 auto intValues = attr.getIntValues(); 1571 printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) { 1572 printDenseIntElement(*(intValues.begin() + index), os, isSigned); 1573 }); 1574 } else { 1575 assert(elementType.isa<FloatType>() && "unexpected element type"); 1576 auto floatValues = attr.getFloatValues(); 1577 printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) { 1578 printFloatValue(*(floatValues.begin() + index), os); 1579 }); 1580 } 1581 } 1582 1583 void ModulePrinter::printDenseStringElementsAttr(DenseStringElementsAttr attr) { 1584 ArrayRef<StringRef> data = attr.getRawStringData(); 1585 auto printFn = [&](unsigned index) { 1586 os << "\""; 1587 printEscapedString(data[index], os); 1588 os << "\""; 1589 }; 1590 printDenseElementsAttrImpl(attr.isSplat(), attr.getType(), os, printFn); 1591 } 1592 1593 void ModulePrinter::printType(Type type) { 1594 if (!type) { 1595 os << "<<NULL TYPE>>"; 1596 return; 1597 } 1598 1599 // Check for an alias for this type. 1600 if (state) { 1601 StringRef alias = state->getAliasState().getTypeAlias(type); 1602 if (!alias.empty()) { 1603 os << '!' << alias; 1604 return; 1605 } 1606 } 1607 1608 switch (type.getKind()) { 1609 default: 1610 return printDialectType(type); 1611 1612 case Type::Kind::Opaque: { 1613 auto opaqueTy = type.cast<OpaqueType>(); 1614 printDialectSymbol(os, "!", opaqueTy.getDialectNamespace(), 1615 opaqueTy.getTypeData()); 1616 return; 1617 } 1618 case StandardTypes::Index: 1619 os << "index"; 1620 return; 1621 case StandardTypes::BF16: 1622 os << "bf16"; 1623 return; 1624 case StandardTypes::F16: 1625 os << "f16"; 1626 return; 1627 case StandardTypes::F32: 1628 os << "f32"; 1629 return; 1630 case StandardTypes::F64: 1631 os << "f64"; 1632 return; 1633 1634 case StandardTypes::Integer: { 1635 auto integer = type.cast<IntegerType>(); 1636 if (integer.isSigned()) 1637 os << 's'; 1638 else if (integer.isUnsigned()) 1639 os << 'u'; 1640 os << 'i' << integer.getWidth(); 1641 return; 1642 } 1643 case Type::Kind::Function: { 1644 auto func = type.cast<FunctionType>(); 1645 os << '('; 1646 interleaveComma(func.getInputs(), [&](Type type) { printType(type); }); 1647 os << ") -> "; 1648 auto results = func.getResults(); 1649 if (results.size() == 1 && !results[0].isa<FunctionType>()) 1650 os << results[0]; 1651 else { 1652 os << '('; 1653 interleaveComma(results, [&](Type type) { printType(type); }); 1654 os << ')'; 1655 } 1656 return; 1657 } 1658 case StandardTypes::Vector: { 1659 auto v = type.cast<VectorType>(); 1660 os << "vector<"; 1661 for (auto dim : v.getShape()) 1662 os << dim << 'x'; 1663 os << v.getElementType() << '>'; 1664 return; 1665 } 1666 case StandardTypes::RankedTensor: { 1667 auto v = type.cast<RankedTensorType>(); 1668 os << "tensor<"; 1669 for (auto dim : v.getShape()) { 1670 if (dim < 0) 1671 os << '?'; 1672 else 1673 os << dim; 1674 os << 'x'; 1675 } 1676 os << v.getElementType() << '>'; 1677 return; 1678 } 1679 case StandardTypes::UnrankedTensor: { 1680 auto v = type.cast<UnrankedTensorType>(); 1681 os << "tensor<*x"; 1682 printType(v.getElementType()); 1683 os << '>'; 1684 return; 1685 } 1686 case StandardTypes::MemRef: { 1687 auto v = type.cast<MemRefType>(); 1688 os << "memref<"; 1689 for (auto dim : v.getShape()) { 1690 if (dim < 0) 1691 os << '?'; 1692 else 1693 os << dim; 1694 os << 'x'; 1695 } 1696 printType(v.getElementType()); 1697 for (auto map : v.getAffineMaps()) { 1698 os << ", "; 1699 printAttribute(AffineMapAttr::get(map)); 1700 } 1701 // Only print the memory space if it is the non-default one. 1702 if (v.getMemorySpace()) 1703 os << ", " << v.getMemorySpace(); 1704 os << '>'; 1705 return; 1706 } 1707 case StandardTypes::UnrankedMemRef: { 1708 auto v = type.cast<UnrankedMemRefType>(); 1709 os << "memref<*x"; 1710 printType(v.getElementType()); 1711 os << '>'; 1712 return; 1713 } 1714 case StandardTypes::Complex: 1715 os << "complex<"; 1716 printType(type.cast<ComplexType>().getElementType()); 1717 os << '>'; 1718 return; 1719 case StandardTypes::Tuple: { 1720 auto tuple = type.cast<TupleType>(); 1721 os << "tuple<"; 1722 interleaveComma(tuple.getTypes(), [&](Type type) { printType(type); }); 1723 os << '>'; 1724 return; 1725 } 1726 case StandardTypes::None: 1727 os << "none"; 1728 return; 1729 } 1730 } 1731 1732 void ModulePrinter::printOptionalAttrDict(ArrayRef<NamedAttribute> attrs, 1733 ArrayRef<StringRef> elidedAttrs, 1734 bool withKeyword) { 1735 // If there are no attributes, then there is nothing to be done. 1736 if (attrs.empty()) 1737 return; 1738 1739 // Filter out any attributes that shouldn't be included. 1740 SmallVector<NamedAttribute, 8> filteredAttrs( 1741 llvm::make_filter_range(attrs, [&](NamedAttribute attr) { 1742 return !llvm::is_contained(elidedAttrs, attr.first.strref()); 1743 })); 1744 1745 // If there are no attributes left to print after filtering, then we're done. 1746 if (filteredAttrs.empty()) 1747 return; 1748 1749 // Print the 'attributes' keyword if necessary. 1750 if (withKeyword) 1751 os << " attributes"; 1752 1753 // Otherwise, print them all out in braces. 1754 os << " {"; 1755 interleaveComma(filteredAttrs, 1756 [&](NamedAttribute attr) { printNamedAttribute(attr); }); 1757 os << '}'; 1758 } 1759 1760 void ModulePrinter::printNamedAttribute(NamedAttribute attr) { 1761 if (isBareIdentifier(attr.first)) { 1762 os << attr.first; 1763 } else { 1764 os << '"'; 1765 printEscapedString(attr.first.strref(), os); 1766 os << '"'; 1767 } 1768 1769 // Pretty printing elides the attribute value for unit attributes. 1770 if (attr.second.isa<UnitAttr>()) 1771 return; 1772 1773 os << " = "; 1774 printAttribute(attr.second); 1775 } 1776 1777 //===----------------------------------------------------------------------===// 1778 // CustomDialectAsmPrinter 1779 //===----------------------------------------------------------------------===// 1780 1781 namespace { 1782 /// This class provides the main specialization of the DialectAsmPrinter that is 1783 /// used to provide support for print attributes and types. This hooks allows 1784 /// for dialects to hook into the main ModulePrinter. 1785 struct CustomDialectAsmPrinter : public DialectAsmPrinter { 1786 public: 1787 CustomDialectAsmPrinter(ModulePrinter &printer) : printer(printer) {} 1788 ~CustomDialectAsmPrinter() override {} 1789 1790 raw_ostream &getStream() const override { return printer.getStream(); } 1791 1792 /// Print the given attribute to the stream. 1793 void printAttribute(Attribute attr) override { printer.printAttribute(attr); } 1794 1795 /// Print the given floating point value in a stablized form. 1796 void printFloat(const APFloat &value) override { 1797 printFloatValue(value, getStream()); 1798 } 1799 1800 /// Print the given type to the stream. 1801 void printType(Type type) override { printer.printType(type); } 1802 1803 /// The main module printer. 1804 ModulePrinter &printer; 1805 }; 1806 } // end anonymous namespace 1807 1808 void ModulePrinter::printDialectAttribute(Attribute attr) { 1809 auto &dialect = attr.getDialect(); 1810 1811 // Ask the dialect to serialize the attribute to a string. 1812 std::string attrName; 1813 { 1814 llvm::raw_string_ostream attrNameStr(attrName); 1815 ModulePrinter subPrinter(attrNameStr, printerFlags, state); 1816 CustomDialectAsmPrinter printer(subPrinter); 1817 dialect.printAttribute(attr, printer); 1818 } 1819 printDialectSymbol(os, "#", dialect.getNamespace(), attrName); 1820 } 1821 1822 void ModulePrinter::printDialectType(Type type) { 1823 auto &dialect = type.getDialect(); 1824 1825 // Ask the dialect to serialize the type to a string. 1826 std::string typeName; 1827 { 1828 llvm::raw_string_ostream typeNameStr(typeName); 1829 ModulePrinter subPrinter(typeNameStr, printerFlags, state); 1830 CustomDialectAsmPrinter printer(subPrinter); 1831 dialect.printType(type, printer); 1832 } 1833 printDialectSymbol(os, "!", dialect.getNamespace(), typeName); 1834 } 1835 1836 //===----------------------------------------------------------------------===// 1837 // Affine expressions and maps 1838 //===----------------------------------------------------------------------===// 1839 1840 void ModulePrinter::printAffineExpr( 1841 AffineExpr expr, function_ref<void(unsigned, bool)> printValueName) { 1842 printAffineExprInternal(expr, BindingStrength::Weak, printValueName); 1843 } 1844 1845 void ModulePrinter::printAffineExprInternal( 1846 AffineExpr expr, BindingStrength enclosingTightness, 1847 function_ref<void(unsigned, bool)> printValueName) { 1848 const char *binopSpelling = nullptr; 1849 switch (expr.getKind()) { 1850 case AffineExprKind::SymbolId: { 1851 unsigned pos = expr.cast<AffineSymbolExpr>().getPosition(); 1852 if (printValueName) 1853 printValueName(pos, /*isSymbol=*/true); 1854 else 1855 os << 's' << pos; 1856 return; 1857 } 1858 case AffineExprKind::DimId: { 1859 unsigned pos = expr.cast<AffineDimExpr>().getPosition(); 1860 if (printValueName) 1861 printValueName(pos, /*isSymbol=*/false); 1862 else 1863 os << 'd' << pos; 1864 return; 1865 } 1866 case AffineExprKind::Constant: 1867 os << expr.cast<AffineConstantExpr>().getValue(); 1868 return; 1869 case AffineExprKind::Add: 1870 binopSpelling = " + "; 1871 break; 1872 case AffineExprKind::Mul: 1873 binopSpelling = " * "; 1874 break; 1875 case AffineExprKind::FloorDiv: 1876 binopSpelling = " floordiv "; 1877 break; 1878 case AffineExprKind::CeilDiv: 1879 binopSpelling = " ceildiv "; 1880 break; 1881 case AffineExprKind::Mod: 1882 binopSpelling = " mod "; 1883 break; 1884 } 1885 1886 auto binOp = expr.cast<AffineBinaryOpExpr>(); 1887 AffineExpr lhsExpr = binOp.getLHS(); 1888 AffineExpr rhsExpr = binOp.getRHS(); 1889 1890 // Handle tightly binding binary operators. 1891 if (binOp.getKind() != AffineExprKind::Add) { 1892 if (enclosingTightness == BindingStrength::Strong) 1893 os << '('; 1894 1895 // Pretty print multiplication with -1. 1896 auto rhsConst = rhsExpr.dyn_cast<AffineConstantExpr>(); 1897 if (rhsConst && binOp.getKind() == AffineExprKind::Mul && 1898 rhsConst.getValue() == -1) { 1899 os << "-"; 1900 printAffineExprInternal(lhsExpr, BindingStrength::Strong, printValueName); 1901 if (enclosingTightness == BindingStrength::Strong) 1902 os << ')'; 1903 return; 1904 } 1905 1906 printAffineExprInternal(lhsExpr, BindingStrength::Strong, printValueName); 1907 1908 os << binopSpelling; 1909 printAffineExprInternal(rhsExpr, BindingStrength::Strong, printValueName); 1910 1911 if (enclosingTightness == BindingStrength::Strong) 1912 os << ')'; 1913 return; 1914 } 1915 1916 // Print out special "pretty" forms for add. 1917 if (enclosingTightness == BindingStrength::Strong) 1918 os << '('; 1919 1920 // Pretty print addition to a product that has a negative operand as a 1921 // subtraction. 1922 if (auto rhs = rhsExpr.dyn_cast<AffineBinaryOpExpr>()) { 1923 if (rhs.getKind() == AffineExprKind::Mul) { 1924 AffineExpr rrhsExpr = rhs.getRHS(); 1925 if (auto rrhs = rrhsExpr.dyn_cast<AffineConstantExpr>()) { 1926 if (rrhs.getValue() == -1) { 1927 printAffineExprInternal(lhsExpr, BindingStrength::Weak, 1928 printValueName); 1929 os << " - "; 1930 if (rhs.getLHS().getKind() == AffineExprKind::Add) { 1931 printAffineExprInternal(rhs.getLHS(), BindingStrength::Strong, 1932 printValueName); 1933 } else { 1934 printAffineExprInternal(rhs.getLHS(), BindingStrength::Weak, 1935 printValueName); 1936 } 1937 1938 if (enclosingTightness == BindingStrength::Strong) 1939 os << ')'; 1940 return; 1941 } 1942 1943 if (rrhs.getValue() < -1) { 1944 printAffineExprInternal(lhsExpr, BindingStrength::Weak, 1945 printValueName); 1946 os << " - "; 1947 printAffineExprInternal(rhs.getLHS(), BindingStrength::Strong, 1948 printValueName); 1949 os << " * " << -rrhs.getValue(); 1950 if (enclosingTightness == BindingStrength::Strong) 1951 os << ')'; 1952 return; 1953 } 1954 } 1955 } 1956 } 1957 1958 // Pretty print addition to a negative number as a subtraction. 1959 if (auto rhsConst = rhsExpr.dyn_cast<AffineConstantExpr>()) { 1960 if (rhsConst.getValue() < 0) { 1961 printAffineExprInternal(lhsExpr, BindingStrength::Weak, printValueName); 1962 os << " - " << -rhsConst.getValue(); 1963 if (enclosingTightness == BindingStrength::Strong) 1964 os << ')'; 1965 return; 1966 } 1967 } 1968 1969 printAffineExprInternal(lhsExpr, BindingStrength::Weak, printValueName); 1970 1971 os << " + "; 1972 printAffineExprInternal(rhsExpr, BindingStrength::Weak, printValueName); 1973 1974 if (enclosingTightness == BindingStrength::Strong) 1975 os << ')'; 1976 } 1977 1978 void ModulePrinter::printAffineConstraint(AffineExpr expr, bool isEq) { 1979 printAffineExprInternal(expr, BindingStrength::Weak); 1980 isEq ? os << " == 0" : os << " >= 0"; 1981 } 1982 1983 void ModulePrinter::printAffineMap(AffineMap map) { 1984 // Dimension identifiers. 1985 os << '('; 1986 for (int i = 0; i < (int)map.getNumDims() - 1; ++i) 1987 os << 'd' << i << ", "; 1988 if (map.getNumDims() >= 1) 1989 os << 'd' << map.getNumDims() - 1; 1990 os << ')'; 1991 1992 // Symbolic identifiers. 1993 if (map.getNumSymbols() != 0) { 1994 os << '['; 1995 for (unsigned i = 0; i < map.getNumSymbols() - 1; ++i) 1996 os << 's' << i << ", "; 1997 if (map.getNumSymbols() >= 1) 1998 os << 's' << map.getNumSymbols() - 1; 1999 os << ']'; 2000 } 2001 2002 // Result affine expressions. 2003 os << " -> ("; 2004 interleaveComma(map.getResults(), 2005 [&](AffineExpr expr) { printAffineExpr(expr); }); 2006 os << ')'; 2007 } 2008 2009 void ModulePrinter::printIntegerSet(IntegerSet set) { 2010 // Dimension identifiers. 2011 os << '('; 2012 for (unsigned i = 1; i < set.getNumDims(); ++i) 2013 os << 'd' << i - 1 << ", "; 2014 if (set.getNumDims() >= 1) 2015 os << 'd' << set.getNumDims() - 1; 2016 os << ')'; 2017 2018 // Symbolic identifiers. 2019 if (set.getNumSymbols() != 0) { 2020 os << '['; 2021 for (unsigned i = 0; i < set.getNumSymbols() - 1; ++i) 2022 os << 's' << i << ", "; 2023 if (set.getNumSymbols() >= 1) 2024 os << 's' << set.getNumSymbols() - 1; 2025 os << ']'; 2026 } 2027 2028 // Print constraints. 2029 os << " : ("; 2030 int numConstraints = set.getNumConstraints(); 2031 for (int i = 1; i < numConstraints; ++i) { 2032 printAffineConstraint(set.getConstraint(i - 1), set.isEq(i - 1)); 2033 os << ", "; 2034 } 2035 if (numConstraints >= 1) 2036 printAffineConstraint(set.getConstraint(numConstraints - 1), 2037 set.isEq(numConstraints - 1)); 2038 os << ')'; 2039 } 2040 2041 //===----------------------------------------------------------------------===// 2042 // OperationPrinter 2043 //===----------------------------------------------------------------------===// 2044 2045 namespace { 2046 /// This class contains the logic for printing operations, regions, and blocks. 2047 class OperationPrinter : public ModulePrinter, private OpAsmPrinter { 2048 public: 2049 explicit OperationPrinter(raw_ostream &os, OpPrintingFlags flags, 2050 AsmStateImpl &state) 2051 : ModulePrinter(os, flags, &state) {} 2052 2053 /// Print the given top-level module. 2054 void print(ModuleOp op); 2055 /// Print the given operation with its indent and location. 2056 void print(Operation *op); 2057 /// Print the bare location, not including indentation/location/etc. 2058 void printOperation(Operation *op); 2059 /// Print the given operation in the generic form. 2060 void printGenericOp(Operation *op) override; 2061 2062 /// Print the name of the given block. 2063 void printBlockName(Block *block); 2064 2065 /// Print the given block. If 'printBlockArgs' is false, the arguments of the 2066 /// block are not printed. If 'printBlockTerminator' is false, the terminator 2067 /// operation of the block is not printed. 2068 void print(Block *block, bool printBlockArgs = true, 2069 bool printBlockTerminator = true); 2070 2071 /// Print the ID of the given value, optionally with its result number. 2072 void printValueID(Value value, bool printResultNo = true, 2073 raw_ostream *streamOverride = nullptr) const; 2074 2075 //===--------------------------------------------------------------------===// 2076 // OpAsmPrinter methods 2077 //===--------------------------------------------------------------------===// 2078 2079 /// Return the current stream of the printer. 2080 raw_ostream &getStream() const override { return os; } 2081 2082 /// Print the given type. 2083 void printType(Type type) override { ModulePrinter::printType(type); } 2084 2085 /// Print the given attribute. 2086 void printAttribute(Attribute attr) override { 2087 ModulePrinter::printAttribute(attr); 2088 } 2089 2090 /// Print the given attribute without its type. The corresponding parser must 2091 /// provide a valid type for the attribute. 2092 void printAttributeWithoutType(Attribute attr) override { 2093 ModulePrinter::printAttribute(attr, AttrTypeElision::Must); 2094 } 2095 2096 /// Print the ID for the given value. 2097 void printOperand(Value value) override { printValueID(value); } 2098 void printOperand(Value value, raw_ostream &os) override { 2099 printValueID(value, /*printResultNo=*/true, &os); 2100 } 2101 2102 /// Print an optional attribute dictionary with a given set of elided values. 2103 void printOptionalAttrDict(ArrayRef<NamedAttribute> attrs, 2104 ArrayRef<StringRef> elidedAttrs = {}) override { 2105 ModulePrinter::printOptionalAttrDict(attrs, elidedAttrs); 2106 } 2107 void printOptionalAttrDictWithKeyword( 2108 ArrayRef<NamedAttribute> attrs, 2109 ArrayRef<StringRef> elidedAttrs = {}) override { 2110 ModulePrinter::printOptionalAttrDict(attrs, elidedAttrs, 2111 /*withKeyword=*/true); 2112 } 2113 2114 /// Print the given successor. 2115 void printSuccessor(Block *successor) override; 2116 2117 /// Print an operation successor with the operands used for the block 2118 /// arguments. 2119 void printSuccessorAndUseList(Block *successor, 2120 ValueRange succOperands) override; 2121 2122 /// Print the given region. 2123 void printRegion(Region ®ion, bool printEntryBlockArgs, 2124 bool printBlockTerminators) override; 2125 2126 /// Renumber the arguments for the specified region to the same names as the 2127 /// SSA values in namesToUse. This may only be used for IsolatedFromAbove 2128 /// operations. If any entry in namesToUse is null, the corresponding 2129 /// argument name is left alone. 2130 void shadowRegionArgs(Region ®ion, ValueRange namesToUse) override { 2131 state->getSSANameState().shadowRegionArgs(region, namesToUse); 2132 } 2133 2134 /// Print the given affine map with the symbol and dimension operands printed 2135 /// inline with the map. 2136 void printAffineMapOfSSAIds(AffineMapAttr mapAttr, 2137 ValueRange operands) override; 2138 2139 /// Print the given string as a symbol reference. 2140 void printSymbolName(StringRef symbolRef) override { 2141 ::printSymbolReference(symbolRef, os); 2142 } 2143 2144 private: 2145 /// The number of spaces used for indenting nested operations. 2146 const static unsigned indentWidth = 2; 2147 2148 // This is the current indentation level for nested structures. 2149 unsigned currentIndent = 0; 2150 }; 2151 } // end anonymous namespace 2152 2153 void OperationPrinter::print(ModuleOp op) { 2154 // Output the aliases at the top level. 2155 state->getAliasState().printAttributeAliases(os, newLine); 2156 state->getAliasState().printTypeAliases(os, newLine); 2157 2158 // Print the module. 2159 print(op.getOperation()); 2160 } 2161 2162 void OperationPrinter::print(Operation *op) { 2163 // Track the location of this operation. 2164 state->registerOperationLocation(op, newLine.curLine, currentIndent); 2165 2166 os.indent(currentIndent); 2167 printOperation(op); 2168 printTrailingLocation(op->getLoc()); 2169 } 2170 2171 void OperationPrinter::printOperation(Operation *op) { 2172 if (size_t numResults = op->getNumResults()) { 2173 auto printResultGroup = [&](size_t resultNo, size_t resultCount) { 2174 printValueID(op->getResult(resultNo), /*printResultNo=*/false); 2175 if (resultCount > 1) 2176 os << ':' << resultCount; 2177 }; 2178 2179 // Check to see if this operation has multiple result groups. 2180 ArrayRef<int> resultGroups = state->getSSANameState().getOpResultGroups(op); 2181 if (!resultGroups.empty()) { 2182 // Interleave the groups excluding the last one, this one will be handled 2183 // separately. 2184 interleaveComma(llvm::seq<int>(0, resultGroups.size() - 1), [&](int i) { 2185 printResultGroup(resultGroups[i], 2186 resultGroups[i + 1] - resultGroups[i]); 2187 }); 2188 os << ", "; 2189 printResultGroup(resultGroups.back(), numResults - resultGroups.back()); 2190 2191 } else { 2192 printResultGroup(/*resultNo=*/0, /*resultCount=*/numResults); 2193 } 2194 2195 os << " = "; 2196 } 2197 2198 // If requested, always print the generic form. 2199 if (!printerFlags.shouldPrintGenericOpForm()) { 2200 // Check to see if this is a known operation. If so, use the registered 2201 // custom printer hook. 2202 if (auto *opInfo = op->getAbstractOperation()) { 2203 opInfo->printAssembly(op, *this); 2204 return; 2205 } 2206 } 2207 2208 // Otherwise print with the generic assembly form. 2209 printGenericOp(op); 2210 } 2211 2212 void OperationPrinter::printGenericOp(Operation *op) { 2213 os << '"'; 2214 printEscapedString(op->getName().getStringRef(), os); 2215 os << "\"("; 2216 interleaveComma(op->getOperands(), [&](Value value) { printValueID(value); }); 2217 os << ')'; 2218 2219 // For terminators, print the list of successors and their operands. 2220 if (op->getNumSuccessors() != 0) { 2221 os << '['; 2222 interleaveComma(op->getSuccessors(), 2223 [&](Block *successor) { printBlockName(successor); }); 2224 os << ']'; 2225 } 2226 2227 // Print regions. 2228 if (op->getNumRegions() != 0) { 2229 os << " ("; 2230 interleaveComma(op->getRegions(), [&](Region ®ion) { 2231 printRegion(region, /*printEntryBlockArgs=*/true, 2232 /*printBlockTerminators=*/true); 2233 }); 2234 os << ')'; 2235 } 2236 2237 auto attrs = op->getAttrs(); 2238 printOptionalAttrDict(attrs); 2239 2240 // Print the type signature of the operation. 2241 os << " : "; 2242 printFunctionalType(op); 2243 } 2244 2245 void OperationPrinter::printBlockName(Block *block) { 2246 auto id = state->getSSANameState().getBlockID(block); 2247 if (id != SSANameState::NameSentinel) 2248 os << "^bb" << id; 2249 else 2250 os << "^INVALIDBLOCK"; 2251 } 2252 2253 void OperationPrinter::print(Block *block, bool printBlockArgs, 2254 bool printBlockTerminator) { 2255 // Print the block label and argument list if requested. 2256 if (printBlockArgs) { 2257 os.indent(currentIndent); 2258 printBlockName(block); 2259 2260 // Print the argument list if non-empty. 2261 if (!block->args_empty()) { 2262 os << '('; 2263 interleaveComma(block->getArguments(), [&](BlockArgument arg) { 2264 printValueID(arg); 2265 os << ": "; 2266 printType(arg.getType()); 2267 }); 2268 os << ')'; 2269 } 2270 os << ':'; 2271 2272 // Print out some context information about the predecessors of this block. 2273 if (!block->getParent()) { 2274 os << " // block is not in a region!"; 2275 } else if (block->hasNoPredecessors()) { 2276 os << " // no predecessors"; 2277 } else if (auto *pred = block->getSinglePredecessor()) { 2278 os << " // pred: "; 2279 printBlockName(pred); 2280 } else { 2281 // We want to print the predecessors in increasing numeric order, not in 2282 // whatever order the use-list is in, so gather and sort them. 2283 SmallVector<std::pair<unsigned, Block *>, 4> predIDs; 2284 for (auto *pred : block->getPredecessors()) 2285 predIDs.push_back({state->getSSANameState().getBlockID(pred), pred}); 2286 llvm::array_pod_sort(predIDs.begin(), predIDs.end()); 2287 2288 os << " // " << predIDs.size() << " preds: "; 2289 2290 interleaveComma(predIDs, [&](std::pair<unsigned, Block *> pred) { 2291 printBlockName(pred.second); 2292 }); 2293 } 2294 os << newLine; 2295 } 2296 2297 currentIndent += indentWidth; 2298 auto range = llvm::make_range( 2299 block->getOperations().begin(), 2300 std::prev(block->getOperations().end(), printBlockTerminator ? 0 : 1)); 2301 for (auto &op : range) { 2302 print(&op); 2303 os << newLine; 2304 } 2305 currentIndent -= indentWidth; 2306 } 2307 2308 void OperationPrinter::printValueID(Value value, bool printResultNo, 2309 raw_ostream *streamOverride) const { 2310 state->getSSANameState().printValueID(value, printResultNo, 2311 streamOverride ? *streamOverride : os); 2312 } 2313 2314 void OperationPrinter::printSuccessor(Block *successor) { 2315 printBlockName(successor); 2316 } 2317 2318 void OperationPrinter::printSuccessorAndUseList(Block *successor, 2319 ValueRange succOperands) { 2320 printBlockName(successor); 2321 if (succOperands.empty()) 2322 return; 2323 2324 os << '('; 2325 interleaveComma(succOperands, 2326 [this](Value operand) { printValueID(operand); }); 2327 os << " : "; 2328 interleaveComma(succOperands, 2329 [this](Value operand) { printType(operand.getType()); }); 2330 os << ')'; 2331 } 2332 2333 void OperationPrinter::printRegion(Region ®ion, bool printEntryBlockArgs, 2334 bool printBlockTerminators) { 2335 os << " {" << newLine; 2336 if (!region.empty()) { 2337 auto *entryBlock = ®ion.front(); 2338 print(entryBlock, printEntryBlockArgs && entryBlock->getNumArguments() != 0, 2339 printBlockTerminators); 2340 for (auto &b : llvm::drop_begin(region.getBlocks(), 1)) 2341 print(&b); 2342 } 2343 os.indent(currentIndent) << "}"; 2344 } 2345 2346 void OperationPrinter::printAffineMapOfSSAIds(AffineMapAttr mapAttr, 2347 ValueRange operands) { 2348 AffineMap map = mapAttr.getValue(); 2349 unsigned numDims = map.getNumDims(); 2350 auto printValueName = [&](unsigned pos, bool isSymbol) { 2351 unsigned index = isSymbol ? numDims + pos : pos; 2352 assert(index < operands.size()); 2353 if (isSymbol) 2354 os << "symbol("; 2355 printValueID(operands[index]); 2356 if (isSymbol) 2357 os << ')'; 2358 }; 2359 2360 interleaveComma(map.getResults(), [&](AffineExpr expr) { 2361 printAffineExpr(expr, printValueName); 2362 }); 2363 } 2364 2365 //===----------------------------------------------------------------------===// 2366 // print and dump methods 2367 //===----------------------------------------------------------------------===// 2368 2369 void Attribute::print(raw_ostream &os) const { 2370 ModulePrinter(os).printAttribute(*this); 2371 } 2372 2373 void Attribute::dump() const { 2374 print(llvm::errs()); 2375 llvm::errs() << "\n"; 2376 } 2377 2378 void Type::print(raw_ostream &os) { ModulePrinter(os).printType(*this); } 2379 2380 void Type::dump() { print(llvm::errs()); } 2381 2382 void AffineMap::dump() const { 2383 print(llvm::errs()); 2384 llvm::errs() << "\n"; 2385 } 2386 2387 void IntegerSet::dump() const { 2388 print(llvm::errs()); 2389 llvm::errs() << "\n"; 2390 } 2391 2392 void AffineExpr::print(raw_ostream &os) const { 2393 if (!expr) { 2394 os << "<<NULL AFFINE EXPR>>"; 2395 return; 2396 } 2397 ModulePrinter(os).printAffineExpr(*this); 2398 } 2399 2400 void AffineExpr::dump() const { 2401 print(llvm::errs()); 2402 llvm::errs() << "\n"; 2403 } 2404 2405 void AffineMap::print(raw_ostream &os) const { 2406 if (!map) { 2407 os << "<<NULL AFFINE MAP>>"; 2408 return; 2409 } 2410 ModulePrinter(os).printAffineMap(*this); 2411 } 2412 2413 void IntegerSet::print(raw_ostream &os) const { 2414 ModulePrinter(os).printIntegerSet(*this); 2415 } 2416 2417 void Value::print(raw_ostream &os) { 2418 if (auto *op = getDefiningOp()) 2419 return op->print(os); 2420 // TODO: Improve this. 2421 assert(isa<BlockArgument>()); 2422 os << "<block argument>\n"; 2423 } 2424 void Value::print(raw_ostream &os, AsmState &state) { 2425 if (auto *op = getDefiningOp()) 2426 return op->print(os, state); 2427 2428 // TODO: Improve this. 2429 assert(isa<BlockArgument>()); 2430 os << "<block argument>\n"; 2431 } 2432 2433 void Value::dump() { 2434 print(llvm::errs()); 2435 llvm::errs() << "\n"; 2436 } 2437 2438 void Value::printAsOperand(raw_ostream &os, AsmState &state) { 2439 // TODO(riverriddle) This doesn't necessarily capture all potential cases. 2440 // Currently, region arguments can be shadowed when printing the main 2441 // operation. If the IR hasn't been printed, this will produce the old SSA 2442 // name and not the shadowed name. 2443 state.getImpl().getSSANameState().printValueID(*this, /*printResultNo=*/true, 2444 os); 2445 } 2446 2447 void Operation::print(raw_ostream &os, OpPrintingFlags flags) { 2448 // Find the operation to number from based upon the provided flags. 2449 Operation *printedOp = this; 2450 bool shouldUseLocalScope = flags.shouldUseLocalScope(); 2451 do { 2452 // If we are printing local scope, stop at the first operation that is 2453 // isolated from above. 2454 if (shouldUseLocalScope && printedOp->isKnownIsolatedFromAbove()) 2455 break; 2456 2457 // Otherwise, traverse up to the next parent. 2458 Operation *parentOp = printedOp->getParentOp(); 2459 if (!parentOp) 2460 break; 2461 printedOp = parentOp; 2462 } while (true); 2463 2464 AsmState state(printedOp); 2465 print(os, state, flags); 2466 } 2467 void Operation::print(raw_ostream &os, AsmState &state, OpPrintingFlags flags) { 2468 OperationPrinter(os, flags, state.getImpl()).print(this); 2469 } 2470 2471 void Operation::dump() { 2472 print(llvm::errs(), OpPrintingFlags().useLocalScope()); 2473 llvm::errs() << "\n"; 2474 } 2475 2476 void Block::print(raw_ostream &os) { 2477 Operation *parentOp = getParentOp(); 2478 if (!parentOp) { 2479 os << "<<UNLINKED BLOCK>>\n"; 2480 return; 2481 } 2482 // Get the top-level op. 2483 while (auto *nextOp = parentOp->getParentOp()) 2484 parentOp = nextOp; 2485 2486 AsmState state(parentOp); 2487 print(os, state); 2488 } 2489 void Block::print(raw_ostream &os, AsmState &state) { 2490 OperationPrinter(os, /*flags=*/llvm::None, state.getImpl()).print(this); 2491 } 2492 2493 void Block::dump() { print(llvm::errs()); } 2494 2495 /// Print out the name of the block without printing its body. 2496 void Block::printAsOperand(raw_ostream &os, bool printType) { 2497 Operation *parentOp = getParentOp(); 2498 if (!parentOp) { 2499 os << "<<UNLINKED BLOCK>>\n"; 2500 return; 2501 } 2502 AsmState state(parentOp); 2503 printAsOperand(os, state); 2504 } 2505 void Block::printAsOperand(raw_ostream &os, AsmState &state) { 2506 OperationPrinter printer(os, /*flags=*/llvm::None, state.getImpl()); 2507 printer.printBlockName(this); 2508 } 2509 2510 void ModuleOp::print(raw_ostream &os, OpPrintingFlags flags) { 2511 AsmState state(*this); 2512 2513 // Don't populate aliases when printing at local scope. 2514 if (!flags.shouldUseLocalScope()) 2515 state.getImpl().initializeAliases(*this); 2516 print(os, state, flags); 2517 } 2518 void ModuleOp::print(raw_ostream &os, AsmState &state, OpPrintingFlags flags) { 2519 OperationPrinter(os, flags, state.getImpl()).print(*this); 2520 } 2521 2522 void ModuleOp::dump() { print(llvm::errs()); } 2523