@@ -133,17 +133,38 @@ void diagnoseRequiredCopyOfMoveOnly(Operand *use,
133
133
// / This result remains valid during copy rewriting. The only instructions
134
134
// / referenced it contains are consumes that cannot be deleted.
135
135
class CanonicalOSSAConsumeInfo final {
136
+ public:
137
+ struct ForwardRewriteInfo {
138
+ CopyValueInst *def = nullptr ;
139
+ SmallVector<Operand *, 4 > borrowedOperands;
140
+ SmallVector<SILInstruction *, 4 > users;
141
+ SmallPtrSetVector<Operand *, 4 > operands;
142
+ SmallVector<DestroyValueInst *, 4 > destroys;
143
+ };
144
+
145
+ private:
136
146
// / Map blocks on the lifetime boundary to the last consuming instruction.
137
147
llvm::SmallDenseMap<SILBasicBlock *, SILInstruction *, 4 > finalBlockConsumes;
138
148
139
149
// / The instructions on the availability boundary of the dead-end region where
140
150
// / this value is not consumed.
141
151
SmallPtrSet<SILInstruction *, 4 > unreachableLifetimeEnds;
142
152
153
+ SmallVector<ForwardRewriteInfo, 4 > forwards;
154
+
143
155
public:
144
- void clear () { finalBlockConsumes.clear (); }
156
+ void clear () {
157
+ finalBlockConsumes.clear ();
158
+ unreachableLifetimeEnds.clear ();
159
+ forwards.clear ();
160
+ }
145
161
146
- bool empty () { return finalBlockConsumes.empty (); }
162
+ // FIXME: FIXME_NOW: Avoid this copy.
163
+ void recordForward (ForwardRewriteInfo forward) {
164
+ forwards.push_back (forward);
165
+ }
166
+
167
+ ArrayRef<ForwardRewriteInfo> getForwards () { return forwards; }
147
168
148
169
bool hasUnclaimedConsumes () const { return !finalBlockConsumes.empty (); }
149
170
@@ -279,6 +300,8 @@ class CanonicalizeOSSALifetime final {
279
300
// / repeatedly do use-def walks from destroys).
280
301
SmallPtrSetVector<SILInstruction *, 8 > destroys;
281
302
303
+ llvm::SmallSetVector<Operand *, 8 > forwardingConsumes;
304
+
282
305
// / Information about consuming instructions discovered in this canonical OSSA
283
306
// / lifetime.
284
307
CanonicalOSSAConsumeInfo consumes;
@@ -331,19 +354,22 @@ class CanonicalizeOSSALifetime final {
331
354
accessBlocks = nullptr ;
332
355
consumes.clear ();
333
356
destroys.clear ();
357
+ forwardingConsumes.clear ();
358
+ discoveredBlocks.clear ();
334
359
335
360
currentDef = def;
336
361
337
- if (maximizeLifetime || respectsDeinitBarriers ()) {
338
- liveness->initializeDiscoveredBlocks (&discoveredBlocks);
339
- }
362
+ // if (maximizeLifetime || respectsDeinitBarriers()) {
363
+ liveness->initializeDiscoveredBlocks (&discoveredBlocks);
364
+ // }
340
365
liveness->initializeDef (getCurrentDef ());
341
366
}
342
367
343
368
void clear () {
344
369
consumingBlocks.clear ();
345
370
debugValues.clear ();
346
371
discoveredBlocks.clear ();
372
+ forwardingConsumes.clear ();
347
373
}
348
374
349
375
// / Top-Level API: rewrites copies and destroys within \p def's extended
@@ -420,6 +446,8 @@ class CanonicalizeOSSALifetime final {
420
446
421
447
void recordDebugValue (DebugValueInst *dvi) { debugValues.insert (dvi); }
422
448
449
+ void recordForwardingConsume (Operand *use) { forwardingConsumes.insert (use); }
450
+
423
451
void recordConsumingUse (Operand *use) { recordConsumingUser (use->getUser ()); }
424
452
// / Record that the value is consumed at `user`.
425
453
// /
@@ -450,6 +478,13 @@ class CanonicalizeOSSALifetime final {
450
478
void insertDestroysOnBoundary (PrunedLivenessBoundary const &boundary);
451
479
452
480
void rewriteCopies ();
481
+ void addForwardingConsumesToLiveness ();
482
+ bool addForwardingConsumeToLiveness (
483
+ CopyValueInst *cvi, CanonicalOSSAConsumeInfo::ForwardRewriteInfo &info);
484
+
485
+ void rewriteForwardingConsumes ();
486
+ void rewriteForwardingConsume (
487
+ CanonicalOSSAConsumeInfo::ForwardRewriteInfo const &info);
453
488
};
454
489
455
490
} // end namespace swift
0 commit comments