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: 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.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.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 DenseIntElementsAttr indices = elementsAttr.getIndices(); 1436 if (indices.getNumElements() != 0) { 1437 printDenseIntOrFPElementsAttr(indices, /*allowHex=*/false); 1438 os << ", "; 1439 printDenseElementsAttr(elementsAttr.getValues(), /*allowHex=*/true); 1440 } 1441 os << '>'; 1442 break; 1443 } 1444 1445 // Location attributes. 1446 case StandardAttributes::CallSiteLocation: 1447 case StandardAttributes::FileLineColLocation: 1448 case StandardAttributes::FusedLocation: 1449 case StandardAttributes::NameLocation: 1450 case StandardAttributes::OpaqueLocation: 1451 case StandardAttributes::UnknownLocation: 1452 printLocation(attr.cast<LocationAttr>()); 1453 break; 1454 } 1455 1456 // Don't print the type if we must elide it, or if it is a None type. 1457 if (typeElision != AttrTypeElision::Must && !attrType.isa<NoneType>()) { 1458 os << " : "; 1459 printType(attrType); 1460 } 1461 } 1462 1463 /// Print the integer element of a DenseElementsAttr. 1464 static void printDenseIntElement(const APInt &value, raw_ostream &os, 1465 bool isSigned) { 1466 if (value.getBitWidth() == 1) 1467 os << (value.getBoolValue() ? "true" : "false"); 1468 else 1469 value.print(os, isSigned); 1470 } 1471 1472 static void 1473 printDenseElementsAttrImpl(bool isSplat, ShapedType type, raw_ostream &os, 1474 function_ref<void(unsigned)> printEltFn) { 1475 // Special case for 0-d and splat tensors. 1476 if (isSplat) 1477 return printEltFn(0); 1478 1479 // Special case for degenerate tensors. 1480 auto numElements = type.getNumElements(); 1481 if (numElements == 0) 1482 return; 1483 1484 // We use a mixed-radix counter to iterate through the shape. When we bump a 1485 // non-least-significant digit, we emit a close bracket. When we next emit an 1486 // element we re-open all closed brackets. 1487 1488 // The mixed-radix counter, with radices in 'shape'. 1489 int64_t rank = type.getRank(); 1490 SmallVector<unsigned, 4> counter(rank, 0); 1491 // The number of brackets that have been opened and not closed. 1492 unsigned openBrackets = 0; 1493 1494 auto shape = type.getShape(); 1495 auto bumpCounter = [&] { 1496 // Bump the least significant digit. 1497 ++counter[rank - 1]; 1498 // Iterate backwards bubbling back the increment. 1499 for (unsigned i = rank - 1; i > 0; --i) 1500 if (counter[i] >= shape[i]) { 1501 // Index 'i' is rolled over. Bump (i-1) and close a bracket. 1502 counter[i] = 0; 1503 ++counter[i - 1]; 1504 --openBrackets; 1505 os << ']'; 1506 } 1507 }; 1508 1509 for (unsigned idx = 0, e = numElements; idx != e; ++idx) { 1510 if (idx != 0) 1511 os << ", "; 1512 while (openBrackets++ < rank) 1513 os << '['; 1514 openBrackets = rank; 1515 printEltFn(idx); 1516 bumpCounter(); 1517 } 1518 while (openBrackets-- > 0) 1519 os << ']'; 1520 } 1521 1522 void ModulePrinter::printDenseElementsAttr(DenseElementsAttr attr, 1523 bool allowHex) { 1524 if (auto stringAttr = attr.dyn_cast<DenseStringElementsAttr>()) 1525 return printDenseStringElementsAttr(stringAttr); 1526 1527 printDenseIntOrFPElementsAttr(attr.cast<DenseIntOrFPElementsAttr>(), 1528 allowHex); 1529 } 1530 1531 void ModulePrinter::printDenseIntOrFPElementsAttr(DenseIntOrFPElementsAttr attr, 1532 bool allowHex) { 1533 auto type = attr.getType(); 1534 auto elementType = type.getElementType(); 1535 1536 // Check to see if we should format this attribute as a hex string. 1537 auto numElements = type.getNumElements(); 1538 if (!attr.isSplat() && allowHex && 1539 shouldPrintElementsAttrWithHex(numElements)) { 1540 ArrayRef<char> rawData = attr.getRawData(); 1541 os << '"' << "0x" << llvm::toHex(StringRef(rawData.data(), rawData.size())) 1542 << "\""; 1543 return; 1544 } 1545 1546 if (ComplexType complexTy = elementType.dyn_cast<ComplexType>()) { 1547 Type complexElementType = complexTy.getElementType(); 1548 // Note: The if and else below had a common lambda function which invoked 1549 // printDenseElementsAttrImpl. This lambda was hitting a bug in gcc 9.1,9.2 1550 // and hence was replaced. 1551 if (complexElementType.isa<IntegerType>()) { 1552 bool isSigned = !complexElementType.isUnsignedInteger(); 1553 printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) { 1554 auto complexValue = *(attr.getComplexIntValues().begin() + index); 1555 os << "("; 1556 printDenseIntElement(complexValue.real(), os, isSigned); 1557 os << ","; 1558 printDenseIntElement(complexValue.imag(), os, isSigned); 1559 os << ")"; 1560 }); 1561 } else { 1562 printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) { 1563 auto complexValue = *(attr.getComplexFloatValues().begin() + index); 1564 os << "("; 1565 printFloatValue(complexValue.real(), os); 1566 os << ","; 1567 printFloatValue(complexValue.imag(), os); 1568 os << ")"; 1569 }); 1570 } 1571 } else if (elementType.isIntOrIndex()) { 1572 bool isSigned = !elementType.isUnsignedInteger(); 1573 auto intValues = attr.getIntValues(); 1574 printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) { 1575 printDenseIntElement(*(intValues.begin() + index), os, isSigned); 1576 }); 1577 } else { 1578 assert(elementType.isa<FloatType>() && "unexpected element type"); 1579 auto floatValues = attr.getFloatValues(); 1580 printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) { 1581 printFloatValue(*(floatValues.begin() + index), os); 1582 }); 1583 } 1584 } 1585 1586 void ModulePrinter::printDenseStringElementsAttr(DenseStringElementsAttr attr) { 1587 ArrayRef<StringRef> data = attr.getRawStringData(); 1588 auto printFn = [&](unsigned index) { 1589 os << "\""; 1590 printEscapedString(data[index], os); 1591 os << "\""; 1592 }; 1593 printDenseElementsAttrImpl(attr.isSplat(), attr.getType(), os, printFn); 1594 } 1595 1596 void ModulePrinter::printType(Type type) { 1597 if (!type) { 1598 os << "<<NULL TYPE>>"; 1599 return; 1600 } 1601 1602 // Check for an alias for this type. 1603 if (state) { 1604 StringRef alias = state->getAliasState().getTypeAlias(type); 1605 if (!alias.empty()) { 1606 os << '!' << alias; 1607 return; 1608 } 1609 } 1610 1611 switch (type.getKind()) { 1612 default: 1613 return printDialectType(type); 1614 1615 case Type::Kind::Opaque: { 1616 auto opaqueTy = type.cast<OpaqueType>(); 1617 printDialectSymbol(os, "!", opaqueTy.getDialectNamespace(), 1618 opaqueTy.getTypeData()); 1619 return; 1620 } 1621 case StandardTypes::Index: 1622 os << "index"; 1623 return; 1624 case StandardTypes::BF16: 1625 os << "bf16"; 1626 return; 1627 case StandardTypes::F16: 1628 os << "f16"; 1629 return; 1630 case StandardTypes::F32: 1631 os << "f32"; 1632 return; 1633 case StandardTypes::F64: 1634 os << "f64"; 1635 return; 1636 1637 case StandardTypes::Integer: { 1638 auto integer = type.cast<IntegerType>(); 1639 if (integer.isSigned()) 1640 os << 's'; 1641 else if (integer.isUnsigned()) 1642 os << 'u'; 1643 os << 'i' << integer.getWidth(); 1644 return; 1645 } 1646 case Type::Kind::Function: { 1647 auto func = type.cast<FunctionType>(); 1648 os << '('; 1649 interleaveComma(func.getInputs(), [&](Type type) { printType(type); }); 1650 os << ") -> "; 1651 auto results = func.getResults(); 1652 if (results.size() == 1 && !results[0].isa<FunctionType>()) 1653 os << results[0]; 1654 else { 1655 os << '('; 1656 interleaveComma(results, [&](Type type) { printType(type); }); 1657 os << ')'; 1658 } 1659 return; 1660 } 1661 case StandardTypes::Vector: { 1662 auto v = type.cast<VectorType>(); 1663 os << "vector<"; 1664 for (auto dim : v.getShape()) 1665 os << dim << 'x'; 1666 os << v.getElementType() << '>'; 1667 return; 1668 } 1669 case StandardTypes::RankedTensor: { 1670 auto v = type.cast<RankedTensorType>(); 1671 os << "tensor<"; 1672 for (auto dim : v.getShape()) { 1673 if (dim < 0) 1674 os << '?'; 1675 else 1676 os << dim; 1677 os << 'x'; 1678 } 1679 os << v.getElementType() << '>'; 1680 return; 1681 } 1682 case StandardTypes::UnrankedTensor: { 1683 auto v = type.cast<UnrankedTensorType>(); 1684 os << "tensor<*x"; 1685 printType(v.getElementType()); 1686 os << '>'; 1687 return; 1688 } 1689 case StandardTypes::MemRef: { 1690 auto v = type.cast<MemRefType>(); 1691 os << "memref<"; 1692 for (auto dim : v.getShape()) { 1693 if (dim < 0) 1694 os << '?'; 1695 else 1696 os << dim; 1697 os << 'x'; 1698 } 1699 printType(v.getElementType()); 1700 for (auto map : v.getAffineMaps()) { 1701 os << ", "; 1702 printAttribute(AffineMapAttr::get(map)); 1703 } 1704 // Only print the memory space if it is the non-default one. 1705 if (v.getMemorySpace()) 1706 os << ", " << v.getMemorySpace(); 1707 os << '>'; 1708 return; 1709 } 1710 case StandardTypes::UnrankedMemRef: { 1711 auto v = type.cast<UnrankedMemRefType>(); 1712 os << "memref<*x"; 1713 printType(v.getElementType()); 1714 os << '>'; 1715 return; 1716 } 1717 case StandardTypes::Complex: 1718 os << "complex<"; 1719 printType(type.cast<ComplexType>().getElementType()); 1720 os << '>'; 1721 return; 1722 case StandardTypes::Tuple: { 1723 auto tuple = type.cast<TupleType>(); 1724 os << "tuple<"; 1725 interleaveComma(tuple.getTypes(), [&](Type type) { printType(type); }); 1726 os << '>'; 1727 return; 1728 } 1729 case StandardTypes::None: 1730 os << "none"; 1731 return; 1732 } 1733 } 1734 1735 void ModulePrinter::printOptionalAttrDict(ArrayRef<NamedAttribute> attrs, 1736 ArrayRef<StringRef> elidedAttrs, 1737 bool withKeyword) { 1738 // If there are no attributes, then there is nothing to be done. 1739 if (attrs.empty()) 1740 return; 1741 1742 // Filter out any attributes that shouldn't be included. 1743 SmallVector<NamedAttribute, 8> filteredAttrs( 1744 llvm::make_filter_range(attrs, [&](NamedAttribute attr) { 1745 return !llvm::is_contained(elidedAttrs, attr.first.strref()); 1746 })); 1747 1748 // If there are no attributes left to print after filtering, then we're done. 1749 if (filteredAttrs.empty()) 1750 return; 1751 1752 // Print the 'attributes' keyword if necessary. 1753 if (withKeyword) 1754 os << " attributes"; 1755 1756 // Otherwise, print them all out in braces. 1757 os << " {"; 1758 interleaveComma(filteredAttrs, 1759 [&](NamedAttribute attr) { printNamedAttribute(attr); }); 1760 os << '}'; 1761 } 1762 1763 void ModulePrinter::printNamedAttribute(NamedAttribute attr) { 1764 if (isBareIdentifier(attr.first)) { 1765 os << attr.first; 1766 } else { 1767 os << '"'; 1768 printEscapedString(attr.first.strref(), os); 1769 os << '"'; 1770 } 1771 1772 // Pretty printing elides the attribute value for unit attributes. 1773 if (attr.second.isa<UnitAttr>()) 1774 return; 1775 1776 os << " = "; 1777 printAttribute(attr.second); 1778 } 1779 1780 //===----------------------------------------------------------------------===// 1781 // CustomDialectAsmPrinter 1782 //===----------------------------------------------------------------------===// 1783 1784 namespace { 1785 /// This class provides the main specialization of the DialectAsmPrinter that is 1786 /// used to provide support for print attributes and types. This hooks allows 1787 /// for dialects to hook into the main ModulePrinter. 1788 struct CustomDialectAsmPrinter : public DialectAsmPrinter { 1789 public: 1790 CustomDialectAsmPrinter(ModulePrinter &printer) : printer(printer) {} 1791 ~CustomDialectAsmPrinter() override {} 1792 1793 raw_ostream &getStream() const override { return printer.getStream(); } 1794 1795 /// Print the given attribute to the stream. 1796 void printAttribute(Attribute attr) override { printer.printAttribute(attr); } 1797 1798 /// Print the given floating point value in a stablized form. 1799 void printFloat(const APFloat &value) override { 1800 printFloatValue(value, getStream()); 1801 } 1802 1803 /// Print the given type to the stream. 1804 void printType(Type type) override { printer.printType(type); } 1805 1806 /// The main module printer. 1807 ModulePrinter &printer; 1808 }; 1809 } // end anonymous namespace 1810 1811 void ModulePrinter::printDialectAttribute(Attribute attr) { 1812 auto &dialect = attr.getDialect(); 1813 1814 // Ask the dialect to serialize the attribute to a string. 1815 std::string attrName; 1816 { 1817 llvm::raw_string_ostream attrNameStr(attrName); 1818 ModulePrinter subPrinter(attrNameStr, printerFlags, state); 1819 CustomDialectAsmPrinter printer(subPrinter); 1820 dialect.printAttribute(attr, printer); 1821 } 1822 printDialectSymbol(os, "#", dialect.getNamespace(), attrName); 1823 } 1824 1825 void ModulePrinter::printDialectType(Type type) { 1826 auto &dialect = type.getDialect(); 1827 1828 // Ask the dialect to serialize the type to a string. 1829 std::string typeName; 1830 { 1831 llvm::raw_string_ostream typeNameStr(typeName); 1832 ModulePrinter subPrinter(typeNameStr, printerFlags, state); 1833 CustomDialectAsmPrinter printer(subPrinter); 1834 dialect.printType(type, printer); 1835 } 1836 printDialectSymbol(os, "!", dialect.getNamespace(), typeName); 1837 } 1838 1839 //===----------------------------------------------------------------------===// 1840 // Affine expressions and maps 1841 //===----------------------------------------------------------------------===// 1842 1843 void ModulePrinter::printAffineExpr( 1844 AffineExpr expr, function_ref<void(unsigned, bool)> printValueName) { 1845 printAffineExprInternal(expr, BindingStrength::Weak, printValueName); 1846 } 1847 1848 void ModulePrinter::printAffineExprInternal( 1849 AffineExpr expr, BindingStrength enclosingTightness, 1850 function_ref<void(unsigned, bool)> printValueName) { 1851 const char *binopSpelling = nullptr; 1852 switch (expr.getKind()) { 1853 case AffineExprKind::SymbolId: { 1854 unsigned pos = expr.cast<AffineSymbolExpr>().getPosition(); 1855 if (printValueName) 1856 printValueName(pos, /*isSymbol=*/true); 1857 else 1858 os << 's' << pos; 1859 return; 1860 } 1861 case AffineExprKind::DimId: { 1862 unsigned pos = expr.cast<AffineDimExpr>().getPosition(); 1863 if (printValueName) 1864 printValueName(pos, /*isSymbol=*/false); 1865 else 1866 os << 'd' << pos; 1867 return; 1868 } 1869 case AffineExprKind::Constant: 1870 os << expr.cast<AffineConstantExpr>().getValue(); 1871 return; 1872 case AffineExprKind::Add: 1873 binopSpelling = " + "; 1874 break; 1875 case AffineExprKind::Mul: 1876 binopSpelling = " * "; 1877 break; 1878 case AffineExprKind::FloorDiv: 1879 binopSpelling = " floordiv "; 1880 break; 1881 case AffineExprKind::CeilDiv: 1882 binopSpelling = " ceildiv "; 1883 break; 1884 case AffineExprKind::Mod: 1885 binopSpelling = " mod "; 1886 break; 1887 } 1888 1889 auto binOp = expr.cast<AffineBinaryOpExpr>(); 1890 AffineExpr lhsExpr = binOp.getLHS(); 1891 AffineExpr rhsExpr = binOp.getRHS(); 1892 1893 // Handle tightly binding binary operators. 1894 if (binOp.getKind() != AffineExprKind::Add) { 1895 if (enclosingTightness == BindingStrength::Strong) 1896 os << '('; 1897 1898 // Pretty print multiplication with -1. 1899 auto rhsConst = rhsExpr.dyn_cast<AffineConstantExpr>(); 1900 if (rhsConst && binOp.getKind() == AffineExprKind::Mul && 1901 rhsConst.getValue() == -1) { 1902 os << "-"; 1903 printAffineExprInternal(lhsExpr, BindingStrength::Strong, printValueName); 1904 if (enclosingTightness == BindingStrength::Strong) 1905 os << ')'; 1906 return; 1907 } 1908 1909 printAffineExprInternal(lhsExpr, BindingStrength::Strong, printValueName); 1910 1911 os << binopSpelling; 1912 printAffineExprInternal(rhsExpr, BindingStrength::Strong, printValueName); 1913 1914 if (enclosingTightness == BindingStrength::Strong) 1915 os << ')'; 1916 return; 1917 } 1918 1919 // Print out special "pretty" forms for add. 1920 if (enclosingTightness == BindingStrength::Strong) 1921 os << '('; 1922 1923 // Pretty print addition to a product that has a negative operand as a 1924 // subtraction. 1925 if (auto rhs = rhsExpr.dyn_cast<AffineBinaryOpExpr>()) { 1926 if (rhs.getKind() == AffineExprKind::Mul) { 1927 AffineExpr rrhsExpr = rhs.getRHS(); 1928 if (auto rrhs = rrhsExpr.dyn_cast<AffineConstantExpr>()) { 1929 if (rrhs.getValue() == -1) { 1930 printAffineExprInternal(lhsExpr, BindingStrength::Weak, 1931 printValueName); 1932 os << " - "; 1933 if (rhs.getLHS().getKind() == AffineExprKind::Add) { 1934 printAffineExprInternal(rhs.getLHS(), BindingStrength::Strong, 1935 printValueName); 1936 } else { 1937 printAffineExprInternal(rhs.getLHS(), BindingStrength::Weak, 1938 printValueName); 1939 } 1940 1941 if (enclosingTightness == BindingStrength::Strong) 1942 os << ')'; 1943 return; 1944 } 1945 1946 if (rrhs.getValue() < -1) { 1947 printAffineExprInternal(lhsExpr, BindingStrength::Weak, 1948 printValueName); 1949 os << " - "; 1950 printAffineExprInternal(rhs.getLHS(), BindingStrength::Strong, 1951 printValueName); 1952 os << " * " << -rrhs.getValue(); 1953 if (enclosingTightness == BindingStrength::Strong) 1954 os << ')'; 1955 return; 1956 } 1957 } 1958 } 1959 } 1960 1961 // Pretty print addition to a negative number as a subtraction. 1962 if (auto rhsConst = rhsExpr.dyn_cast<AffineConstantExpr>()) { 1963 if (rhsConst.getValue() < 0) { 1964 printAffineExprInternal(lhsExpr, BindingStrength::Weak, printValueName); 1965 os << " - " << -rhsConst.getValue(); 1966 if (enclosingTightness == BindingStrength::Strong) 1967 os << ')'; 1968 return; 1969 } 1970 } 1971 1972 printAffineExprInternal(lhsExpr, BindingStrength::Weak, printValueName); 1973 1974 os << " + "; 1975 printAffineExprInternal(rhsExpr, BindingStrength::Weak, printValueName); 1976 1977 if (enclosingTightness == BindingStrength::Strong) 1978 os << ')'; 1979 } 1980 1981 void ModulePrinter::printAffineConstraint(AffineExpr expr, bool isEq) { 1982 printAffineExprInternal(expr, BindingStrength::Weak); 1983 isEq ? os << " == 0" : os << " >= 0"; 1984 } 1985 1986 void ModulePrinter::printAffineMap(AffineMap map) { 1987 // Dimension identifiers. 1988 os << '('; 1989 for (int i = 0; i < (int)map.getNumDims() - 1; ++i) 1990 os << 'd' << i << ", "; 1991 if (map.getNumDims() >= 1) 1992 os << 'd' << map.getNumDims() - 1; 1993 os << ')'; 1994 1995 // Symbolic identifiers. 1996 if (map.getNumSymbols() != 0) { 1997 os << '['; 1998 for (unsigned i = 0; i < map.getNumSymbols() - 1; ++i) 1999 os << 's' << i << ", "; 2000 if (map.getNumSymbols() >= 1) 2001 os << 's' << map.getNumSymbols() - 1; 2002 os << ']'; 2003 } 2004 2005 // Result affine expressions. 2006 os << " -> ("; 2007 interleaveComma(map.getResults(), 2008 [&](AffineExpr expr) { printAffineExpr(expr); }); 2009 os << ')'; 2010 } 2011 2012 void ModulePrinter::printIntegerSet(IntegerSet set) { 2013 // Dimension identifiers. 2014 os << '('; 2015 for (unsigned i = 1; i < set.getNumDims(); ++i) 2016 os << 'd' << i - 1 << ", "; 2017 if (set.getNumDims() >= 1) 2018 os << 'd' << set.getNumDims() - 1; 2019 os << ')'; 2020 2021 // Symbolic identifiers. 2022 if (set.getNumSymbols() != 0) { 2023 os << '['; 2024 for (unsigned i = 0; i < set.getNumSymbols() - 1; ++i) 2025 os << 's' << i << ", "; 2026 if (set.getNumSymbols() >= 1) 2027 os << 's' << set.getNumSymbols() - 1; 2028 os << ']'; 2029 } 2030 2031 // Print constraints. 2032 os << " : ("; 2033 int numConstraints = set.getNumConstraints(); 2034 for (int i = 1; i < numConstraints; ++i) { 2035 printAffineConstraint(set.getConstraint(i - 1), set.isEq(i - 1)); 2036 os << ", "; 2037 } 2038 if (numConstraints >= 1) 2039 printAffineConstraint(set.getConstraint(numConstraints - 1), 2040 set.isEq(numConstraints - 1)); 2041 os << ')'; 2042 } 2043 2044 //===----------------------------------------------------------------------===// 2045 // OperationPrinter 2046 //===----------------------------------------------------------------------===// 2047 2048 namespace { 2049 /// This class contains the logic for printing operations, regions, and blocks. 2050 class OperationPrinter : public ModulePrinter, private OpAsmPrinter { 2051 public: 2052 explicit OperationPrinter(raw_ostream &os, OpPrintingFlags flags, 2053 AsmStateImpl &state) 2054 : ModulePrinter(os, flags, &state) {} 2055 2056 /// Print the given top-level module. 2057 void print(ModuleOp op); 2058 /// Print the given operation with its indent and location. 2059 void print(Operation *op); 2060 /// Print the bare location, not including indentation/location/etc. 2061 void printOperation(Operation *op); 2062 /// Print the given operation in the generic form. 2063 void printGenericOp(Operation *op) override; 2064 2065 /// Print the name of the given block. 2066 void printBlockName(Block *block); 2067 2068 /// Print the given block. If 'printBlockArgs' is false, the arguments of the 2069 /// block are not printed. If 'printBlockTerminator' is false, the terminator 2070 /// operation of the block is not printed. 2071 void print(Block *block, bool printBlockArgs = true, 2072 bool printBlockTerminator = true); 2073 2074 /// Print the ID of the given value, optionally with its result number. 2075 void printValueID(Value value, bool printResultNo = true, 2076 raw_ostream *streamOverride = nullptr) const; 2077 2078 //===--------------------------------------------------------------------===// 2079 // OpAsmPrinter methods 2080 //===--------------------------------------------------------------------===// 2081 2082 /// Return the current stream of the printer. 2083 raw_ostream &getStream() const override { return os; } 2084 2085 /// Print the given type. 2086 void printType(Type type) override { ModulePrinter::printType(type); } 2087 2088 /// Print the given attribute. 2089 void printAttribute(Attribute attr) override { 2090 ModulePrinter::printAttribute(attr); 2091 } 2092 2093 /// Print the given attribute without its type. The corresponding parser must 2094 /// provide a valid type for the attribute. 2095 void printAttributeWithoutType(Attribute attr) override { 2096 ModulePrinter::printAttribute(attr, AttrTypeElision::Must); 2097 } 2098 2099 /// Print the ID for the given value. 2100 void printOperand(Value value) override { printValueID(value); } 2101 void printOperand(Value value, raw_ostream &os) override { 2102 printValueID(value, /*printResultNo=*/true, &os); 2103 } 2104 2105 /// Print an optional attribute dictionary with a given set of elided values. 2106 void printOptionalAttrDict(ArrayRef<NamedAttribute> attrs, 2107 ArrayRef<StringRef> elidedAttrs = {}) override { 2108 ModulePrinter::printOptionalAttrDict(attrs, elidedAttrs); 2109 } 2110 void printOptionalAttrDictWithKeyword( 2111 ArrayRef<NamedAttribute> attrs, 2112 ArrayRef<StringRef> elidedAttrs = {}) override { 2113 ModulePrinter::printOptionalAttrDict(attrs, elidedAttrs, 2114 /*withKeyword=*/true); 2115 } 2116 2117 /// Print the given successor. 2118 void printSuccessor(Block *successor) override; 2119 2120 /// Print an operation successor with the operands used for the block 2121 /// arguments. 2122 void printSuccessorAndUseList(Block *successor, 2123 ValueRange succOperands) override; 2124 2125 /// Print the given region. 2126 void printRegion(Region ®ion, bool printEntryBlockArgs, 2127 bool printBlockTerminators) override; 2128 2129 /// Renumber the arguments for the specified region to the same names as the 2130 /// SSA values in namesToUse. This may only be used for IsolatedFromAbove 2131 /// operations. If any entry in namesToUse is null, the corresponding 2132 /// argument name is left alone. 2133 void shadowRegionArgs(Region ®ion, ValueRange namesToUse) override { 2134 state->getSSANameState().shadowRegionArgs(region, namesToUse); 2135 } 2136 2137 /// Print the given affine map with the symbol and dimension operands printed 2138 /// inline with the map. 2139 void printAffineMapOfSSAIds(AffineMapAttr mapAttr, 2140 ValueRange operands) override; 2141 2142 /// Print the given string as a symbol reference. 2143 void printSymbolName(StringRef symbolRef) override { 2144 ::printSymbolReference(symbolRef, os); 2145 } 2146 2147 private: 2148 /// The number of spaces used for indenting nested operations. 2149 const static unsigned indentWidth = 2; 2150 2151 // This is the current indentation level for nested structures. 2152 unsigned currentIndent = 0; 2153 }; 2154 } // end anonymous namespace 2155 2156 void OperationPrinter::print(ModuleOp op) { 2157 // Output the aliases at the top level. 2158 state->getAliasState().printAttributeAliases(os, newLine); 2159 state->getAliasState().printTypeAliases(os, newLine); 2160 2161 // Print the module. 2162 print(op.getOperation()); 2163 } 2164 2165 void OperationPrinter::print(Operation *op) { 2166 // Track the location of this operation. 2167 state->registerOperationLocation(op, newLine.curLine, currentIndent); 2168 2169 os.indent(currentIndent); 2170 printOperation(op); 2171 printTrailingLocation(op->getLoc()); 2172 } 2173 2174 void OperationPrinter::printOperation(Operation *op) { 2175 if (size_t numResults = op->getNumResults()) { 2176 auto printResultGroup = [&](size_t resultNo, size_t resultCount) { 2177 printValueID(op->getResult(resultNo), /*printResultNo=*/false); 2178 if (resultCount > 1) 2179 os << ':' << resultCount; 2180 }; 2181 2182 // Check to see if this operation has multiple result groups. 2183 ArrayRef<int> resultGroups = state->getSSANameState().getOpResultGroups(op); 2184 if (!resultGroups.empty()) { 2185 // Interleave the groups excluding the last one, this one will be handled 2186 // separately. 2187 interleaveComma(llvm::seq<int>(0, resultGroups.size() - 1), [&](int i) { 2188 printResultGroup(resultGroups[i], 2189 resultGroups[i + 1] - resultGroups[i]); 2190 }); 2191 os << ", "; 2192 printResultGroup(resultGroups.back(), numResults - resultGroups.back()); 2193 2194 } else { 2195 printResultGroup(/*resultNo=*/0, /*resultCount=*/numResults); 2196 } 2197 2198 os << " = "; 2199 } 2200 2201 // If requested, always print the generic form. 2202 if (!printerFlags.shouldPrintGenericOpForm()) { 2203 // Check to see if this is a known operation. If so, use the registered 2204 // custom printer hook. 2205 if (auto *opInfo = op->getAbstractOperation()) { 2206 opInfo->printAssembly(op, *this); 2207 return; 2208 } 2209 } 2210 2211 // Otherwise print with the generic assembly form. 2212 printGenericOp(op); 2213 } 2214 2215 void OperationPrinter::printGenericOp(Operation *op) { 2216 os << '"'; 2217 printEscapedString(op->getName().getStringRef(), os); 2218 os << "\"("; 2219 interleaveComma(op->getOperands(), [&](Value value) { printValueID(value); }); 2220 os << ')'; 2221 2222 // For terminators, print the list of successors and their operands. 2223 if (op->getNumSuccessors() != 0) { 2224 os << '['; 2225 interleaveComma(op->getSuccessors(), 2226 [&](Block *successor) { printBlockName(successor); }); 2227 os << ']'; 2228 } 2229 2230 // Print regions. 2231 if (op->getNumRegions() != 0) { 2232 os << " ("; 2233 interleaveComma(op->getRegions(), [&](Region ®ion) { 2234 printRegion(region, /*printEntryBlockArgs=*/true, 2235 /*printBlockTerminators=*/true); 2236 }); 2237 os << ')'; 2238 } 2239 2240 auto attrs = op->getAttrs(); 2241 printOptionalAttrDict(attrs); 2242 2243 // Print the type signature of the operation. 2244 os << " : "; 2245 printFunctionalType(op); 2246 } 2247 2248 void OperationPrinter::printBlockName(Block *block) { 2249 auto id = state->getSSANameState().getBlockID(block); 2250 if (id != SSANameState::NameSentinel) 2251 os << "^bb" << id; 2252 else 2253 os << "^INVALIDBLOCK"; 2254 } 2255 2256 void OperationPrinter::print(Block *block, bool printBlockArgs, 2257 bool printBlockTerminator) { 2258 // Print the block label and argument list if requested. 2259 if (printBlockArgs) { 2260 os.indent(currentIndent); 2261 printBlockName(block); 2262 2263 // Print the argument list if non-empty. 2264 if (!block->args_empty()) { 2265 os << '('; 2266 interleaveComma(block->getArguments(), [&](BlockArgument arg) { 2267 printValueID(arg); 2268 os << ": "; 2269 printType(arg.getType()); 2270 }); 2271 os << ')'; 2272 } 2273 os << ':'; 2274 2275 // Print out some context information about the predecessors of this block. 2276 if (!block->getParent()) { 2277 os << " // block is not in a region!"; 2278 } else if (block->hasNoPredecessors()) { 2279 os << " // no predecessors"; 2280 } else if (auto *pred = block->getSinglePredecessor()) { 2281 os << " // pred: "; 2282 printBlockName(pred); 2283 } else { 2284 // We want to print the predecessors in increasing numeric order, not in 2285 // whatever order the use-list is in, so gather and sort them. 2286 SmallVector<std::pair<unsigned, Block *>, 4> predIDs; 2287 for (auto *pred : block->getPredecessors()) 2288 predIDs.push_back({state->getSSANameState().getBlockID(pred), pred}); 2289 llvm::array_pod_sort(predIDs.begin(), predIDs.end()); 2290 2291 os << " // " << predIDs.size() << " preds: "; 2292 2293 interleaveComma(predIDs, [&](std::pair<unsigned, Block *> pred) { 2294 printBlockName(pred.second); 2295 }); 2296 } 2297 os << newLine; 2298 } 2299 2300 currentIndent += indentWidth; 2301 auto range = llvm::make_range( 2302 block->getOperations().begin(), 2303 std::prev(block->getOperations().end(), printBlockTerminator ? 0 : 1)); 2304 for (auto &op : range) { 2305 print(&op); 2306 os << newLine; 2307 } 2308 currentIndent -= indentWidth; 2309 } 2310 2311 void OperationPrinter::printValueID(Value value, bool printResultNo, 2312 raw_ostream *streamOverride) const { 2313 state->getSSANameState().printValueID(value, printResultNo, 2314 streamOverride ? *streamOverride : os); 2315 } 2316 2317 void OperationPrinter::printSuccessor(Block *successor) { 2318 printBlockName(successor); 2319 } 2320 2321 void OperationPrinter::printSuccessorAndUseList(Block *successor, 2322 ValueRange succOperands) { 2323 printBlockName(successor); 2324 if (succOperands.empty()) 2325 return; 2326 2327 os << '('; 2328 interleaveComma(succOperands, 2329 [this](Value operand) { printValueID(operand); }); 2330 os << " : "; 2331 interleaveComma(succOperands, 2332 [this](Value operand) { printType(operand.getType()); }); 2333 os << ')'; 2334 } 2335 2336 void OperationPrinter::printRegion(Region ®ion, bool printEntryBlockArgs, 2337 bool printBlockTerminators) { 2338 os << " {" << newLine; 2339 if (!region.empty()) { 2340 auto *entryBlock = ®ion.front(); 2341 print(entryBlock, printEntryBlockArgs && entryBlock->getNumArguments() != 0, 2342 printBlockTerminators); 2343 for (auto &b : llvm::drop_begin(region.getBlocks(), 1)) 2344 print(&b); 2345 } 2346 os.indent(currentIndent) << "}"; 2347 } 2348 2349 void OperationPrinter::printAffineMapOfSSAIds(AffineMapAttr mapAttr, 2350 ValueRange operands) { 2351 AffineMap map = mapAttr.getValue(); 2352 unsigned numDims = map.getNumDims(); 2353 auto printValueName = [&](unsigned pos, bool isSymbol) { 2354 unsigned index = isSymbol ? numDims + pos : pos; 2355 assert(index < operands.size()); 2356 if (isSymbol) 2357 os << "symbol("; 2358 printValueID(operands[index]); 2359 if (isSymbol) 2360 os << ')'; 2361 }; 2362 2363 interleaveComma(map.getResults(), [&](AffineExpr expr) { 2364 printAffineExpr(expr, printValueName); 2365 }); 2366 } 2367 2368 //===----------------------------------------------------------------------===// 2369 // print and dump methods 2370 //===----------------------------------------------------------------------===// 2371 2372 void Attribute::print(raw_ostream &os) const { 2373 ModulePrinter(os).printAttribute(*this); 2374 } 2375 2376 void Attribute::dump() const { 2377 print(llvm::errs()); 2378 llvm::errs() << "\n"; 2379 } 2380 2381 void Type::print(raw_ostream &os) { ModulePrinter(os).printType(*this); } 2382 2383 void Type::dump() { print(llvm::errs()); } 2384 2385 void AffineMap::dump() const { 2386 print(llvm::errs()); 2387 llvm::errs() << "\n"; 2388 } 2389 2390 void IntegerSet::dump() const { 2391 print(llvm::errs()); 2392 llvm::errs() << "\n"; 2393 } 2394 2395 void AffineExpr::print(raw_ostream &os) const { 2396 if (!expr) { 2397 os << "<<NULL AFFINE EXPR>>"; 2398 return; 2399 } 2400 ModulePrinter(os).printAffineExpr(*this); 2401 } 2402 2403 void AffineExpr::dump() const { 2404 print(llvm::errs()); 2405 llvm::errs() << "\n"; 2406 } 2407 2408 void AffineMap::print(raw_ostream &os) const { 2409 if (!map) { 2410 os << "<<NULL AFFINE MAP>>"; 2411 return; 2412 } 2413 ModulePrinter(os).printAffineMap(*this); 2414 } 2415 2416 void IntegerSet::print(raw_ostream &os) const { 2417 ModulePrinter(os).printIntegerSet(*this); 2418 } 2419 2420 void Value::print(raw_ostream &os) { 2421 if (auto *op = getDefiningOp()) 2422 return op->print(os); 2423 // TODO: Improve this. 2424 assert(isa<BlockArgument>()); 2425 os << "<block argument>\n"; 2426 } 2427 void Value::print(raw_ostream &os, AsmState &state) { 2428 if (auto *op = getDefiningOp()) 2429 return op->print(os, state); 2430 2431 // TODO: Improve this. 2432 assert(isa<BlockArgument>()); 2433 os << "<block argument>\n"; 2434 } 2435 2436 void Value::dump() { 2437 print(llvm::errs()); 2438 llvm::errs() << "\n"; 2439 } 2440 2441 void Value::printAsOperand(raw_ostream &os, AsmState &state) { 2442 // TODO: This doesn't necessarily capture all potential cases. 2443 // Currently, region arguments can be shadowed when printing the main 2444 // operation. If the IR hasn't been printed, this will produce the old SSA 2445 // name and not the shadowed name. 2446 state.getImpl().getSSANameState().printValueID(*this, /*printResultNo=*/true, 2447 os); 2448 } 2449 2450 void Operation::print(raw_ostream &os, OpPrintingFlags flags) { 2451 // Find the operation to number from based upon the provided flags. 2452 Operation *printedOp = this; 2453 bool shouldUseLocalScope = flags.shouldUseLocalScope(); 2454 do { 2455 // If we are printing local scope, stop at the first operation that is 2456 // isolated from above. 2457 if (shouldUseLocalScope && printedOp->isKnownIsolatedFromAbove()) 2458 break; 2459 2460 // Otherwise, traverse up to the next parent. 2461 Operation *parentOp = printedOp->getParentOp(); 2462 if (!parentOp) 2463 break; 2464 printedOp = parentOp; 2465 } while (true); 2466 2467 AsmState state(printedOp); 2468 print(os, state, flags); 2469 } 2470 void Operation::print(raw_ostream &os, AsmState &state, OpPrintingFlags flags) { 2471 OperationPrinter(os, flags, state.getImpl()).print(this); 2472 } 2473 2474 void Operation::dump() { 2475 print(llvm::errs(), OpPrintingFlags().useLocalScope()); 2476 llvm::errs() << "\n"; 2477 } 2478 2479 void Block::print(raw_ostream &os) { 2480 Operation *parentOp = getParentOp(); 2481 if (!parentOp) { 2482 os << "<<UNLINKED BLOCK>>\n"; 2483 return; 2484 } 2485 // Get the top-level op. 2486 while (auto *nextOp = parentOp->getParentOp()) 2487 parentOp = nextOp; 2488 2489 AsmState state(parentOp); 2490 print(os, state); 2491 } 2492 void Block::print(raw_ostream &os, AsmState &state) { 2493 OperationPrinter(os, /*flags=*/llvm::None, state.getImpl()).print(this); 2494 } 2495 2496 void Block::dump() { print(llvm::errs()); } 2497 2498 /// Print out the name of the block without printing its body. 2499 void Block::printAsOperand(raw_ostream &os, bool printType) { 2500 Operation *parentOp = getParentOp(); 2501 if (!parentOp) { 2502 os << "<<UNLINKED BLOCK>>\n"; 2503 return; 2504 } 2505 AsmState state(parentOp); 2506 printAsOperand(os, state); 2507 } 2508 void Block::printAsOperand(raw_ostream &os, AsmState &state) { 2509 OperationPrinter printer(os, /*flags=*/llvm::None, state.getImpl()); 2510 printer.printBlockName(this); 2511 } 2512 2513 void ModuleOp::print(raw_ostream &os, OpPrintingFlags flags) { 2514 AsmState state(*this); 2515 2516 // Don't populate aliases when printing at local scope. 2517 if (!flags.shouldUseLocalScope()) 2518 state.getImpl().initializeAliases(*this); 2519 print(os, state, flags); 2520 } 2521 void ModuleOp::print(raw_ostream &os, AsmState &state, OpPrintingFlags flags) { 2522 OperationPrinter(os, flags, state.getImpl()).print(*this); 2523 } 2524 2525 void ModuleOp::dump() { print(llvm::errs()); } 2526