@@ -77,6 +77,14 @@ llvm::cl::opt<bool>
7777SILPrintSourceInfo (" sil-print-sourceinfo" , llvm::cl::init(false ),
7878 llvm::cl::desc(" Include source annotation in SIL output" ));
7979
80+ llvm::cl::opt<bool >
81+ SILPrintTypes (" sil-print-types" , llvm::cl::init(false ),
82+ llvm::cl::desc(" always print type annotations for instruction operands in SIL output" ));
83+
84+ llvm::cl::opt<bool >
85+ SILPrintNoUses (" sil-print-no-uses" , llvm::cl::init(false ),
86+ llvm::cl::desc(" omit use comments in SIL output" ));
87+
8088llvm::cl::opt<bool > SILPrintGenericSpecializationInfo (
8189 " sil-print-generic-specialization-info" , llvm::cl::init(false ),
8290 llvm::cl::desc(" Include generic specialization"
@@ -165,31 +173,34 @@ struct SILValuePrinterInfo {
165173 bool IsCapture = false ;
166174 bool IsReborrow = false ;
167175 bool IsEscaping = false ;
176+ bool needPrintType = false ;
168177
169178 SILValuePrinterInfo (ID ValueID) : ValueID(ValueID), Type(), OwnershipKind() {}
170- SILValuePrinterInfo (ID ValueID, SILType Type)
171- : ValueID(ValueID), Type(Type), OwnershipKind() {}
179+ SILValuePrinterInfo (ID ValueID, SILType Type, bool needPrintType )
180+ : ValueID(ValueID), Type(Type), OwnershipKind(), needPrintType(needPrintType) {}
172181 SILValuePrinterInfo (ID ValueID, SILType Type,
173182 ValueOwnershipKind OwnershipKind)
174183 : ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind) {}
175184 SILValuePrinterInfo (ID ValueID, SILType Type,
176185 ValueOwnershipKind OwnershipKind, bool IsNoImplicitCopy,
177186 LifetimeAnnotation Lifetime, bool IsCapture,
178- bool IsReborrow, bool IsEscaping)
187+ bool IsReborrow, bool IsEscaping, bool needPrintType )
179188 : ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
180189 IsNoImplicitCopy (IsNoImplicitCopy), Lifetime(Lifetime),
181- IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
190+ IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
191+ needPrintType(needPrintType){}
182192 SILValuePrinterInfo (ID ValueID, SILType Type, bool IsNoImplicitCopy,
183193 LifetimeAnnotation Lifetime, bool IsCapture,
184- bool IsReborrow, bool IsEscaping)
194+ bool IsReborrow, bool IsEscaping, bool needPrintType )
185195 : ValueID(ValueID), Type(Type), OwnershipKind(),
186196 IsNoImplicitCopy(IsNoImplicitCopy), Lifetime(Lifetime),
187- IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
197+ IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
198+ needPrintType(needPrintType) {}
188199 SILValuePrinterInfo (ID ValueID, SILType Type,
189200 ValueOwnershipKind OwnershipKind, bool IsReborrow,
190- bool IsEscaping)
201+ bool IsEscaping, bool needPrintType )
191202 : ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
192- IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
203+ IsReborrow(IsReborrow), IsEscaping(IsEscaping), needPrintType(needPrintType) {}
193204};
194205
195206// / Return the fully qualified dotted path for DeclContext.
@@ -656,6 +667,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
656667 } PrintState;
657668 LineComments lineComments;
658669 unsigned LastBufferID;
670+ llvm::DenseSet<const SILBasicBlock *> printedBlocks;
659671
660672 // Printers for the underlying stream.
661673#define SIMPLE_PRINTER (TYPE ) \
@@ -684,29 +696,57 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
684696 *this << i.ValueID ;
685697 if (!i.Type )
686698 return *this ;
687- *this << " : " ;
688- if (i.IsNoImplicitCopy )
689- *this << " @noImplicitCopy " ;
699+ const char *separator = " : " ;
700+ if (i.IsNoImplicitCopy ) {
701+ *this << separator << " @noImplicitCopy" ;
702+ separator = " " ;
703+ }
690704 switch (i.Lifetime ) {
691705 case LifetimeAnnotation::EagerMove:
692- *this << " @_eagerMove " ;
706+ *this << separator << " @_eagerMove" ;
707+ separator = " " ;
693708 break ;
694709 case LifetimeAnnotation::None:
695710 break ;
696711 case LifetimeAnnotation::Lexical:
697- *this << " @_lexical " ;
712+ *this << separator << " @_lexical" ;
713+ separator = " " ;
698714 break ;
699715 }
700- if (i.IsCapture )
701- *this << " @closureCapture " ;
702- if (i.IsReborrow )
703- *this << " @reborrow " ;
704- if (i.IsEscaping )
705- *this << " @pointer_escape " ;
716+ if (i.IsCapture ) {
717+ *this << separator << " @closureCapture" ;
718+ separator = " " ;
719+ }
720+ if (i.IsReborrow ) {
721+ *this << separator << " @reborrow" ;
722+ separator = " " ;
723+ }
724+ if (i.IsEscaping ) {
725+ *this << separator << " @pointer_escape" ;
726+ separator = " " ;
727+ }
706728 if (!i.IsReborrow && i.OwnershipKind && *i.OwnershipKind != OwnershipKind::None) {
707- *this << " @" << i.OwnershipKind .value () << " " ;
729+ *this << separator << " @" << i.OwnershipKind .value () << " " ;
730+ separator = " " ;
731+ }
732+ if (i.needPrintType ) {
733+ *this << separator << i.Type ;
708734 }
709- return *this << i.Type ;
735+ return *this ;
736+ }
737+
738+ bool needPrintTypeFor (SILValue V) {
739+ if (SILPrintTypes)
740+ return true ;
741+
742+ if (!V)
743+ return false ;
744+
745+ if (isa<SILUndef>(V))
746+ return true ;
747+
748+ // Make sure to print the type if the operand's definition was not printed so far
749+ return printedBlocks.count (V->getParentBlock ()) == 0 ;
710750 }
711751
712752 SILPrinter &operator <<(Type t) {
@@ -733,13 +773,20 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
733773 }
734774
735775 SILValuePrinterInfo getIDAndType (SILValue V) {
736- return {Ctx.getID (V), V ? V->getType () : SILType ()};
776+ return {Ctx.getID (V), V ? V->getType () : SILType (), needPrintTypeFor (V) };
737777 }
778+ SILValuePrinterInfo getIDAndForcedPrintedType (SILValue V) {
779+ return {Ctx.getID (V), V ? V->getType () : SILType (), /* needPrintType=*/ true };
780+ }
781+
738782 SILValuePrinterInfo getIDAndType (SILFunctionArgument *arg) {
739783 return {Ctx.getID (arg), arg->getType (),
740784 arg->isNoImplicitCopy (), arg->getLifetimeAnnotation (),
741785 arg->isClosureCapture (), arg->isReborrow (),
742- arg->hasPointerEscape ()};
786+ arg->hasPointerEscape (), /* needPrintType=*/ true };
787+ }
788+ SILValuePrinterInfo getIDAndType (SILArgument *arg) {
789+ return {Ctx.getID (arg), arg->getType (), /* needPrintType=*/ true };
743790 }
744791
745792 SILValuePrinterInfo getIDAndTypeAndOwnership (SILValue V) {
@@ -753,11 +800,13 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
753800 arg->getLifetimeAnnotation (),
754801 arg->isClosureCapture (),
755802 arg->isReborrow (),
756- arg->hasPointerEscape ()};
803+ arg->hasPointerEscape (),
804+ /* needPrintType=*/ true };
757805 }
758806 SILValuePrinterInfo getIDAndTypeAndOwnership (SILArgument *arg) {
759807 return {Ctx.getID (arg), arg->getType (), arg->getOwnershipKind (),
760- arg->isReborrow (), arg->hasPointerEscape ()};
808+ arg->isReborrow (), arg->hasPointerEscape (),
809+ /* needPrintType=*/ true };
761810 }
762811
763812 // ===--------------------------------------------------------------------===//
@@ -783,6 +832,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
783832 }
784833
785834 void printBlockArgumentUses (const SILBasicBlock *BB) {
835+ if (SILPrintNoUses)
836+ return ;
837+
786838 if (BB->args_empty ())
787839 return ;
788840
@@ -880,6 +932,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
880932#endif
881933
882934 void print (const SILBasicBlock *BB) {
935+ printedBlocks.insert (BB);
936+
883937 // Output uses for BB arguments. These are put into place as comments before
884938 // the block header.
885939 printBlockArgumentUses (BB);
@@ -895,7 +949,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
895949 printBlockArguments (BB);
896950 *this << " :" ;
897951
898- if (!BB->pred_empty ()) {
952+ if (!BB->pred_empty () && !SILPrintNoUses ) {
899953 PrintState.OS .PadToColumn (50 );
900954
901955 *this << " // Preds:" ;
@@ -985,6 +1039,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
9851039 }
9861040
9871041 void printUserList (ArrayRef<SILValue> values, SILNodePointer node) {
1042+ if (SILPrintNoUses)
1043+ return ;
1044+
9881045 // If the set of values is empty, we need to print the ID of
9891046 // the instruction. Otherwise, if none of the values has a use,
9901047 // we don't need to do anything.
@@ -2464,7 +2521,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
24642521 PrintState.OS , QualifiedSILTypeOptions);
24652522 if (!WMI->getTypeDependentOperands ().empty ()) {
24662523 *this << " , " ;
2467- *this << getIDAndType (WMI->getTypeDependentOperands ()[0 ].get ());
2524+ *this << getIDAndForcedPrintedType (WMI->getTypeDependentOperands ()[0 ].get ());
24682525 }
24692526 *this << " : " << WMI->getType ();
24702527 printConformances ({WMI->getConformance ()});
@@ -2505,7 +2562,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
25052562 printConformances (AEI->getConformances ());
25062563 }
25072564 void visitInitExistentialRefInst (InitExistentialRefInst *AEI) {
2508- *this << getIDAndType (AEI->getOperand ()) << " : $"
2565+ *this << getIDAndForcedPrintedType (AEI->getOperand ()) << " : $"
25092566 << AEI->getFormalConcreteType () << " , " << AEI->getType ();
25102567 printConformances (AEI->getConformances ());
25112568 printForwardingOwnershipKind (AEI, AEI->getOperand ());
0 commit comments