@@ -86,6 +86,10 @@ llvm::cl::opt<bool>
8686SILPrintTypes (" sil-print-types" , llvm::cl::init(false ),
8787 llvm::cl::desc(" always print type annotations for instruction operands in SIL output" ));
8888
89+ llvm::cl::opt<bool >
90+ SILPrintOwnership (" sil-print-ownership" , llvm::cl::init(false ),
91+ llvm::cl::desc(" print ownership of instruction results in SIL output" ));
92+
8993llvm::cl::opt<bool >
9094SILPrintNoUses (" sil-print-no-uses" , llvm::cl::init(false ),
9195 llvm::cl::desc(" omit use comments in SIL output" ));
@@ -693,6 +697,35 @@ class LineComments : public raw_ostream {
693697 }
694698};
695699
700+ static bool hasNonAddressResults (const SILInstruction *inst) {
701+ for (SILValue result : inst->getResults ()) {
702+ if (result->getType ().isObject ())
703+ return true ;
704+ }
705+ return false ;
706+ }
707+
708+ // / Returns true if the ownership of a result of `inst` mismatches with its type.
709+ // / That can happen e.g. for non-trivial enums which are constructed with a trivial case:
710+ // / ```
711+ // / enum E {
712+ // / case A
713+ // / case B(AnyObject)
714+ // / }
715+ // /
716+ // / %1 = enum $E, #E.A!enumelt // type of %1 is non trivial, but ownership is "none"
717+ // / ```
718+ static bool hasUnusualResultOwnership (const SILInstruction *inst) {
719+ for (SILValue result : inst->getResults ()) {
720+ if (result->getType ().isObject () &&
721+ result->getOwnershipKind () == OwnershipKind::None &&
722+ !result->getType ().isTrivial (*inst->getFunction ())) {
723+ return true ;
724+ }
725+ }
726+ return false ;
727+ }
728+
696729} // namespace
697730
698731namespace swift {
@@ -1092,6 +1125,28 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
10921125 printBranchTargets (inst);
10931126 }
10941127
1128+ void printOwnershipOfInstruction (const SILInstruction *inst) {
1129+
1130+ if (!inst->isStaticInitializerInst () &&
1131+ inst->getFunction ()->hasOwnership () &&
1132+ hasNonAddressResults (inst) &&
1133+ (SILPrintOwnership || hasUnusualResultOwnership (inst)))
1134+ {
1135+ lineComments.delim ();
1136+
1137+ *this << " ownership: " ;
1138+ llvm::interleave (inst->getResults (),
1139+ [&](SILValue result) {
1140+ if (result->getType ().isAddress ()) {
1141+ *this << ' -' ;
1142+ } else {
1143+ *this << result->getOwnershipKind ();
1144+ }
1145+ },
1146+ [&] { *this << " , " ; });
1147+ }
1148+ }
1149+
10951150 void printUserList (ArrayRef<SILValue> values, SILNodePointer node) {
10961151 if (SILPrintNoUses)
10971152 return ;
@@ -1364,6 +1419,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
13641419 // Print users, or id for valueless instructions.
13651420 printUsersOfInstruction (I);
13661421
1422+ printOwnershipOfInstruction (I);
1423+
13671424 // Print SIL location.
13681425 if (Ctx.printVerbose ()) {
13691426 printSILLocation (I->getLoc (), I->getModule (), I->getDebugScope ());
@@ -1965,6 +2022,23 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
19652022 }
19662023 }
19672024
2025+ template <typename Inst>
2026+ void printForwardingOwnershipKind (Inst *inst) {
2027+ if (inst->getNumRealOperands () == 0 ) {
2028+ return ;
2029+ }
2030+ bool matching = false ;
2031+ for (Operand *op : inst->getRealOperands ()) {
2032+ if (inst->getForwardingOwnershipKind () == op->get ()->getOwnershipKind ()) {
2033+ matching = true ;
2034+ break ;
2035+ }
2036+ }
2037+ if (!matching) {
2038+ *this << " , forwarding: @" << inst->getForwardingOwnershipKind ();
2039+ }
2040+ }
2041+
19682042 void visitStoreInst (StoreInst *SI) {
19692043 *this << Ctx.getID (SI->getSrc ()) << " to " ;
19702044 printStoreOwnershipQualifier (SI->getOwnershipQualifier ());
@@ -2409,6 +2483,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
24092483 SI->getElements (), [&](const SILValue &V) { *this << getIDAndType (V); },
24102484 [&] { *this << " , " ; });
24112485 *this << ' )' ;
2486+ printForwardingOwnershipKind (SI);
24122487 }
24132488
24142489 void visitObjectInst (ObjectInst *OI) {
@@ -2464,6 +2539,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
24642539 [&] { *this << " , " ; });
24652540 *this << ' )' ;
24662541 }
2542+ printForwardingOwnershipKind (TI);
24672543 }
24682544
24692545 void visitTupleAddrConstructorInst (TupleAddrConstructorInst *TI) {
0 commit comments