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