@@ -130,7 +130,7 @@ void diagnoseRequiredCopyOfMoveOnly(Operand *use,
130
130
// /
131
131
// / This result remains valid during copy rewriting. The only instructions
132
132
// / referenced it contains are consumes that cannot be deleted.
133
- class CanonicalOSSAConsumeInfo {
133
+ class CanonicalOSSAConsumeInfo final {
134
134
// / Map blocks on the lifetime boundary to the last consuming instruction.
135
135
llvm::SmallDenseMap<SILBasicBlock *, SILInstruction *, 4 > finalBlockConsumes;
136
136
@@ -159,6 +159,10 @@ class CanonicalOSSAConsumeInfo {
159
159
return false ;
160
160
}
161
161
162
+ CanonicalOSSAConsumeInfo () {}
163
+ CanonicalOSSAConsumeInfo (CanonicalOSSAConsumeInfo const &) = delete ;
164
+ CanonicalOSSAConsumeInfo &
165
+ operator =(CanonicalOSSAConsumeInfo const &) = delete ;
162
166
SWIFT_ASSERT_ONLY_DECL (void dump () const LLVM_ATTRIBUTE_USED);
163
167
};
164
168
@@ -169,7 +173,7 @@ class CanonicalOSSAConsumeInfo {
169
173
// /
170
174
// / TODO: Move all the private per-definition members into an implementation
171
175
// / class in the .cpp file.
172
- class CanonicalizeOSSALifetime {
176
+ class CanonicalizeOSSALifetime final {
173
177
public:
174
178
// / Find the original definition of a potentially copied value. \p copiedValue
175
179
// / must be an owned value. It is usually a copy but may also be a destroy.
@@ -205,6 +209,10 @@ class CanonicalizeOSSALifetime {
205
209
// / liveness may be pruned during canonicalization.
206
210
bool pruneDebugMode;
207
211
212
+ // / If true, lifetimes will not be shortened except when necessary to avoid
213
+ // / copies.
214
+ bool maximizeLifetime;
215
+
208
216
// / If true and we are processing a value of move_only type, emit a diagnostic
209
217
// / when-ever we need to insert a copy_value.
210
218
std::function<void (Operand *)> moveOnlyCopyValueNotification;
@@ -240,6 +248,9 @@ class CanonicalizeOSSALifetime {
240
248
// / Visited set for general def-use traversal that prevents revisiting values.
241
249
GraphNodeWorklist<SILValue, 8 > defUseWorklist;
242
250
251
+ // / The blocks that were discovered by PrunedLiveness.
252
+ SmallVector<SILBasicBlock *, 32 > discoveredBlocks;
253
+
243
254
// / Pruned liveness for the extended live range including copies. For this
244
255
// / purpose, only consuming instructions are considered "lifetime
245
256
// / ending". end_borrows do not end a liverange that may include owned copies.
@@ -248,7 +259,7 @@ class CanonicalizeOSSALifetime {
248
259
// / The destroys of the value. These are not uses, but need to be recorded so
249
260
// / that we know when the last use in a consuming block is (without having to
250
261
// / repeatedly do use-def walks from destroys).
251
- SmallPtrSet <SILInstruction *, 8 > destroys;
262
+ SmallPtrSetVector <SILInstruction *, 8 > destroys;
252
263
253
264
// / Information about consuming instructions discovered in this canonical OSSA
254
265
// / lifetime.
@@ -286,15 +297,17 @@ class CanonicalizeOSSALifetime {
286
297
}
287
298
288
299
CanonicalizeOSSALifetime (
289
- bool pruneDebugMode, NonLocalAccessBlockAnalysis *accessBlockAnalysis,
290
- DominanceInfo *domTree, InstructionDeleter &deleter,
300
+ bool pruneDebugMode, bool maximizeLifetime,
301
+ NonLocalAccessBlockAnalysis *accessBlockAnalysis, DominanceInfo *domTree,
302
+ InstructionDeleter &deleter,
291
303
std::function<void (Operand *)> moveOnlyCopyValueNotification = nullptr ,
292
304
std::function<void (Operand *)> moveOnlyFinalConsumingUse = nullptr )
293
- : pruneDebugMode(pruneDebugMode),
305
+ : pruneDebugMode(pruneDebugMode), maximizeLifetime(maximizeLifetime),
294
306
moveOnlyCopyValueNotification (moveOnlyCopyValueNotification),
295
307
moveOnlyFinalConsumingUse(moveOnlyFinalConsumingUse),
296
308
accessBlockAnalysis(accessBlockAnalysis), domTree(domTree),
297
- deleter(deleter) {}
309
+ deleter(deleter),
310
+ liveness(maximizeLifetime ? &discoveredBlocks : nullptr ) {}
298
311
299
312
SILValue getCurrentDef () const { return liveness.getDef (); }
300
313
@@ -313,6 +326,7 @@ class CanonicalizeOSSALifetime {
313
326
consumingBlocks.clear ();
314
327
debugValues.clear ();
315
328
liveness.clear ();
329
+ discoveredBlocks.clear ();
316
330
}
317
331
318
332
// / Top-Level API: rewrites copies and destroys within \p def's extended
@@ -331,7 +345,7 @@ class CanonicalizeOSSALifetime {
331
345
332
346
InstModCallbacks &getCallbacks () { return deleter.getCallbacks (); }
333
347
334
- protected :
348
+ private :
335
349
void recordDebugValue (DebugValueInst *dvi) { debugValues.insert (dvi); }
336
350
337
351
void recordConsumingUse (Operand *use) {
@@ -343,9 +357,14 @@ class CanonicalizeOSSALifetime {
343
357
344
358
void extendLivenessThroughOverlappingAccess ();
345
359
346
- void findExtendedBoundary (PrunedLivenessBoundary &boundary);
360
+ void findOriginalBoundary (PrunedLivenessBoundary &boundary);
361
+
362
+ void findExtendedBoundary (PrunedLivenessBoundary const &originalBoundary,
363
+ PrunedLivenessBoundary &boundary);
364
+
365
+ void extendUnconsumedLiveness (PrunedLivenessBoundary const &boundary);
347
366
348
- void insertDestroysOnBoundary (PrunedLivenessBoundary &boundary);
367
+ void insertDestroysOnBoundary (PrunedLivenessBoundary const &boundary);
349
368
350
369
void rewriteCopies ();
351
370
};
0 commit comments