@@ -77,6 +77,10 @@ llvm::cl::opt<bool>
77
77
SILPrintSourceInfo (" sil-print-sourceinfo" , llvm::cl::init(false ),
78
78
llvm::cl::desc(" Include source annotation in SIL output" ));
79
79
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
+
80
84
llvm::cl::opt<bool > SILPrintGenericSpecializationInfo (
81
85
" sil-print-generic-specialization-info" , llvm::cl::init(false ),
82
86
llvm::cl::desc(" Include generic specialization"
@@ -165,31 +169,34 @@ struct SILValuePrinterInfo {
165
169
bool IsCapture = false ;
166
170
bool IsReborrow = false ;
167
171
bool IsEscaping = false ;
172
+ bool needPrintType = false ;
168
173
169
174
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) {}
172
177
SILValuePrinterInfo (ID ValueID, SILType Type,
173
178
ValueOwnershipKind OwnershipKind)
174
179
: ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind) {}
175
180
SILValuePrinterInfo (ID ValueID, SILType Type,
176
181
ValueOwnershipKind OwnershipKind, bool IsNoImplicitCopy,
177
182
LifetimeAnnotation Lifetime, bool IsCapture,
178
- bool IsReborrow, bool IsEscaping)
183
+ bool IsReborrow, bool IsEscaping, bool needPrintType )
179
184
: ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
180
185
IsNoImplicitCopy (IsNoImplicitCopy), Lifetime(Lifetime),
181
- IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
186
+ IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
187
+ needPrintType(needPrintType){}
182
188
SILValuePrinterInfo (ID ValueID, SILType Type, bool IsNoImplicitCopy,
183
189
LifetimeAnnotation Lifetime, bool IsCapture,
184
- bool IsReborrow, bool IsEscaping)
190
+ bool IsReborrow, bool IsEscaping, bool needPrintType )
185
191
: ValueID(ValueID), Type(Type), OwnershipKind(),
186
192
IsNoImplicitCopy(IsNoImplicitCopy), Lifetime(Lifetime),
187
- IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
193
+ IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
194
+ needPrintType(needPrintType) {}
188
195
SILValuePrinterInfo (ID ValueID, SILType Type,
189
196
ValueOwnershipKind OwnershipKind, bool IsReborrow,
190
- bool IsEscaping)
197
+ bool IsEscaping, bool needPrintType )
191
198
: ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
192
- IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
199
+ IsReborrow(IsReborrow), IsEscaping(IsEscaping), needPrintType(needPrintType) {}
193
200
};
194
201
195
202
// / Return the fully qualified dotted path for DeclContext.
@@ -656,6 +663,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
656
663
} PrintState;
657
664
LineComments lineComments;
658
665
unsigned LastBufferID;
666
+ llvm::DenseSet<const SILBasicBlock *> printedBlocks;
659
667
660
668
// Printers for the underlying stream.
661
669
#define SIMPLE_PRINTER (TYPE ) \
@@ -684,29 +692,57 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
684
692
*this << i.ValueID ;
685
693
if (!i.Type )
686
694
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
+ }
690
700
switch (i.Lifetime ) {
691
701
case LifetimeAnnotation::EagerMove:
692
- *this << " @_eagerMove " ;
702
+ *this << separator << " @_eagerMove" ;
703
+ separator = " " ;
693
704
break ;
694
705
case LifetimeAnnotation::None:
695
706
break ;
696
707
case LifetimeAnnotation::Lexical:
697
- *this << " @_lexical " ;
708
+ *this << separator << " @_lexical" ;
709
+ separator = " " ;
698
710
break ;
699
711
}
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
+ }
706
724
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 ;
708
730
}
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 ;
710
746
}
711
747
712
748
SILPrinter &operator <<(Type t) {
@@ -733,13 +769,20 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
733
769
}
734
770
735
771
SILValuePrinterInfo getIDAndType (SILValue V) {
736
- return {Ctx.getID (V), V ? V->getType () : SILType ()};
772
+ return {Ctx.getID (V), V ? V->getType () : SILType (), needPrintTypeFor (V) };
737
773
}
774
+ SILValuePrinterInfo getIDAndForcedPrintedType (SILValue V) {
775
+ return {Ctx.getID (V), V ? V->getType () : SILType (), /* needPrintType=*/ true };
776
+ }
777
+
738
778
SILValuePrinterInfo getIDAndType (SILFunctionArgument *arg) {
739
779
return {Ctx.getID (arg), arg->getType (),
740
780
arg->isNoImplicitCopy (), arg->getLifetimeAnnotation (),
741
781
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 };
743
786
}
744
787
745
788
SILValuePrinterInfo getIDAndTypeAndOwnership (SILValue V) {
@@ -753,11 +796,13 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
753
796
arg->getLifetimeAnnotation (),
754
797
arg->isClosureCapture (),
755
798
arg->isReborrow (),
756
- arg->hasPointerEscape ()};
799
+ arg->hasPointerEscape (),
800
+ /* needPrintType=*/ true };
757
801
}
758
802
SILValuePrinterInfo getIDAndTypeAndOwnership (SILArgument *arg) {
759
803
return {Ctx.getID (arg), arg->getType (), arg->getOwnershipKind (),
760
- arg->isReborrow (), arg->hasPointerEscape ()};
804
+ arg->isReborrow (), arg->hasPointerEscape (),
805
+ /* needPrintType=*/ true };
761
806
}
762
807
763
808
// ===--------------------------------------------------------------------===//
@@ -880,6 +925,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
880
925
#endif
881
926
882
927
void print (const SILBasicBlock *BB) {
928
+ printedBlocks.insert (BB);
929
+
883
930
// Output uses for BB arguments. These are put into place as comments before
884
931
// the block header.
885
932
printBlockArgumentUses (BB);
@@ -2464,7 +2511,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
2464
2511
PrintState.OS , QualifiedSILTypeOptions);
2465
2512
if (!WMI->getTypeDependentOperands ().empty ()) {
2466
2513
*this << " , " ;
2467
- *this << getIDAndType (WMI->getTypeDependentOperands ()[0 ].get ());
2514
+ *this << getIDAndForcedPrintedType (WMI->getTypeDependentOperands ()[0 ].get ());
2468
2515
}
2469
2516
*this << " : " << WMI->getType ();
2470
2517
printConformances ({WMI->getConformance ()});
@@ -2505,7 +2552,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
2505
2552
printConformances (AEI->getConformances ());
2506
2553
}
2507
2554
void visitInitExistentialRefInst (InitExistentialRefInst *AEI) {
2508
- *this << getIDAndType (AEI->getOperand ()) << " : $"
2555
+ *this << getIDAndForcedPrintedType (AEI->getOperand ()) << " : $"
2509
2556
<< AEI->getFormalConcreteType () << " , " << AEI->getType ();
2510
2557
printConformances (AEI->getConformances ());
2511
2558
printForwardingOwnershipKind (AEI, AEI->getOperand ());
0 commit comments