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::Dictionary:
1322     os << '{';
1323     interleaveComma(attr.cast<DictionaryAttr>().getValue(),
1324                     [&](NamedAttribute attr) { printNamedAttribute(attr); });
1325     os << '}';
1326     break;
1327   case StandardAttributes::Integer: {
1328     auto intAttr = attr.cast<IntegerAttr>();
1329     if (attrType.isSignlessInteger(1)) {
1330       os << (intAttr.getValue().getBoolValue() ? "true" : "false");
1331 
1332       // Boolean integer attributes always elides the type.
1333       return;
1334     }
1335 
1336     // Only print attributes as unsigned if they are explicitly unsigned or are
1337     // signless 1-bit values.  Indexes, signed values, and multi-bit signless
1338     // values print as signed.
1339     bool isUnsigned =
1340         attrType.isUnsignedInteger() || attrType.isSignlessInteger(1);
1341     intAttr.getValue().print(os, !isUnsigned);
1342 
1343     // IntegerAttr elides the type if I64.
1344     if (typeElision == AttrTypeElision::May && attrType.isSignlessInteger(64))
1345       return;
1346     break;
1347   }
1348   case StandardAttributes::Float: {
1349     auto floatAttr = attr.cast<FloatAttr>();
1350     printFloatValue(floatAttr.getValue(), os);
1351 
1352     // FloatAttr elides the type if F64.
1353     if (typeElision == AttrTypeElision::May && attrType.isF64())
1354       return;
1355     break;
1356   }
1357   case StandardAttributes::String:
1358     os << '"';
1359     printEscapedString(attr.cast<StringAttr>().getValue(), os);
1360     os << '"';
1361     break;
1362   case StandardAttributes::Array:
1363     os << '[';
1364     interleaveComma(attr.cast<ArrayAttr>().getValue(), [&](Attribute attr) {
1365       printAttribute(attr, AttrTypeElision::May);
1366     });
1367     os << ']';
1368     break;
1369   case StandardAttributes::AffineMap:
1370     os << "affine_map<";
1371     attr.cast<AffineMapAttr>().getValue().print(os);
1372     os << '>';
1373 
1374     // AffineMap always elides the type.
1375     return;
1376   case StandardAttributes::IntegerSet:
1377     os << "affine_set<";
1378     attr.cast<IntegerSetAttr>().getValue().print(os);
1379     os << '>';
1380 
1381     // IntegerSet always elides the type.
1382     return;
1383   case StandardAttributes::Type:
1384     printType(attr.cast<TypeAttr>().getValue());
1385     break;
1386   case StandardAttributes::SymbolRef: {
1387     auto refAttr = attr.dyn_cast<SymbolRefAttr>();
1388     printSymbolReference(refAttr.getRootReference(), os);
1389     for (FlatSymbolRefAttr nestedRef : refAttr.getNestedReferences()) {
1390       os << "::";
1391       printSymbolReference(nestedRef.getValue(), os);
1392     }
1393     break;
1394   }
1395   case StandardAttributes::OpaqueElements: {
1396     auto eltsAttr = attr.cast<OpaqueElementsAttr>();
1397     if (printerFlags.shouldElideElementsAttr(eltsAttr)) {
1398       printElidedElementsAttr(os);
1399       break;
1400     }
1401     os << "opaque<\"" << eltsAttr.getDialect()->getNamespace() << "\", ";
1402     os << '"' << "0x" << llvm::toHex(eltsAttr.getValue()) << "\">";
1403     break;
1404   }
1405   case StandardAttributes::DenseIntOrFPElements: {
1406     auto eltsAttr = attr.cast<DenseIntOrFPElementsAttr>();
1407     if (printerFlags.shouldElideElementsAttr(eltsAttr)) {
1408       printElidedElementsAttr(os);
1409       break;
1410     }
1411     os << "dense<";
1412     printDenseIntOrFPElementsAttr(eltsAttr, /*allowHex=*/true);
1413     os << '>';
1414     break;
1415   }
1416   case StandardAttributes::DenseStringElements: {
1417     auto eltsAttr = attr.cast<DenseStringElementsAttr>();
1418     if (printerFlags.shouldElideElementsAttr(eltsAttr)) {
1419       printElidedElementsAttr(os);
1420       break;
1421     }
1422     os << "dense<";
1423     printDenseStringElementsAttr(eltsAttr);
1424     os << '>';
1425     break;
1426   }
1427   case StandardAttributes::SparseElements: {
1428     auto elementsAttr = attr.cast<SparseElementsAttr>();
1429     if (printerFlags.shouldElideElementsAttr(elementsAttr.getIndices()) ||
1430         printerFlags.shouldElideElementsAttr(elementsAttr.getValues())) {
1431       printElidedElementsAttr(os);
1432       break;
1433     }
1434     os << "sparse<";
1435     printDenseIntOrFPElementsAttr(elementsAttr.getIndices(),
1436                                   /*allowHex=*/false);
1437     os << ", ";
1438     printDenseElementsAttr(elementsAttr.getValues(), /*allowHex=*/true);
1439     os << '>';
1440     break;
1441   }
1442 
1443   // Location attributes.
1444   case StandardAttributes::CallSiteLocation:
1445   case StandardAttributes::FileLineColLocation:
1446   case StandardAttributes::FusedLocation:
1447   case StandardAttributes::NameLocation:
1448   case StandardAttributes::OpaqueLocation:
1449   case StandardAttributes::UnknownLocation:
1450     printLocation(attr.cast<LocationAttr>());
1451     break;
1452   }
1453 
1454   // Don't print the type if we must elide it, or if it is a None type.
1455   if (typeElision != AttrTypeElision::Must && !attrType.isa<NoneType>()) {
1456     os << " : ";
1457     printType(attrType);
1458   }
1459 }
1460 
1461 /// Print the integer element of a DenseElementsAttr.
1462 static void printDenseIntElement(const APInt &value, raw_ostream &os,
1463                                  bool isSigned) {
1464   if (value.getBitWidth() == 1)
1465     os << (value.getBoolValue() ? "true" : "false");
1466   else
1467     value.print(os, isSigned);
1468 }
1469 
1470 static void
1471 printDenseElementsAttrImpl(bool isSplat, ShapedType type, raw_ostream &os,
1472                            function_ref<void(unsigned)> printEltFn) {
1473   // Special case for 0-d and splat tensors.
1474   if (isSplat)
1475     return printEltFn(0);
1476 
1477   // Special case for degenerate tensors.
1478   auto numElements = type.getNumElements();
1479   int64_t rank = type.getRank();
1480   if (numElements == 0) {
1481     for (int i = 0; i < rank; ++i)
1482       os << '[';
1483     for (int i = 0; i < rank; ++i)
1484       os << ']';
1485     return;
1486   }
1487 
1488   // We use a mixed-radix counter to iterate through the shape. When we bump a
1489   // non-least-significant digit, we emit a close bracket. When we next emit an
1490   // element we re-open all closed brackets.
1491 
1492   // The mixed-radix counter, with radices in 'shape'.
1493   SmallVector<unsigned, 4> counter(rank, 0);
1494   // The number of brackets that have been opened and not closed.
1495   unsigned openBrackets = 0;
1496 
1497   auto shape = type.getShape();
1498   auto bumpCounter = [&] {
1499     // Bump the least significant digit.
1500     ++counter[rank - 1];
1501     // Iterate backwards bubbling back the increment.
1502     for (unsigned i = rank - 1; i > 0; --i)
1503       if (counter[i] >= shape[i]) {
1504         // Index 'i' is rolled over. Bump (i-1) and close a bracket.
1505         counter[i] = 0;
1506         ++counter[i - 1];
1507         --openBrackets;
1508         os << ']';
1509       }
1510   };
1511 
1512   for (unsigned idx = 0, e = numElements; idx != e; ++idx) {
1513     if (idx != 0)
1514       os << ", ";
1515     while (openBrackets++ < rank)
1516       os << '[';
1517     openBrackets = rank;
1518     printEltFn(idx);
1519     bumpCounter();
1520   }
1521   while (openBrackets-- > 0)
1522     os << ']';
1523 }
1524 
1525 void ModulePrinter::printDenseElementsAttr(DenseElementsAttr attr,
1526                                            bool allowHex) {
1527   if (auto stringAttr = attr.dyn_cast<DenseStringElementsAttr>())
1528     return printDenseStringElementsAttr(stringAttr);
1529 
1530   printDenseIntOrFPElementsAttr(attr.cast<DenseIntOrFPElementsAttr>(),
1531                                 allowHex);
1532 }
1533 
1534 void ModulePrinter::printDenseIntOrFPElementsAttr(DenseIntOrFPElementsAttr attr,
1535                                                   bool allowHex) {
1536   auto type = attr.getType();
1537   auto elementType = type.getElementType();
1538 
1539   // Check to see if we should format this attribute as a hex string.
1540   auto numElements = type.getNumElements();
1541   if (!attr.isSplat() && allowHex &&
1542       shouldPrintElementsAttrWithHex(numElements)) {
1543     ArrayRef<char> rawData = attr.getRawData();
1544     os << '"' << "0x" << llvm::toHex(StringRef(rawData.data(), rawData.size()))
1545        << "\"";
1546     return;
1547   }
1548 
1549   if (ComplexType complexTy = elementType.dyn_cast<ComplexType>()) {
1550     auto printComplexValue = [&](auto complexValues, auto printFn,
1551                                  raw_ostream &os, auto &&... params) {
1552       printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) {
1553         auto complexValue = *(complexValues.begin() + index);
1554         os << "(";
1555         printFn(complexValue.real(), os, params...);
1556         os << ",";
1557         printFn(complexValue.imag(), os, params...);
1558         os << ")";
1559       });
1560     };
1561 
1562     Type complexElementType = complexTy.getElementType();
1563     if (complexElementType.isa<IntegerType>())
1564       printComplexValue(attr.getComplexIntValues(), printDenseIntElement, os,
1565                         /*isSigned=*/!complexElementType.isUnsignedInteger());
1566     else
1567       printComplexValue(attr.getComplexFloatValues(), printFloatValue, os);
1568   } else if (elementType.isIntOrIndex()) {
1569     bool isSigned = !elementType.isUnsignedInteger();
1570     auto intValues = attr.getIntValues();
1571     printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) {
1572       printDenseIntElement(*(intValues.begin() + index), os, isSigned);
1573     });
1574   } else {
1575     assert(elementType.isa<FloatType>() && "unexpected element type");
1576     auto floatValues = attr.getFloatValues();
1577     printDenseElementsAttrImpl(attr.isSplat(), type, os, [&](unsigned index) {
1578       printFloatValue(*(floatValues.begin() + index), os);
1579     });
1580   }
1581 }
1582 
1583 void ModulePrinter::printDenseStringElementsAttr(DenseStringElementsAttr attr) {
1584   ArrayRef<StringRef> data = attr.getRawStringData();
1585   auto printFn = [&](unsigned index) {
1586     os << "\"";
1587     printEscapedString(data[index], os);
1588     os << "\"";
1589   };
1590   printDenseElementsAttrImpl(attr.isSplat(), attr.getType(), os, printFn);
1591 }
1592 
1593 void ModulePrinter::printType(Type type) {
1594   if (!type) {
1595     os << "<<NULL TYPE>>";
1596     return;
1597   }
1598 
1599   // Check for an alias for this type.
1600   if (state) {
1601     StringRef alias = state->getAliasState().getTypeAlias(type);
1602     if (!alias.empty()) {
1603       os << '!' << alias;
1604       return;
1605     }
1606   }
1607 
1608   switch (type.getKind()) {
1609   default:
1610     return printDialectType(type);
1611 
1612   case Type::Kind::Opaque: {
1613     auto opaqueTy = type.cast<OpaqueType>();
1614     printDialectSymbol(os, "!", opaqueTy.getDialectNamespace(),
1615                        opaqueTy.getTypeData());
1616     return;
1617   }
1618   case StandardTypes::Index:
1619     os << "index";
1620     return;
1621   case StandardTypes::BF16:
1622     os << "bf16";
1623     return;
1624   case StandardTypes::F16:
1625     os << "f16";
1626     return;
1627   case StandardTypes::F32:
1628     os << "f32";
1629     return;
1630   case StandardTypes::F64:
1631     os << "f64";
1632     return;
1633 
1634   case StandardTypes::Integer: {
1635     auto integer = type.cast<IntegerType>();
1636     if (integer.isSigned())
1637       os << 's';
1638     else if (integer.isUnsigned())
1639       os << 'u';
1640     os << 'i' << integer.getWidth();
1641     return;
1642   }
1643   case Type::Kind::Function: {
1644     auto func = type.cast<FunctionType>();
1645     os << '(';
1646     interleaveComma(func.getInputs(), [&](Type type) { printType(type); });
1647     os << ") -> ";
1648     auto results = func.getResults();
1649     if (results.size() == 1 && !results[0].isa<FunctionType>())
1650       os << results[0];
1651     else {
1652       os << '(';
1653       interleaveComma(results, [&](Type type) { printType(type); });
1654       os << ')';
1655     }
1656     return;
1657   }
1658   case StandardTypes::Vector: {
1659     auto v = type.cast<VectorType>();
1660     os << "vector<";
1661     for (auto dim : v.getShape())
1662       os << dim << 'x';
1663     os << v.getElementType() << '>';
1664     return;
1665   }
1666   case StandardTypes::RankedTensor: {
1667     auto v = type.cast<RankedTensorType>();
1668     os << "tensor<";
1669     for (auto dim : v.getShape()) {
1670       if (dim < 0)
1671         os << '?';
1672       else
1673         os << dim;
1674       os << 'x';
1675     }
1676     os << v.getElementType() << '>';
1677     return;
1678   }
1679   case StandardTypes::UnrankedTensor: {
1680     auto v = type.cast<UnrankedTensorType>();
1681     os << "tensor<*x";
1682     printType(v.getElementType());
1683     os << '>';
1684     return;
1685   }
1686   case StandardTypes::MemRef: {
1687     auto v = type.cast<MemRefType>();
1688     os << "memref<";
1689     for (auto dim : v.getShape()) {
1690       if (dim < 0)
1691         os << '?';
1692       else
1693         os << dim;
1694       os << 'x';
1695     }
1696     printType(v.getElementType());
1697     for (auto map : v.getAffineMaps()) {
1698       os << ", ";
1699       printAttribute(AffineMapAttr::get(map));
1700     }
1701     // Only print the memory space if it is the non-default one.
1702     if (v.getMemorySpace())
1703       os << ", " << v.getMemorySpace();
1704     os << '>';
1705     return;
1706   }
1707   case StandardTypes::UnrankedMemRef: {
1708     auto v = type.cast<UnrankedMemRefType>();
1709     os << "memref<*x";
1710     printType(v.getElementType());
1711     os << '>';
1712     return;
1713   }
1714   case StandardTypes::Complex:
1715     os << "complex<";
1716     printType(type.cast<ComplexType>().getElementType());
1717     os << '>';
1718     return;
1719   case StandardTypes::Tuple: {
1720     auto tuple = type.cast<TupleType>();
1721     os << "tuple<";
1722     interleaveComma(tuple.getTypes(), [&](Type type) { printType(type); });
1723     os << '>';
1724     return;
1725   }
1726   case StandardTypes::None:
1727     os << "none";
1728     return;
1729   }
1730 }
1731 
1732 void ModulePrinter::printOptionalAttrDict(ArrayRef<NamedAttribute> attrs,
1733                                           ArrayRef<StringRef> elidedAttrs,
1734                                           bool withKeyword) {
1735   // If there are no attributes, then there is nothing to be done.
1736   if (attrs.empty())
1737     return;
1738 
1739   // Filter out any attributes that shouldn't be included.
1740   SmallVector<NamedAttribute, 8> filteredAttrs(
1741       llvm::make_filter_range(attrs, [&](NamedAttribute attr) {
1742         return !llvm::is_contained(elidedAttrs, attr.first.strref());
1743       }));
1744 
1745   // If there are no attributes left to print after filtering, then we're done.
1746   if (filteredAttrs.empty())
1747     return;
1748 
1749   // Print the 'attributes' keyword if necessary.
1750   if (withKeyword)
1751     os << " attributes";
1752 
1753   // Otherwise, print them all out in braces.
1754   os << " {";
1755   interleaveComma(filteredAttrs,
1756                   [&](NamedAttribute attr) { printNamedAttribute(attr); });
1757   os << '}';
1758 }
1759 
1760 void ModulePrinter::printNamedAttribute(NamedAttribute attr) {
1761   if (isBareIdentifier(attr.first)) {
1762     os << attr.first;
1763   } else {
1764     os << '"';
1765     printEscapedString(attr.first.strref(), os);
1766     os << '"';
1767   }
1768 
1769   // Pretty printing elides the attribute value for unit attributes.
1770   if (attr.second.isa<UnitAttr>())
1771     return;
1772 
1773   os << " = ";
1774   printAttribute(attr.second);
1775 }
1776 
1777 //===----------------------------------------------------------------------===//
1778 // CustomDialectAsmPrinter
1779 //===----------------------------------------------------------------------===//
1780 
1781 namespace {
1782 /// This class provides the main specialization of the DialectAsmPrinter that is
1783 /// used to provide support for print attributes and types. This hooks allows
1784 /// for dialects to hook into the main ModulePrinter.
1785 struct CustomDialectAsmPrinter : public DialectAsmPrinter {
1786 public:
1787   CustomDialectAsmPrinter(ModulePrinter &printer) : printer(printer) {}
1788   ~CustomDialectAsmPrinter() override {}
1789 
1790   raw_ostream &getStream() const override { return printer.getStream(); }
1791 
1792   /// Print the given attribute to the stream.
1793   void printAttribute(Attribute attr) override { printer.printAttribute(attr); }
1794 
1795   /// Print the given floating point value in a stablized form.
1796   void printFloat(const APFloat &value) override {
1797     printFloatValue(value, getStream());
1798   }
1799 
1800   /// Print the given type to the stream.
1801   void printType(Type type) override { printer.printType(type); }
1802 
1803   /// The main module printer.
1804   ModulePrinter &printer;
1805 };
1806 } // end anonymous namespace
1807 
1808 void ModulePrinter::printDialectAttribute(Attribute attr) {
1809   auto &dialect = attr.getDialect();
1810 
1811   // Ask the dialect to serialize the attribute to a string.
1812   std::string attrName;
1813   {
1814     llvm::raw_string_ostream attrNameStr(attrName);
1815     ModulePrinter subPrinter(attrNameStr, printerFlags, state);
1816     CustomDialectAsmPrinter printer(subPrinter);
1817     dialect.printAttribute(attr, printer);
1818   }
1819   printDialectSymbol(os, "#", dialect.getNamespace(), attrName);
1820 }
1821 
1822 void ModulePrinter::printDialectType(Type type) {
1823   auto &dialect = type.getDialect();
1824 
1825   // Ask the dialect to serialize the type to a string.
1826   std::string typeName;
1827   {
1828     llvm::raw_string_ostream typeNameStr(typeName);
1829     ModulePrinter subPrinter(typeNameStr, printerFlags, state);
1830     CustomDialectAsmPrinter printer(subPrinter);
1831     dialect.printType(type, printer);
1832   }
1833   printDialectSymbol(os, "!", dialect.getNamespace(), typeName);
1834 }
1835 
1836 //===----------------------------------------------------------------------===//
1837 // Affine expressions and maps
1838 //===----------------------------------------------------------------------===//
1839 
1840 void ModulePrinter::printAffineExpr(
1841     AffineExpr expr, function_ref<void(unsigned, bool)> printValueName) {
1842   printAffineExprInternal(expr, BindingStrength::Weak, printValueName);
1843 }
1844 
1845 void ModulePrinter::printAffineExprInternal(
1846     AffineExpr expr, BindingStrength enclosingTightness,
1847     function_ref<void(unsigned, bool)> printValueName) {
1848   const char *binopSpelling = nullptr;
1849   switch (expr.getKind()) {
1850   case AffineExprKind::SymbolId: {
1851     unsigned pos = expr.cast<AffineSymbolExpr>().getPosition();
1852     if (printValueName)
1853       printValueName(pos, /*isSymbol=*/true);
1854     else
1855       os << 's' << pos;
1856     return;
1857   }
1858   case AffineExprKind::DimId: {
1859     unsigned pos = expr.cast<AffineDimExpr>().getPosition();
1860     if (printValueName)
1861       printValueName(pos, /*isSymbol=*/false);
1862     else
1863       os << 'd' << pos;
1864     return;
1865   }
1866   case AffineExprKind::Constant:
1867     os << expr.cast<AffineConstantExpr>().getValue();
1868     return;
1869   case AffineExprKind::Add:
1870     binopSpelling = " + ";
1871     break;
1872   case AffineExprKind::Mul:
1873     binopSpelling = " * ";
1874     break;
1875   case AffineExprKind::FloorDiv:
1876     binopSpelling = " floordiv ";
1877     break;
1878   case AffineExprKind::CeilDiv:
1879     binopSpelling = " ceildiv ";
1880     break;
1881   case AffineExprKind::Mod:
1882     binopSpelling = " mod ";
1883     break;
1884   }
1885 
1886   auto binOp = expr.cast<AffineBinaryOpExpr>();
1887   AffineExpr lhsExpr = binOp.getLHS();
1888   AffineExpr rhsExpr = binOp.getRHS();
1889 
1890   // Handle tightly binding binary operators.
1891   if (binOp.getKind() != AffineExprKind::Add) {
1892     if (enclosingTightness == BindingStrength::Strong)
1893       os << '(';
1894 
1895     // Pretty print multiplication with -1.
1896     auto rhsConst = rhsExpr.dyn_cast<AffineConstantExpr>();
1897     if (rhsConst && binOp.getKind() == AffineExprKind::Mul &&
1898         rhsConst.getValue() == -1) {
1899       os << "-";
1900       printAffineExprInternal(lhsExpr, BindingStrength::Strong, printValueName);
1901       if (enclosingTightness == BindingStrength::Strong)
1902         os << ')';
1903       return;
1904     }
1905 
1906     printAffineExprInternal(lhsExpr, BindingStrength::Strong, printValueName);
1907 
1908     os << binopSpelling;
1909     printAffineExprInternal(rhsExpr, BindingStrength::Strong, printValueName);
1910 
1911     if (enclosingTightness == BindingStrength::Strong)
1912       os << ')';
1913     return;
1914   }
1915 
1916   // Print out special "pretty" forms for add.
1917   if (enclosingTightness == BindingStrength::Strong)
1918     os << '(';
1919 
1920   // Pretty print addition to a product that has a negative operand as a
1921   // subtraction.
1922   if (auto rhs = rhsExpr.dyn_cast<AffineBinaryOpExpr>()) {
1923     if (rhs.getKind() == AffineExprKind::Mul) {
1924       AffineExpr rrhsExpr = rhs.getRHS();
1925       if (auto rrhs = rrhsExpr.dyn_cast<AffineConstantExpr>()) {
1926         if (rrhs.getValue() == -1) {
1927           printAffineExprInternal(lhsExpr, BindingStrength::Weak,
1928                                   printValueName);
1929           os << " - ";
1930           if (rhs.getLHS().getKind() == AffineExprKind::Add) {
1931             printAffineExprInternal(rhs.getLHS(), BindingStrength::Strong,
1932                                     printValueName);
1933           } else {
1934             printAffineExprInternal(rhs.getLHS(), BindingStrength::Weak,
1935                                     printValueName);
1936           }
1937 
1938           if (enclosingTightness == BindingStrength::Strong)
1939             os << ')';
1940           return;
1941         }
1942 
1943         if (rrhs.getValue() < -1) {
1944           printAffineExprInternal(lhsExpr, BindingStrength::Weak,
1945                                   printValueName);
1946           os << " - ";
1947           printAffineExprInternal(rhs.getLHS(), BindingStrength::Strong,
1948                                   printValueName);
1949           os << " * " << -rrhs.getValue();
1950           if (enclosingTightness == BindingStrength::Strong)
1951             os << ')';
1952           return;
1953         }
1954       }
1955     }
1956   }
1957 
1958   // Pretty print addition to a negative number as a subtraction.
1959   if (auto rhsConst = rhsExpr.dyn_cast<AffineConstantExpr>()) {
1960     if (rhsConst.getValue() < 0) {
1961       printAffineExprInternal(lhsExpr, BindingStrength::Weak, printValueName);
1962       os << " - " << -rhsConst.getValue();
1963       if (enclosingTightness == BindingStrength::Strong)
1964         os << ')';
1965       return;
1966     }
1967   }
1968 
1969   printAffineExprInternal(lhsExpr, BindingStrength::Weak, printValueName);
1970 
1971   os << " + ";
1972   printAffineExprInternal(rhsExpr, BindingStrength::Weak, printValueName);
1973 
1974   if (enclosingTightness == BindingStrength::Strong)
1975     os << ')';
1976 }
1977 
1978 void ModulePrinter::printAffineConstraint(AffineExpr expr, bool isEq) {
1979   printAffineExprInternal(expr, BindingStrength::Weak);
1980   isEq ? os << " == 0" : os << " >= 0";
1981 }
1982 
1983 void ModulePrinter::printAffineMap(AffineMap map) {
1984   // Dimension identifiers.
1985   os << '(';
1986   for (int i = 0; i < (int)map.getNumDims() - 1; ++i)
1987     os << 'd' << i << ", ";
1988   if (map.getNumDims() >= 1)
1989     os << 'd' << map.getNumDims() - 1;
1990   os << ')';
1991 
1992   // Symbolic identifiers.
1993   if (map.getNumSymbols() != 0) {
1994     os << '[';
1995     for (unsigned i = 0; i < map.getNumSymbols() - 1; ++i)
1996       os << 's' << i << ", ";
1997     if (map.getNumSymbols() >= 1)
1998       os << 's' << map.getNumSymbols() - 1;
1999     os << ']';
2000   }
2001 
2002   // Result affine expressions.
2003   os << " -> (";
2004   interleaveComma(map.getResults(),
2005                   [&](AffineExpr expr) { printAffineExpr(expr); });
2006   os << ')';
2007 }
2008 
2009 void ModulePrinter::printIntegerSet(IntegerSet set) {
2010   // Dimension identifiers.
2011   os << '(';
2012   for (unsigned i = 1; i < set.getNumDims(); ++i)
2013     os << 'd' << i - 1 << ", ";
2014   if (set.getNumDims() >= 1)
2015     os << 'd' << set.getNumDims() - 1;
2016   os << ')';
2017 
2018   // Symbolic identifiers.
2019   if (set.getNumSymbols() != 0) {
2020     os << '[';
2021     for (unsigned i = 0; i < set.getNumSymbols() - 1; ++i)
2022       os << 's' << i << ", ";
2023     if (set.getNumSymbols() >= 1)
2024       os << 's' << set.getNumSymbols() - 1;
2025     os << ']';
2026   }
2027 
2028   // Print constraints.
2029   os << " : (";
2030   int numConstraints = set.getNumConstraints();
2031   for (int i = 1; i < numConstraints; ++i) {
2032     printAffineConstraint(set.getConstraint(i - 1), set.isEq(i - 1));
2033     os << ", ";
2034   }
2035   if (numConstraints >= 1)
2036     printAffineConstraint(set.getConstraint(numConstraints - 1),
2037                           set.isEq(numConstraints - 1));
2038   os << ')';
2039 }
2040 
2041 //===----------------------------------------------------------------------===//
2042 // OperationPrinter
2043 //===----------------------------------------------------------------------===//
2044 
2045 namespace {
2046 /// This class contains the logic for printing operations, regions, and blocks.
2047 class OperationPrinter : public ModulePrinter, private OpAsmPrinter {
2048 public:
2049   explicit OperationPrinter(raw_ostream &os, OpPrintingFlags flags,
2050                             AsmStateImpl &state)
2051       : ModulePrinter(os, flags, &state) {}
2052 
2053   /// Print the given top-level module.
2054   void print(ModuleOp op);
2055   /// Print the given operation with its indent and location.
2056   void print(Operation *op);
2057   /// Print the bare location, not including indentation/location/etc.
2058   void printOperation(Operation *op);
2059   /// Print the given operation in the generic form.
2060   void printGenericOp(Operation *op) override;
2061 
2062   /// Print the name of the given block.
2063   void printBlockName(Block *block);
2064 
2065   /// Print the given block. If 'printBlockArgs' is false, the arguments of the
2066   /// block are not printed. If 'printBlockTerminator' is false, the terminator
2067   /// operation of the block is not printed.
2068   void print(Block *block, bool printBlockArgs = true,
2069              bool printBlockTerminator = true);
2070 
2071   /// Print the ID of the given value, optionally with its result number.
2072   void printValueID(Value value, bool printResultNo = true,
2073                     raw_ostream *streamOverride = nullptr) const;
2074 
2075   //===--------------------------------------------------------------------===//
2076   // OpAsmPrinter methods
2077   //===--------------------------------------------------------------------===//
2078 
2079   /// Return the current stream of the printer.
2080   raw_ostream &getStream() const override { return os; }
2081 
2082   /// Print the given type.
2083   void printType(Type type) override { ModulePrinter::printType(type); }
2084 
2085   /// Print the given attribute.
2086   void printAttribute(Attribute attr) override {
2087     ModulePrinter::printAttribute(attr);
2088   }
2089 
2090   /// Print the given attribute without its type. The corresponding parser must
2091   /// provide a valid type for the attribute.
2092   void printAttributeWithoutType(Attribute attr) override {
2093     ModulePrinter::printAttribute(attr, AttrTypeElision::Must);
2094   }
2095 
2096   /// Print the ID for the given value.
2097   void printOperand(Value value) override { printValueID(value); }
2098   void printOperand(Value value, raw_ostream &os) override {
2099     printValueID(value, /*printResultNo=*/true, &os);
2100   }
2101 
2102   /// Print an optional attribute dictionary with a given set of elided values.
2103   void printOptionalAttrDict(ArrayRef<NamedAttribute> attrs,
2104                              ArrayRef<StringRef> elidedAttrs = {}) override {
2105     ModulePrinter::printOptionalAttrDict(attrs, elidedAttrs);
2106   }
2107   void printOptionalAttrDictWithKeyword(
2108       ArrayRef<NamedAttribute> attrs,
2109       ArrayRef<StringRef> elidedAttrs = {}) override {
2110     ModulePrinter::printOptionalAttrDict(attrs, elidedAttrs,
2111                                          /*withKeyword=*/true);
2112   }
2113 
2114   /// Print the given successor.
2115   void printSuccessor(Block *successor) override;
2116 
2117   /// Print an operation successor with the operands used for the block
2118   /// arguments.
2119   void printSuccessorAndUseList(Block *successor,
2120                                 ValueRange succOperands) override;
2121 
2122   /// Print the given region.
2123   void printRegion(Region &region, bool printEntryBlockArgs,
2124                    bool printBlockTerminators) override;
2125 
2126   /// Renumber the arguments for the specified region to the same names as the
2127   /// SSA values in namesToUse. This may only be used for IsolatedFromAbove
2128   /// operations. If any entry in namesToUse is null, the corresponding
2129   /// argument name is left alone.
2130   void shadowRegionArgs(Region &region, ValueRange namesToUse) override {
2131     state->getSSANameState().shadowRegionArgs(region, namesToUse);
2132   }
2133 
2134   /// Print the given affine map with the symbol and dimension operands printed
2135   /// inline with the map.
2136   void printAffineMapOfSSAIds(AffineMapAttr mapAttr,
2137                               ValueRange operands) override;
2138 
2139   /// Print the given string as a symbol reference.
2140   void printSymbolName(StringRef symbolRef) override {
2141     ::printSymbolReference(symbolRef, os);
2142   }
2143 
2144 private:
2145   /// The number of spaces used for indenting nested operations.
2146   const static unsigned indentWidth = 2;
2147 
2148   // This is the current indentation level for nested structures.
2149   unsigned currentIndent = 0;
2150 };
2151 } // end anonymous namespace
2152 
2153 void OperationPrinter::print(ModuleOp op) {
2154   // Output the aliases at the top level.
2155   state->getAliasState().printAttributeAliases(os, newLine);
2156   state->getAliasState().printTypeAliases(os, newLine);
2157 
2158   // Print the module.
2159   print(op.getOperation());
2160 }
2161 
2162 void OperationPrinter::print(Operation *op) {
2163   // Track the location of this operation.
2164   state->registerOperationLocation(op, newLine.curLine, currentIndent);
2165 
2166   os.indent(currentIndent);
2167   printOperation(op);
2168   printTrailingLocation(op->getLoc());
2169 }
2170 
2171 void OperationPrinter::printOperation(Operation *op) {
2172   if (size_t numResults = op->getNumResults()) {
2173     auto printResultGroup = [&](size_t resultNo, size_t resultCount) {
2174       printValueID(op->getResult(resultNo), /*printResultNo=*/false);
2175       if (resultCount > 1)
2176         os << ':' << resultCount;
2177     };
2178 
2179     // Check to see if this operation has multiple result groups.
2180     ArrayRef<int> resultGroups = state->getSSANameState().getOpResultGroups(op);
2181     if (!resultGroups.empty()) {
2182       // Interleave the groups excluding the last one, this one will be handled
2183       // separately.
2184       interleaveComma(llvm::seq<int>(0, resultGroups.size() - 1), [&](int i) {
2185         printResultGroup(resultGroups[i],
2186                          resultGroups[i + 1] - resultGroups[i]);
2187       });
2188       os << ", ";
2189       printResultGroup(resultGroups.back(), numResults - resultGroups.back());
2190 
2191     } else {
2192       printResultGroup(/*resultNo=*/0, /*resultCount=*/numResults);
2193     }
2194 
2195     os << " = ";
2196   }
2197 
2198   // If requested, always print the generic form.
2199   if (!printerFlags.shouldPrintGenericOpForm()) {
2200     // Check to see if this is a known operation.  If so, use the registered
2201     // custom printer hook.
2202     if (auto *opInfo = op->getAbstractOperation()) {
2203       opInfo->printAssembly(op, *this);
2204       return;
2205     }
2206   }
2207 
2208   // Otherwise print with the generic assembly form.
2209   printGenericOp(op);
2210 }
2211 
2212 void OperationPrinter::printGenericOp(Operation *op) {
2213   os << '"';
2214   printEscapedString(op->getName().getStringRef(), os);
2215   os << "\"(";
2216   interleaveComma(op->getOperands(), [&](Value value) { printValueID(value); });
2217   os << ')';
2218 
2219   // For terminators, print the list of successors and their operands.
2220   if (op->getNumSuccessors() != 0) {
2221     os << '[';
2222     interleaveComma(op->getSuccessors(),
2223                     [&](Block *successor) { printBlockName(successor); });
2224     os << ']';
2225   }
2226 
2227   // Print regions.
2228   if (op->getNumRegions() != 0) {
2229     os << " (";
2230     interleaveComma(op->getRegions(), [&](Region &region) {
2231       printRegion(region, /*printEntryBlockArgs=*/true,
2232                   /*printBlockTerminators=*/true);
2233     });
2234     os << ')';
2235   }
2236 
2237   auto attrs = op->getAttrs();
2238   printOptionalAttrDict(attrs);
2239 
2240   // Print the type signature of the operation.
2241   os << " : ";
2242   printFunctionalType(op);
2243 }
2244 
2245 void OperationPrinter::printBlockName(Block *block) {
2246   auto id = state->getSSANameState().getBlockID(block);
2247   if (id != SSANameState::NameSentinel)
2248     os << "^bb" << id;
2249   else
2250     os << "^INVALIDBLOCK";
2251 }
2252 
2253 void OperationPrinter::print(Block *block, bool printBlockArgs,
2254                              bool printBlockTerminator) {
2255   // Print the block label and argument list if requested.
2256   if (printBlockArgs) {
2257     os.indent(currentIndent);
2258     printBlockName(block);
2259 
2260     // Print the argument list if non-empty.
2261     if (!block->args_empty()) {
2262       os << '(';
2263       interleaveComma(block->getArguments(), [&](BlockArgument arg) {
2264         printValueID(arg);
2265         os << ": ";
2266         printType(arg.getType());
2267       });
2268       os << ')';
2269     }
2270     os << ':';
2271 
2272     // Print out some context information about the predecessors of this block.
2273     if (!block->getParent()) {
2274       os << "  // block is not in a region!";
2275     } else if (block->hasNoPredecessors()) {
2276       os << "  // no predecessors";
2277     } else if (auto *pred = block->getSinglePredecessor()) {
2278       os << "  // pred: ";
2279       printBlockName(pred);
2280     } else {
2281       // We want to print the predecessors in increasing numeric order, not in
2282       // whatever order the use-list is in, so gather and sort them.
2283       SmallVector<std::pair<unsigned, Block *>, 4> predIDs;
2284       for (auto *pred : block->getPredecessors())
2285         predIDs.push_back({state->getSSANameState().getBlockID(pred), pred});
2286       llvm::array_pod_sort(predIDs.begin(), predIDs.end());
2287 
2288       os << "  // " << predIDs.size() << " preds: ";
2289 
2290       interleaveComma(predIDs, [&](std::pair<unsigned, Block *> pred) {
2291         printBlockName(pred.second);
2292       });
2293     }
2294     os << newLine;
2295   }
2296 
2297   currentIndent += indentWidth;
2298   auto range = llvm::make_range(
2299       block->getOperations().begin(),
2300       std::prev(block->getOperations().end(), printBlockTerminator ? 0 : 1));
2301   for (auto &op : range) {
2302     print(&op);
2303     os << newLine;
2304   }
2305   currentIndent -= indentWidth;
2306 }
2307 
2308 void OperationPrinter::printValueID(Value value, bool printResultNo,
2309                                     raw_ostream *streamOverride) const {
2310   state->getSSANameState().printValueID(value, printResultNo,
2311                                         streamOverride ? *streamOverride : os);
2312 }
2313 
2314 void OperationPrinter::printSuccessor(Block *successor) {
2315   printBlockName(successor);
2316 }
2317 
2318 void OperationPrinter::printSuccessorAndUseList(Block *successor,
2319                                                 ValueRange succOperands) {
2320   printBlockName(successor);
2321   if (succOperands.empty())
2322     return;
2323 
2324   os << '(';
2325   interleaveComma(succOperands,
2326                   [this](Value operand) { printValueID(operand); });
2327   os << " : ";
2328   interleaveComma(succOperands,
2329                   [this](Value operand) { printType(operand.getType()); });
2330   os << ')';
2331 }
2332 
2333 void OperationPrinter::printRegion(Region &region, bool printEntryBlockArgs,
2334                                    bool printBlockTerminators) {
2335   os << " {" << newLine;
2336   if (!region.empty()) {
2337     auto *entryBlock = &region.front();
2338     print(entryBlock, printEntryBlockArgs && entryBlock->getNumArguments() != 0,
2339           printBlockTerminators);
2340     for (auto &b : llvm::drop_begin(region.getBlocks(), 1))
2341       print(&b);
2342   }
2343   os.indent(currentIndent) << "}";
2344 }
2345 
2346 void OperationPrinter::printAffineMapOfSSAIds(AffineMapAttr mapAttr,
2347                                               ValueRange operands) {
2348   AffineMap map = mapAttr.getValue();
2349   unsigned numDims = map.getNumDims();
2350   auto printValueName = [&](unsigned pos, bool isSymbol) {
2351     unsigned index = isSymbol ? numDims + pos : pos;
2352     assert(index < operands.size());
2353     if (isSymbol)
2354       os << "symbol(";
2355     printValueID(operands[index]);
2356     if (isSymbol)
2357       os << ')';
2358   };
2359 
2360   interleaveComma(map.getResults(), [&](AffineExpr expr) {
2361     printAffineExpr(expr, printValueName);
2362   });
2363 }
2364 
2365 //===----------------------------------------------------------------------===//
2366 // print and dump methods
2367 //===----------------------------------------------------------------------===//
2368 
2369 void Attribute::print(raw_ostream &os) const {
2370   ModulePrinter(os).printAttribute(*this);
2371 }
2372 
2373 void Attribute::dump() const {
2374   print(llvm::errs());
2375   llvm::errs() << "\n";
2376 }
2377 
2378 void Type::print(raw_ostream &os) { ModulePrinter(os).printType(*this); }
2379 
2380 void Type::dump() { print(llvm::errs()); }
2381 
2382 void AffineMap::dump() const {
2383   print(llvm::errs());
2384   llvm::errs() << "\n";
2385 }
2386 
2387 void IntegerSet::dump() const {
2388   print(llvm::errs());
2389   llvm::errs() << "\n";
2390 }
2391 
2392 void AffineExpr::print(raw_ostream &os) const {
2393   if (!expr) {
2394     os << "<<NULL AFFINE EXPR>>";
2395     return;
2396   }
2397   ModulePrinter(os).printAffineExpr(*this);
2398 }
2399 
2400 void AffineExpr::dump() const {
2401   print(llvm::errs());
2402   llvm::errs() << "\n";
2403 }
2404 
2405 void AffineMap::print(raw_ostream &os) const {
2406   if (!map) {
2407     os << "<<NULL AFFINE MAP>>";
2408     return;
2409   }
2410   ModulePrinter(os).printAffineMap(*this);
2411 }
2412 
2413 void IntegerSet::print(raw_ostream &os) const {
2414   ModulePrinter(os).printIntegerSet(*this);
2415 }
2416 
2417 void Value::print(raw_ostream &os) {
2418   if (auto *op = getDefiningOp())
2419     return op->print(os);
2420   // TODO: Improve this.
2421   assert(isa<BlockArgument>());
2422   os << "<block argument>\n";
2423 }
2424 void Value::print(raw_ostream &os, AsmState &state) {
2425   if (auto *op = getDefiningOp())
2426     return op->print(os, state);
2427 
2428   // TODO: Improve this.
2429   assert(isa<BlockArgument>());
2430   os << "<block argument>\n";
2431 }
2432 
2433 void Value::dump() {
2434   print(llvm::errs());
2435   llvm::errs() << "\n";
2436 }
2437 
2438 void Value::printAsOperand(raw_ostream &os, AsmState &state) {
2439   // TODO(riverriddle) This doesn't necessarily capture all potential cases.
2440   // Currently, region arguments can be shadowed when printing the main
2441   // operation. If the IR hasn't been printed, this will produce the old SSA
2442   // name and not the shadowed name.
2443   state.getImpl().getSSANameState().printValueID(*this, /*printResultNo=*/true,
2444                                                  os);
2445 }
2446 
2447 void Operation::print(raw_ostream &os, OpPrintingFlags flags) {
2448   // Find the operation to number from based upon the provided flags.
2449   Operation *printedOp = this;
2450   bool shouldUseLocalScope = flags.shouldUseLocalScope();
2451   do {
2452     // If we are printing local scope, stop at the first operation that is
2453     // isolated from above.
2454     if (shouldUseLocalScope && printedOp->isKnownIsolatedFromAbove())
2455       break;
2456 
2457     // Otherwise, traverse up to the next parent.
2458     Operation *parentOp = printedOp->getParentOp();
2459     if (!parentOp)
2460       break;
2461     printedOp = parentOp;
2462   } while (true);
2463 
2464   AsmState state(printedOp);
2465   print(os, state, flags);
2466 }
2467 void Operation::print(raw_ostream &os, AsmState &state, OpPrintingFlags flags) {
2468   OperationPrinter(os, flags, state.getImpl()).print(this);
2469 }
2470 
2471 void Operation::dump() {
2472   print(llvm::errs(), OpPrintingFlags().useLocalScope());
2473   llvm::errs() << "\n";
2474 }
2475 
2476 void Block::print(raw_ostream &os) {
2477   Operation *parentOp = getParentOp();
2478   if (!parentOp) {
2479     os << "<<UNLINKED BLOCK>>\n";
2480     return;
2481   }
2482   // Get the top-level op.
2483   while (auto *nextOp = parentOp->getParentOp())
2484     parentOp = nextOp;
2485 
2486   AsmState state(parentOp);
2487   print(os, state);
2488 }
2489 void Block::print(raw_ostream &os, AsmState &state) {
2490   OperationPrinter(os, /*flags=*/llvm::None, state.getImpl()).print(this);
2491 }
2492 
2493 void Block::dump() { print(llvm::errs()); }
2494 
2495 /// Print out the name of the block without printing its body.
2496 void Block::printAsOperand(raw_ostream &os, bool printType) {
2497   Operation *parentOp = getParentOp();
2498   if (!parentOp) {
2499     os << "<<UNLINKED BLOCK>>\n";
2500     return;
2501   }
2502   AsmState state(parentOp);
2503   printAsOperand(os, state);
2504 }
2505 void Block::printAsOperand(raw_ostream &os, AsmState &state) {
2506   OperationPrinter printer(os, /*flags=*/llvm::None, state.getImpl());
2507   printer.printBlockName(this);
2508 }
2509 
2510 void ModuleOp::print(raw_ostream &os, OpPrintingFlags flags) {
2511   AsmState state(*this);
2512 
2513   // Don't populate aliases when printing at local scope.
2514   if (!flags.shouldUseLocalScope())
2515     state.getImpl().initializeAliases(*this);
2516   print(os, state, flags);
2517 }
2518 void ModuleOp::print(raw_ostream &os, AsmState &state, OpPrintingFlags flags) {
2519   OperationPrinter(os, flags, state.getImpl()).print(*this);
2520 }
2521 
2522 void ModuleOp::dump() { print(llvm::errs()); }
2523