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