@@ -79,75 +79,72 @@ class LiveRange {
79
79
80
80
LiveRange::LiveRange (SILValue value)
81
81
: destroys(), generalForwardingInsts(), unknownConsumingUsers() {
82
- SmallVector<Operand *, 32 > worklist (value-> getUses () );
82
+ assert (value. getOwnershipKind () == ValueOwnershipKind::Owned );
83
83
84
+ // We know that our silvalue produces an @owned value. Look through all of our
85
+ // uses and classify them as either consuming or not.
86
+ SmallVector<Operand *, 32 > worklist (value->getUses ());
84
87
while (!worklist.empty ()) {
85
88
auto *op = worklist.pop_back_val ();
86
89
87
90
// Skip type dependent operands.
88
91
if (op->isTypeDependent ())
89
92
continue ;
90
93
91
- auto *user = op->getUser ();
94
+ // Do a quick check that we did not add ValueOwnershipKind that are not
95
+ // owned to the worklist.
96
+ assert (op->get ().getOwnershipKind () == ValueOwnershipKind::Owned &&
97
+ " Added non-owned value to worklist?!" );
92
98
93
- // We know that a copy_value produces an @owned value. Look through all of
94
- // our uses and classify them as either invalidating or not
95
- // invalidating. Make sure that all of the invalidating ones are
96
- // destroy_value since otherwise the live_range is not complete.
97
- auto map = op->getOwnershipKindMap ();
98
- auto constraint = map.getLifetimeConstraint (ValueOwnershipKind::Owned);
99
- switch (constraint) {
100
- case UseLifetimeConstraint::MustBeInvalidated: {
101
- // See if we have a destroy value. If we don't we have an
102
- // unknown consumer. Return false, we need this live range.
103
- if (auto *dvi = dyn_cast<DestroyValueInst>(user)) {
104
- destroys.push_back (dvi);
105
- continue ;
106
- }
99
+ auto *user = op->getUser ();
107
100
108
- // Otherwise, see if we have a forwarding value that has a single
109
- // non-trivial operand that can accept a guaranteed value. If not, we can
110
- // not recursively process it, so be conservative and assume that we /may
111
- // consume/ the value, so the live range must not be eliminated.
112
- //
113
- // DISCUSSION: For now we do not support forwarding instructions with
114
- // multiple non-trivial arguments since we would need to optimize all of
115
- // the non-trivial arguments at the same time.
116
- //
117
- // NOTE: Today we do not support TermInsts for simplicity... we /could/
118
- // support it though if we need to.
119
- if (isa<TermInst>(user) || !isGuaranteedForwardingInst (user) ||
120
- 1 != count_if (user->getOperandValues (
121
- true /* ignore type dependent operands*/ ),
122
- [&](SILValue v) {
123
- return v.getOwnershipKind () ==
124
- ValueOwnershipKind::Owned;
125
- })) {
126
- unknownConsumingUsers.push_back (user);
127
- continue ;
128
- }
101
+ // Ok, this constraint can take something owned as live. Assert that it
102
+ // can also accept something that is guaranteed. Any non-consuming use of
103
+ // an owned value should be able to take a guaranteed parameter as well
104
+ // (modulo bugs). We assert to catch these.
105
+ if (!op->isConsumingUse ()) {
106
+ continue ;
107
+ }
129
108
130
- // Ok, this is a forwarding instruction whose ownership we can flip from
131
- // owned -> guaranteed. Visit its users recursively to see if the the
132
- // users force the live range to be alive.
133
- generalForwardingInsts.push_back (user);
134
- for (SILValue v : user->getResults ()) {
135
- if (v.getOwnershipKind () != ValueOwnershipKind::Owned)
136
- continue ;
137
- llvm::copy (v->getUses (), std::back_inserter (worklist));
138
- }
109
+ // Ok, we know now that we have a consuming use. See if we have a destroy
110
+ // value, quickly up front. If we do have one, stash it and continue.
111
+ if (auto *dvi = dyn_cast<DestroyValueInst>(user)) {
112
+ destroys.push_back (dvi);
139
113
continue ;
140
114
}
141
- case UseLifetimeConstraint::MustBeLive:
142
- // Ok, this constraint can take something owned as live. Assert that it
143
- // can also accept something that is guaranteed. Any non-consuming use of
144
- // an owned value should be able to take a guaranteed parameter as well
145
- // (modulo bugs). We assert to catch these.
146
- assert (map.canAcceptKind (ValueOwnershipKind::Guaranteed) &&
147
- " Any non-consuming use of an owned value should be able to take a "
148
- " guaranteed value" );
115
+
116
+ // Otherwise, we have some form of consuming use that either forwards or
117
+ // that we do not understand. See if we have a forwarding value that has a
118
+ // single non-trivial operand that can accept a guaranteed value. If not, we
119
+ // can not recursively process it, so be conservative and assume that we
120
+ // /may consume/ the value, so the live range must not be eliminated.
121
+ //
122
+ // DISCUSSION: For now we do not support forwarding instructions with
123
+ // multiple non-trivial arguments since we would need to optimize all of
124
+ // the non-trivial arguments at the same time.
125
+ //
126
+ // NOTE: Today we do not support TermInsts for simplicity... we /could/
127
+ // support it though if we need to.
128
+ if (isa<TermInst>(user) || !isGuaranteedForwardingInst (user) ||
129
+ 1 != count_if (user->getOperandValues (
130
+ true /* ignore type dependent operands*/ ),
131
+ [&](SILValue v) {
132
+ return v.getOwnershipKind () ==
133
+ ValueOwnershipKind::Owned;
134
+ })) {
135
+ unknownConsumingUsers.push_back (user);
149
136
continue ;
150
137
}
138
+
139
+ // Ok, this is a forwarding instruction whose ownership we can flip from
140
+ // owned -> guaranteed. Visit its users recursively to see if the the
141
+ // users force the live range to be alive.
142
+ generalForwardingInsts.push_back (user);
143
+ for (SILValue v : user->getResults ()) {
144
+ if (v.getOwnershipKind () != ValueOwnershipKind::Owned)
145
+ continue ;
146
+ llvm::copy (v->getUses (), std::back_inserter (worklist));
147
+ }
151
148
}
152
149
}
153
150
0 commit comments