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