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