@@ -77,6 +77,10 @@ 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+
8084llvm::cl::opt<bool > SILPrintGenericSpecializationInfo (
8185 " sil-print-generic-specialization-info" , llvm::cl::init(false ),
8286 llvm::cl::desc(" Include generic specialization"
@@ -165,31 +169,34 @@ struct SILValuePrinterInfo {
165169 bool IsCapture = false ;
166170 bool IsReborrow = false ;
167171 bool IsEscaping = false ;
172+ bool needPrintType = false ;
168173
169174 SILValuePrinterInfo (ID ValueID) : ValueID(ValueID), Type(), OwnershipKind() {}
170- SILValuePrinterInfo (ID ValueID, SILType Type)
171- : ValueID(ValueID), Type(Type), OwnershipKind() {}
175+ SILValuePrinterInfo (ID ValueID, SILType Type, bool needPrintType )
176+ : ValueID(ValueID), Type(Type), OwnershipKind(), needPrintType(needPrintType) {}
172177 SILValuePrinterInfo (ID ValueID, SILType Type,
173178 ValueOwnershipKind OwnershipKind)
174179 : ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind) {}
175180 SILValuePrinterInfo (ID ValueID, SILType Type,
176181 ValueOwnershipKind OwnershipKind, bool IsNoImplicitCopy,
177182 LifetimeAnnotation Lifetime, bool IsCapture,
178- bool IsReborrow, bool IsEscaping)
183+ bool IsReborrow, bool IsEscaping, bool needPrintType )
179184 : ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
180185 IsNoImplicitCopy (IsNoImplicitCopy), Lifetime(Lifetime),
181- IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
186+ IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
187+ needPrintType(needPrintType){}
182188 SILValuePrinterInfo (ID ValueID, SILType Type, bool IsNoImplicitCopy,
183189 LifetimeAnnotation Lifetime, bool IsCapture,
184- bool IsReborrow, bool IsEscaping)
190+ bool IsReborrow, bool IsEscaping, bool needPrintType )
185191 : ValueID(ValueID), Type(Type), OwnershipKind(),
186192 IsNoImplicitCopy(IsNoImplicitCopy), Lifetime(Lifetime),
187- IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
193+ IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
194+ needPrintType(needPrintType) {}
188195 SILValuePrinterInfo (ID ValueID, SILType Type,
189196 ValueOwnershipKind OwnershipKind, bool IsReborrow,
190- bool IsEscaping)
197+ bool IsEscaping, bool needPrintType )
191198 : ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
192- IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
199+ IsReborrow(IsReborrow), IsEscaping(IsEscaping), needPrintType(needPrintType) {}
193200};
194201
195202// / Return the fully qualified dotted path for DeclContext.
@@ -656,6 +663,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
656663 } PrintState;
657664 LineComments lineComments;
658665 unsigned LastBufferID;
666+ llvm::DenseSet<const SILBasicBlock *> printedBlocks;
659667
660668 // Printers for the underlying stream.
661669#define SIMPLE_PRINTER (TYPE ) \
@@ -684,29 +692,57 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
684692 *this << i.ValueID ;
685693 if (!i.Type )
686694 return *this ;
687- *this << " : " ;
688- if (i.IsNoImplicitCopy )
689- *this << " @noImplicitCopy " ;
695+ const char *separator = " : " ;
696+ if (i.IsNoImplicitCopy ) {
697+ *this << separator << " @noImplicitCopy" ;
698+ separator = " " ;
699+ }
690700 switch (i.Lifetime ) {
691701 case LifetimeAnnotation::EagerMove:
692- *this << " @_eagerMove " ;
702+ *this << separator << " @_eagerMove" ;
703+ separator = " " ;
693704 break ;
694705 case LifetimeAnnotation::None:
695706 break ;
696707 case LifetimeAnnotation::Lexical:
697- *this << " @_lexical " ;
708+ *this << separator << " @_lexical" ;
709+ separator = " " ;
698710 break ;
699711 }
700- if (i.IsCapture )
701- *this << " @closureCapture " ;
702- if (i.IsReborrow )
703- *this << " @reborrow " ;
704- if (i.IsEscaping )
705- *this << " @pointer_escape " ;
712+ if (i.IsCapture ) {
713+ *this << separator << " @closureCapture" ;
714+ separator = " " ;
715+ }
716+ if (i.IsReborrow ) {
717+ *this << separator << " @reborrow" ;
718+ separator = " " ;
719+ }
720+ if (i.IsEscaping ) {
721+ *this << separator << " @pointer_escape" ;
722+ separator = " " ;
723+ }
706724 if (!i.IsReborrow && i.OwnershipKind && *i.OwnershipKind != OwnershipKind::None) {
707- *this << " @" << i.OwnershipKind .value () << " " ;
725+ *this << separator << " @" << i.OwnershipKind .value () << " " ;
726+ separator = " " ;
727+ }
728+ if (i.needPrintType ) {
729+ *this << separator << i.Type ;
708730 }
709- return *this << i.Type ;
731+ return *this ;
732+ }
733+
734+ bool needPrintTypeFor (SILValue V) {
735+ if (SILPrintTypes)
736+ return true ;
737+
738+ if (!V)
739+ return false ;
740+
741+ if (isa<SILUndef>(V))
742+ return true ;
743+
744+ // Make sure to print the type if the operand's definition was not printed so far
745+ return printedBlocks.count (V->getParentBlock ()) == 0 ;
710746 }
711747
712748 SILPrinter &operator <<(Type t) {
@@ -733,13 +769,20 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
733769 }
734770
735771 SILValuePrinterInfo getIDAndType (SILValue V) {
736- return {Ctx.getID (V), V ? V->getType () : SILType ()};
772+ return {Ctx.getID (V), V ? V->getType () : SILType (), needPrintTypeFor (V) };
737773 }
774+ SILValuePrinterInfo getIDAndForcedPrintedType (SILValue V) {
775+ return {Ctx.getID (V), V ? V->getType () : SILType (), /* needPrintType=*/ true };
776+ }
777+
738778 SILValuePrinterInfo getIDAndType (SILFunctionArgument *arg) {
739779 return {Ctx.getID (arg), arg->getType (),
740780 arg->isNoImplicitCopy (), arg->getLifetimeAnnotation (),
741781 arg->isClosureCapture (), arg->isReborrow (),
742- arg->hasPointerEscape ()};
782+ arg->hasPointerEscape (), /* needPrintType=*/ true };
783+ }
784+ SILValuePrinterInfo getIDAndType (SILArgument *arg) {
785+ return {Ctx.getID (arg), arg->getType (), /* needPrintType=*/ true };
743786 }
744787
745788 SILValuePrinterInfo getIDAndTypeAndOwnership (SILValue V) {
@@ -753,11 +796,13 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
753796 arg->getLifetimeAnnotation (),
754797 arg->isClosureCapture (),
755798 arg->isReborrow (),
756- arg->hasPointerEscape ()};
799+ arg->hasPointerEscape (),
800+ /* needPrintType=*/ true };
757801 }
758802 SILValuePrinterInfo getIDAndTypeAndOwnership (SILArgument *arg) {
759803 return {Ctx.getID (arg), arg->getType (), arg->getOwnershipKind (),
760- arg->isReborrow (), arg->hasPointerEscape ()};
804+ arg->isReborrow (), arg->hasPointerEscape (),
805+ /* needPrintType=*/ true };
761806 }
762807
763808 // ===--------------------------------------------------------------------===//
@@ -880,6 +925,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
880925#endif
881926
882927 void print (const SILBasicBlock *BB) {
928+ printedBlocks.insert (BB);
929+
883930 // Output uses for BB arguments. These are put into place as comments before
884931 // the block header.
885932 printBlockArgumentUses (BB);
@@ -2464,7 +2511,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
24642511 PrintState.OS , QualifiedSILTypeOptions);
24652512 if (!WMI->getTypeDependentOperands ().empty ()) {
24662513 *this << " , " ;
2467- *this << getIDAndType (WMI->getTypeDependentOperands ()[0 ].get ());
2514+ *this << getIDAndForcedPrintedType (WMI->getTypeDependentOperands ()[0 ].get ());
24682515 }
24692516 *this << " : " << WMI->getType ();
24702517 printConformances ({WMI->getConformance ()});
@@ -2505,7 +2552,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
25052552 printConformances (AEI->getConformances ());
25062553 }
25072554 void visitInitExistentialRefInst (InitExistentialRefInst *AEI) {
2508- *this << getIDAndType (AEI->getOperand ()) << " : $"
2555+ *this << getIDAndForcedPrintedType (AEI->getOperand ()) << " : $"
25092556 << AEI->getFormalConcreteType () << " , " << AEI->getType ();
25102557 printConformances (AEI->getConformances ());
25112558 printForwardingOwnershipKind (AEI, AEI->getOperand ());
0 commit comments