@@ -74,35 +74,37 @@ static bool isDeadLiveRange(
74
74
}
75
75
76
76
// Otherwise, see if we have a forwarding value that has a single
77
- // non-trivial operand that can accept a guaranteed value. If so, at its
78
- // users to the worklist and continue.
77
+ // non-trivial operand that can accept a guaranteed value. If not, we can
78
+ // not recursively process it, so be conservative and assume that we /may
79
+ // consume/ the value, so the live range must not be eliminated.
79
80
//
80
81
// DISCUSSION: For now we do not support forwarding instructions with
81
82
// multiple non-trivial arguments since we would need to optimize all of
82
83
// the non-trivial arguments at the same time.
83
84
//
84
85
// NOTE: Today we do not support TermInsts for simplicity... we /could/
85
86
// support it though if we need to.
86
- if (forwardingInsts.isNonNull () && ! isa<TermInst>(user) &&
87
- isGuaranteedForwardingInst (user) &&
88
- 1 = = count_if (user->getOperandValues (
87
+ if (forwardingInsts.isNull () || isa<TermInst>(user) ||
88
+ ! isGuaranteedForwardingInst (user) ||
89
+ 1 ! = count_if (user->getOperandValues (
89
90
true /* ignore type dependent operands*/ ),
90
91
[&](SILValue v) {
91
92
return v.getOwnershipKind () ==
92
93
ValueOwnershipKind::Owned;
93
94
})) {
94
- forwardingInsts.get ()->push_back (user);
95
- for (SILValue v : user->getResults ()) {
96
- if (v.getOwnershipKind () != ValueOwnershipKind::Owned)
97
- continue ;
98
- llvm::copy (v->getUses (), std::back_inserter (worklist));
99
- }
100
- continue ;
95
+ return false ;
101
96
}
102
97
103
- // Otherwise be conservative and assume that we /may consume/ the value,
104
- // so the live range must not be eliminated.
105
- return false ;
98
+ // Ok, this is a forwarding instruction whose ownership we can flip from
99
+ // owned -> guaranteed. Visit its users recursively to see if the the
100
+ // users force the live range to be alive.
101
+ forwardingInsts.get ()->push_back (user);
102
+ for (SILValue v : user->getResults ()) {
103
+ if (v.getOwnershipKind () != ValueOwnershipKind::Owned)
104
+ continue ;
105
+ llvm::copy (v->getUses (), std::back_inserter (worklist));
106
+ }
107
+ continue ;
106
108
}
107
109
case UseLifetimeConstraint::MustBeLive:
108
110
// Ok, this constraint can take something owned as live. Assert that it
0 commit comments