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