@@ -523,6 +523,69 @@ namespace {
523
523
524
524
class SILPrinter ;
525
525
526
+ // 1. Accumulate opcode-specific comments in this stream.
527
+ // 2. Start emitting comments: lineComments.start()
528
+ // 3. Emit each comment section: lineComments.delim()
529
+ // 4. End emitting comments: LineComments::end()
530
+ class LineComments : public raw_ostream {
531
+ llvm::formatted_raw_ostream &os;
532
+ // Opcode-specific comments to be printed at the end of the current line.
533
+ std::string opcodeCommentString;
534
+ llvm::raw_string_ostream opcodeCommentStream;
535
+ bool emitting = false ;
536
+ bool printedSlashes = false ;
537
+
538
+ public:
539
+ LineComments (llvm::formatted_raw_ostream &os)
540
+ : os(os), opcodeCommentStream(opcodeCommentString) {
541
+ SetUnbuffered (); // pass through to the underlying stream
542
+ }
543
+
544
+ // Call to start emitting line comments into the underlying stream.
545
+ void start () {
546
+ emitting = true ;
547
+ printedSlashes = false ;
548
+
549
+ if (opcodeCommentString.empty ())
550
+ return ;
551
+
552
+ delim ();
553
+ os << opcodeCommentString;
554
+ opcodeCommentString.clear ();
555
+ }
556
+ // Call for each section of line
557
+ void delim () {
558
+ assert (emitting);
559
+ if (printedSlashes) {
560
+ os << " ; " ;
561
+ } else {
562
+ os.PadToColumn (50 );
563
+ os << " // " ;
564
+ printedSlashes = true ;
565
+ }
566
+ }
567
+ void end () {
568
+ assert (emitting);
569
+ emitting = false ;
570
+ printedSlashes = false ;
571
+ os << " \n " ;
572
+ }
573
+
574
+ protected:
575
+ void write_impl (const char *ptr, size_t size) override {
576
+ if (emitting)
577
+ os.write (ptr, size);
578
+ else
579
+ opcodeCommentStream.write (ptr, size);
580
+ }
581
+ uint64_t current_pos () const override {
582
+ if (emitting)
583
+ return os.tell () - os.GetNumBytesInBuffer ();
584
+
585
+ return opcodeCommentString.size ();
586
+ }
587
+ };
588
+
526
589
// / SILPrinter class - This holds the internal implementation details of
527
590
// / printing SIL structures.
528
591
class SILPrinter : public SILInstructionVisitor <SILPrinter> {
@@ -531,6 +594,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
531
594
llvm::formatted_raw_ostream OS;
532
595
PrintOptions ASTOptions;
533
596
} PrintState;
597
+ LineComments lineComments;
534
598
unsigned LastBufferID;
535
599
536
600
// Printers for the underlying stream.
@@ -581,7 +645,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
581
645
llvm::DenseMap<CanType, Identifier> *AlternativeTypeNames = nullptr )
582
646
: Ctx(PrintCtx), PrintState{{PrintCtx.OS ()},
583
647
PrintOptions::printSIL (&PrintCtx)},
584
- LastBufferID (0 ) {
648
+ lineComments (PrintState.OS), LastBufferID(0 ) {
585
649
PrintState.ASTOptions .AlternativeTypeNames = AlternativeTypeNames;
586
650
PrintState.ASTOptions .PrintForSIL = true ;
587
651
}
@@ -755,33 +819,33 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
755
819
// ===--------------------------------------------------------------------===//
756
820
// SILInstruction Printing Logic
757
821
758
- bool printTypeDependentOperands (const SILInstruction *I) {
822
+ void printTypeDependentOperands (const SILInstruction *I) {
759
823
ArrayRef<Operand> TypeDepOps = I->getTypeDependentOperands ();
760
824
if (TypeDepOps.empty ())
761
- return false ;
825
+ return ;
762
826
763
- PrintState. OS . PadToColumn ( 50 );
764
- *this << " // type-defs: " ;
827
+ lineComments. delim ( );
828
+ *this << " type-defs: " ;
765
829
interleave (TypeDepOps,
766
830
[&](const Operand &op) { *this << Ctx.getID (op.get ()); },
767
831
[&] { *this << " , " ; });
768
- return true ;
769
832
}
770
833
771
834
// / Print out the users of the SILValue \p V. Return true if we printed out
772
835
// / either an id or a use list. Return false otherwise.
773
- bool printUsersOfValue (SILValue value, bool printedSlashes) {
774
- return printUserList ({value}, value, printedSlashes);
836
+ void printUsersOfValue (SILValue value) {
837
+ lineComments.start ();
838
+ printUserList ({value}, value);
839
+ lineComments.end ();
775
840
}
776
841
777
- bool printUsersOfInstruction (const SILInstruction *inst, bool printedSlashes ) {
842
+ void printUsersOfInstruction (const SILInstruction *inst) {
778
843
llvm::SmallVector<SILValue, 8 > values;
779
844
llvm::copy (inst->getResults (), std::back_inserter (values));
780
- return printUserList (values, inst, printedSlashes );
845
+ printUserList (values, inst);
781
846
}
782
847
783
- bool printUserList (ArrayRef<SILValue> values, SILNodePointer node,
784
- bool printedSlashes) {
848
+ void printUserList (ArrayRef<SILValue> values, SILNodePointer node) {
785
849
// If the set of values is empty, we need to print the ID of
786
850
// the instruction. Otherwise, if none of the values has a use,
787
851
// we don't need to do anything.
@@ -791,18 +855,13 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
791
855
if (!value->use_empty ()) hasUse = true ;
792
856
}
793
857
if (!hasUse)
794
- return printedSlashes ;
858
+ return ;
795
859
}
860
+ lineComments.delim ();
796
861
797
- if (printedSlashes) {
798
- *this << " ; " ;
799
- } else {
800
- PrintState.OS .PadToColumn (50 );
801
- *this << " // " ;
802
- }
803
862
if (values.empty ()) {
804
863
*this << " id: " << Ctx.getID (node);
805
- return true ;
864
+ return ;
806
865
}
807
866
808
867
llvm::SmallVector<ID, 32 > UserIDs;
@@ -825,17 +884,16 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
825
884
llvm::interleave (
826
885
UserIDs.begin (), UserIDs.end (), [&](ID id) { *this << id; },
827
886
[&] { *this << " , " ; });
828
- return true ;
829
887
}
830
888
831
889
void printConformances (ArrayRef<ProtocolConformanceRef> conformances) {
832
890
// FIXME: conformances should always be printed and parsed!
833
891
if (!Ctx.printVerbose ()) {
834
892
return ;
835
893
}
836
- * this << " // " ;
837
- for (ProtocolConformanceRef conformance : conformances)
838
- conformance. dump (PrintState. OS , /* indent */ 0 , /* details */ false );
894
+ for (ProtocolConformanceRef conformance : conformances) {
895
+ conformance. dump (lineComments, /* indent */ 0 , /* details */ false );
896
+ }
839
897
}
840
898
841
899
void printDebugLocRef (SILLocation Loc, const SourceManager &SM,
@@ -881,15 +939,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
881
939
}
882
940
}
883
941
884
- void printSILLocation (SILLocation L, SILModule &M, const SILDebugScope *DS,
885
- bool printedSlashes) {
942
+ void printSILLocation (SILLocation L, SILModule &M, const SILDebugScope *DS) {
943
+ lineComments. delim ();
886
944
if (!L.isNull ()) {
887
- if (!printedSlashes) {
888
- PrintState.OS .PadToColumn (50 );
889
- *this << " //" ;
890
- }
891
- *this << " " ;
892
-
893
945
// To minimize output, only print the line and column number for
894
946
// everything but the first instruction.
895
947
L.getSourceLoc ().printLineAndColumn (PrintState.OS ,
@@ -924,12 +976,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
924
976
*this << " :auto_gen" ;
925
977
if (L.isInPrologue ())
926
978
*this << " :in_prologue" ;
927
- }
928
- if (L.isNull ()) {
929
- if (!printedSlashes) {
930
- PrintState.OS .PadToColumn (50 );
931
- *this << " //" ;
932
- }
979
+ } else {
933
980
if (L.isAutoGenerated ())
934
981
*this << " auto_gen" ;
935
982
else
@@ -1009,25 +1056,25 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
1009
1056
visit (const_cast <SILInstruction*>(I));
1010
1057
1011
1058
// Maybe print debugging information.
1012
- bool printedSlashes = false ;
1013
1059
if (Ctx.printDebugInfo () && !I->isDeleted ()
1014
1060
&& !I->isStaticInitializerInst ()) {
1015
1061
auto &SM = I->getModule ().getASTContext ().SourceMgr ;
1016
1062
printDebugLocRef (I->getLoc (), SM);
1017
1063
printDebugScopeRef (I->getDebugScope (), SM);
1018
1064
}
1019
- printedSlashes = printTypeDependentOperands (I);
1065
+
1066
+ lineComments.start ();
1067
+
1068
+ printTypeDependentOperands (I);
1020
1069
1021
1070
// Print users, or id for valueless instructions.
1022
- printedSlashes = printUsersOfInstruction (I, printedSlashes );
1071
+ printUsersOfInstruction (I);
1023
1072
1024
1073
// Print SIL location.
1025
1074
if (Ctx.printVerbose ()) {
1026
- printSILLocation (I->getLoc (), I->getModule (), I->getDebugScope (),
1027
- printedSlashes);
1075
+ printSILLocation (I->getLoc (), I->getModule (), I->getDebugScope ());
1028
1076
}
1029
-
1030
- *this << ' \n ' ;
1077
+ lineComments.end ();
1031
1078
}
1032
1079
1033
1080
void print (const SILNode *node) {
@@ -1068,9 +1115,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
1068
1115
<< Ctx.getID (arg->getParent ()) << " : " << arg->getType ();
1069
1116
1070
1117
// Print users.
1071
- (void ) printUsersOfValue (arg, false );
1072
-
1073
- *this << ' \n ' ;
1118
+ printUsersOfValue (arg);
1074
1119
}
1075
1120
1076
1121
void printSILUndef (const SILUndef *undef) {
@@ -1105,9 +1150,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
1105
1150
visit (static_cast <SILInstruction *>(nonConstParent));
1106
1151
1107
1152
// Print users.
1108
- (void )printUsersOfValue (result, false );
1109
-
1110
- *this << ' \n ' ;
1153
+ printUsersOfValue (result);
1111
1154
}
1112
1155
1113
1156
void printInContext (const SILNode *node) {
@@ -1630,6 +1673,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
1630
1673
*this << " !true_count(" << CI->getTrueBBCount ().getValue () << " )" ;
1631
1674
if (CI->getFalseBBCount ())
1632
1675
*this << " !false_count(" << CI->getFalseBBCount ().getValue () << " )" ;
1676
+ printForwardingOwnershipKind (CI, CI->getOperand ());
1633
1677
}
1634
1678
1635
1679
void visitCheckedCastValueBranchInst (CheckedCastValueBranchInst *CI) {
@@ -2238,34 +2282,41 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
2238
2282
*this << " , default " << Ctx.getID (SII->getDefaultBB ());
2239
2283
}
2240
2284
2241
- void printSwitchEnumInst (SwitchEnumTermInst SOI ) {
2242
- *this << getIDAndType (SOI .getOperand ());
2243
- for (unsigned i = 0 , e = SOI .getNumCases (); i < e; ++i) {
2285
+ void printSwitchEnumInst (SwitchEnumTermInst switchEnum ) {
2286
+ *this << getIDAndType (switchEnum .getOperand ());
2287
+ for (unsigned i = 0 , e = switchEnum .getNumCases (); i < e; ++i) {
2244
2288
EnumElementDecl *elt;
2245
2289
SILBasicBlock *dest;
2246
- std::tie (elt, dest) = SOI .getCase (i);
2290
+ std::tie (elt, dest) = switchEnum .getCase (i);
2247
2291
*this << " , case " << SILDeclRef (elt, SILDeclRef::Kind::EnumElement)
2248
2292
<< " : " << Ctx.getID (dest);
2249
- if (SOI.getCaseCount (i)) {
2250
- *this << " !case_count(" << SOI.getCaseCount (i).getValue () << " )" ;
2293
+ if (switchEnum.getCaseCount (i)) {
2294
+ *this << " !case_count(" << switchEnum.getCaseCount (i).getValue ()
2295
+ << " )" ;
2251
2296
}
2252
2297
}
2253
- if (SOI.hasDefault ()) {
2254
- *this << " , default " << Ctx.getID (SOI.getDefaultBB ());
2255
- if (SOI.getDefaultCount ()) {
2256
- *this << " !default_count(" << SOI.getDefaultCount ().getValue () << " )" ;
2298
+ if (switchEnum.hasDefault ()) {
2299
+ *this << " , default " << Ctx.getID (switchEnum.getDefaultBB ());
2300
+ if (switchEnum.getDefaultCount ()) {
2301
+ *this << " !default_count(" << switchEnum.getDefaultCount ().getValue ()
2302
+ << " )" ;
2303
+ }
2304
+ if (NullablePtr<EnumElementDecl> uniqueCase =
2305
+ switchEnum.getUniqueCaseForDefault ()) {
2306
+ lineComments << SILDeclRef (uniqueCase.get (),
2307
+ SILDeclRef::Kind::EnumElement);
2257
2308
}
2258
2309
}
2259
2310
}
2260
2311
2261
- void visitSwitchEnumInst (SwitchEnumInst *SOI ) {
2262
- printSwitchEnumInst (SOI );
2263
- printForwardingOwnershipKind (SOI, SOI ->getOperand ());
2312
+ void visitSwitchEnumInst (SwitchEnumInst *switchEnum ) {
2313
+ printSwitchEnumInst (switchEnum );
2314
+ printForwardingOwnershipKind (switchEnum, switchEnum ->getOperand ());
2264
2315
}
2265
- void visitSwitchEnumAddrInst (SwitchEnumAddrInst *SOI ) {
2266
- printSwitchEnumInst (SOI );
2316
+ void visitSwitchEnumAddrInst (SwitchEnumAddrInst *switchEnum ) {
2317
+ printSwitchEnumInst (switchEnum );
2267
2318
}
2268
-
2319
+
2269
2320
void printSelectEnumInst (SelectEnumInstBase *SEI) {
2270
2321
*this << getIDAndType (SEI->getEnumOperand ());
2271
2322
0 commit comments