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