@@ -77,6 +77,14 @@ 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
+
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
+
80
88
llvm::cl::opt<bool > SILPrintGenericSpecializationInfo (
81
89
" sil-print-generic-specialization-info" , llvm::cl::init(false ),
82
90
llvm::cl::desc(" Include generic specialization"
@@ -165,31 +173,34 @@ struct SILValuePrinterInfo {
165
173
bool IsCapture = false ;
166
174
bool IsReborrow = false ;
167
175
bool IsEscaping = false ;
176
+ bool needPrintType = false ;
168
177
169
178
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) {}
172
181
SILValuePrinterInfo (ID ValueID, SILType Type,
173
182
ValueOwnershipKind OwnershipKind)
174
183
: ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind) {}
175
184
SILValuePrinterInfo (ID ValueID, SILType Type,
176
185
ValueOwnershipKind OwnershipKind, bool IsNoImplicitCopy,
177
186
LifetimeAnnotation Lifetime, bool IsCapture,
178
- bool IsReborrow, bool IsEscaping)
187
+ bool IsReborrow, bool IsEscaping, bool needPrintType )
179
188
: ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
180
189
IsNoImplicitCopy (IsNoImplicitCopy), Lifetime(Lifetime),
181
- IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
190
+ IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
191
+ needPrintType(needPrintType){}
182
192
SILValuePrinterInfo (ID ValueID, SILType Type, bool IsNoImplicitCopy,
183
193
LifetimeAnnotation Lifetime, bool IsCapture,
184
- bool IsReborrow, bool IsEscaping)
194
+ bool IsReborrow, bool IsEscaping, bool needPrintType )
185
195
: ValueID(ValueID), Type(Type), OwnershipKind(),
186
196
IsNoImplicitCopy(IsNoImplicitCopy), Lifetime(Lifetime),
187
- IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
197
+ IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
198
+ needPrintType(needPrintType) {}
188
199
SILValuePrinterInfo (ID ValueID, SILType Type,
189
200
ValueOwnershipKind OwnershipKind, bool IsReborrow,
190
- bool IsEscaping)
201
+ bool IsEscaping, bool needPrintType )
191
202
: ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
192
- IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
203
+ IsReborrow(IsReborrow), IsEscaping(IsEscaping), needPrintType(needPrintType) {}
193
204
};
194
205
195
206
// / Return the fully qualified dotted path for DeclContext.
@@ -656,6 +667,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
656
667
} PrintState;
657
668
LineComments lineComments;
658
669
unsigned LastBufferID;
670
+ llvm::DenseSet<const SILBasicBlock *> printedBlocks;
659
671
660
672
// Printers for the underlying stream.
661
673
#define SIMPLE_PRINTER (TYPE ) \
@@ -684,29 +696,57 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
684
696
*this << i.ValueID ;
685
697
if (!i.Type )
686
698
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
+ }
690
704
switch (i.Lifetime ) {
691
705
case LifetimeAnnotation::EagerMove:
692
- *this << " @_eagerMove " ;
706
+ *this << separator << " @_eagerMove" ;
707
+ separator = " " ;
693
708
break ;
694
709
case LifetimeAnnotation::None:
695
710
break ;
696
711
case LifetimeAnnotation::Lexical:
697
- *this << " @_lexical " ;
712
+ *this << separator << " @_lexical" ;
713
+ separator = " " ;
698
714
break ;
699
715
}
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
+ }
706
728
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 ;
708
734
}
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 ;
710
750
}
711
751
712
752
SILPrinter &operator <<(Type t) {
@@ -733,13 +773,20 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
733
773
}
734
774
735
775
SILValuePrinterInfo getIDAndType (SILValue V) {
736
- return {Ctx.getID (V), V ? V->getType () : SILType ()};
776
+ return {Ctx.getID (V), V ? V->getType () : SILType (), needPrintTypeFor (V) };
737
777
}
778
+ SILValuePrinterInfo getIDAndForcedPrintedType (SILValue V) {
779
+ return {Ctx.getID (V), V ? V->getType () : SILType (), /* needPrintType=*/ true };
780
+ }
781
+
738
782
SILValuePrinterInfo getIDAndType (SILFunctionArgument *arg) {
739
783
return {Ctx.getID (arg), arg->getType (),
740
784
arg->isNoImplicitCopy (), arg->getLifetimeAnnotation (),
741
785
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 };
743
790
}
744
791
745
792
SILValuePrinterInfo getIDAndTypeAndOwnership (SILValue V) {
@@ -753,11 +800,13 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
753
800
arg->getLifetimeAnnotation (),
754
801
arg->isClosureCapture (),
755
802
arg->isReborrow (),
756
- arg->hasPointerEscape ()};
803
+ arg->hasPointerEscape (),
804
+ /* needPrintType=*/ true };
757
805
}
758
806
SILValuePrinterInfo getIDAndTypeAndOwnership (SILArgument *arg) {
759
807
return {Ctx.getID (arg), arg->getType (), arg->getOwnershipKind (),
760
- arg->isReborrow (), arg->hasPointerEscape ()};
808
+ arg->isReborrow (), arg->hasPointerEscape (),
809
+ /* needPrintType=*/ true };
761
810
}
762
811
763
812
// ===--------------------------------------------------------------------===//
@@ -783,6 +832,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
783
832
}
784
833
785
834
void printBlockArgumentUses (const SILBasicBlock *BB) {
835
+ if (SILPrintNoUses)
836
+ return ;
837
+
786
838
if (BB->args_empty ())
787
839
return ;
788
840
@@ -880,6 +932,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
880
932
#endif
881
933
882
934
void print (const SILBasicBlock *BB) {
935
+ printedBlocks.insert (BB);
936
+
883
937
// Output uses for BB arguments. These are put into place as comments before
884
938
// the block header.
885
939
printBlockArgumentUses (BB);
@@ -895,7 +949,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
895
949
printBlockArguments (BB);
896
950
*this << " :" ;
897
951
898
- if (!BB->pred_empty ()) {
952
+ if (!BB->pred_empty () && !SILPrintNoUses ) {
899
953
PrintState.OS .PadToColumn (50 );
900
954
901
955
*this << " // Preds:" ;
@@ -985,6 +1039,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
985
1039
}
986
1040
987
1041
void printUserList (ArrayRef<SILValue> values, SILNodePointer node) {
1042
+ if (SILPrintNoUses)
1043
+ return ;
1044
+
988
1045
// If the set of values is empty, we need to print the ID of
989
1046
// the instruction. Otherwise, if none of the values has a use,
990
1047
// we don't need to do anything.
@@ -2464,7 +2521,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
2464
2521
PrintState.OS , QualifiedSILTypeOptions);
2465
2522
if (!WMI->getTypeDependentOperands ().empty ()) {
2466
2523
*this << " , " ;
2467
- *this << getIDAndType (WMI->getTypeDependentOperands ()[0 ].get ());
2524
+ *this << getIDAndForcedPrintedType (WMI->getTypeDependentOperands ()[0 ].get ());
2468
2525
}
2469
2526
*this << " : " << WMI->getType ();
2470
2527
printConformances ({WMI->getConformance ()});
@@ -2505,7 +2562,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
2505
2562
printConformances (AEI->getConformances ());
2506
2563
}
2507
2564
void visitInitExistentialRefInst (InitExistentialRefInst *AEI) {
2508
- *this << getIDAndType (AEI->getOperand ()) << " : $"
2565
+ *this << getIDAndForcedPrintedType (AEI->getOperand ()) << " : $"
2509
2566
<< AEI->getFormalConcreteType () << " , " << AEI->getType ();
2510
2567
printConformances (AEI->getConformances ());
2511
2568
printForwardingOwnershipKind (AEI, AEI->getOperand ());
0 commit comments