@@ -196,26 +196,19 @@ class PrunedLiveBlocks {
196
196
197
197
unsigned size () const { return bits.size () / 2 ; }
198
198
199
- // FIXME: specialize this for scalar liveness, which is the critical path
200
- // for all OSSA utilities.
201
199
IsLive getLiveness (unsigned bitNo) const {
202
- SmallVector<IsLive, 1 > foundLiveness;
203
- getLiveness (bitNo, bitNo + 1 , foundLiveness) ;
204
- return foundLiveness[ 0 ] ;
200
+ if (!bits[bitNo * 2 ])
201
+ return IsLive::Dead ;
202
+ return bits[bitNo * 2 + 1 ] ? LiveOut : LiveWithin ;
205
203
}
206
204
205
+ // / Returns the liveness in \p resultingFoundLiveness. We only return the
206
+ // / bits for endBitNo - startBitNo.
207
207
void getLiveness (unsigned startBitNo, unsigned endBitNo,
208
208
SmallVectorImpl<IsLive> &resultingFoundLiveness) const {
209
209
unsigned actualStartBitNo = startBitNo * 2 ;
210
210
unsigned actualEndBitNo = endBitNo * 2 ;
211
211
212
- // NOTE: We pad both before/after with Dead to ensure that we are
213
- // returning an array that acts as a bit mask and thus can be directly
214
- // compared against other such bitmasks. This invariant is used when
215
- // computing boundaries.
216
- for (unsigned i = 0 ; i != startBitNo; ++i) {
217
- resultingFoundLiveness.push_back (Dead);
218
- }
219
212
for (unsigned i = actualStartBitNo, e = actualEndBitNo; i != e; i += 2 ) {
220
213
if (!bits[i]) {
221
214
resultingFoundLiveness.push_back (Dead);
@@ -224,9 +217,6 @@ class PrunedLiveBlocks {
224
217
225
218
resultingFoundLiveness.push_back (bits[i + 1 ] ? LiveOut : LiveWithin);
226
219
}
227
- for (unsigned i = endBitNo, e = size (); i != e; ++i) {
228
- resultingFoundLiveness.push_back (Dead);
229
- }
230
220
}
231
221
232
222
void setLiveness (unsigned startBitNo, unsigned endBitNo, IsLive isLive) {
@@ -291,9 +281,12 @@ class PrunedLiveBlocks {
291
281
292
282
// / Update this liveness result for a single use.
293
283
IsLive updateForUse (SILInstruction *user, unsigned bitNo) {
294
- SmallVector<IsLive, 1 > resultingLiveness;
295
- updateForUse (user, bitNo, bitNo + 1 , resultingLiveness);
296
- return resultingLiveness[0 ];
284
+ auto *block = user->getParent ();
285
+ auto liveness = getBlockLiveness (block, bitNo);
286
+ if (liveness != Dead)
287
+ return liveness;
288
+ computeScalarUseBlockLiveness (block, bitNo);
289
+ return getBlockLiveness (block, bitNo);
297
290
}
298
291
299
292
// / Update this range of liveness results for a single use.
@@ -302,19 +295,22 @@ class PrunedLiveBlocks {
302
295
SmallVectorImpl<IsLive> &resultingLiveness);
303
296
304
297
IsLive getBlockLiveness (SILBasicBlock *bb, unsigned bitNo) const {
305
- SmallVector<IsLive, 1 > isLive;
306
- getBlockLiveness (bb, bitNo, bitNo + 1 , isLive);
307
- return isLive[0 ];
298
+ auto liveBlockIter = liveBlocks.find (bb);
299
+ if (liveBlockIter == liveBlocks.end ()) {
300
+ return Dead;
301
+ }
302
+
303
+ return liveBlockIter->second .getLiveness (bitNo);
308
304
}
309
305
310
- // FIXME: This API should directly return the live bitset. The live bitset
311
- // type should have an api for querying and iterating over the live fields.
306
+ // / FIXME: This API should directly return the live bitset. The live bitset
307
+ // / type should have an api for querying and iterating over the live fields.
312
308
void getBlockLiveness (SILBasicBlock *bb, unsigned startBitNo,
313
309
unsigned endBitNo,
314
310
SmallVectorImpl<IsLive> &foundLivenessInfo) const {
315
311
auto liveBlockIter = liveBlocks.find (bb);
316
312
if (liveBlockIter == liveBlocks.end ()) {
317
- for (unsigned i : range (numBitsToTrack )) {
313
+ for (unsigned i : range (endBitNo - startBitNo )) {
318
314
(void )i;
319
315
foundLivenessInfo.push_back (Dead);
320
316
}
@@ -330,11 +326,6 @@ class PrunedLiveBlocks {
330
326
331
327
protected:
332
328
void markBlockLive (SILBasicBlock *bb, unsigned bitNo, IsLive isLive) {
333
- markBlockLive (bb, bitNo, bitNo + 1 , isLive);
334
- }
335
-
336
- void markBlockLive (SILBasicBlock *bb, unsigned startBitNo, unsigned endBitNo,
337
- IsLive isLive) {
338
329
assert (isLive != Dead && " erasing live blocks isn't implemented." );
339
330
auto iterAndInserted =
340
331
liveBlocks.insert (std::make_pair (bb, LivenessSmallBitVector ()));
@@ -344,18 +335,44 @@ class PrunedLiveBlocks {
344
335
// we have more than SmallBitVector's small size number of bits.
345
336
auto &insertedBV = iterAndInserted.first ->getSecond ();
346
337
insertedBV.init (numBitsToTrack);
347
- insertedBV.setLiveness (startBitNo, endBitNo , isLive);
338
+ insertedBV.setLiveness (bitNo, bitNo + 1 , isLive);
348
339
if (discoveredBlocks)
349
340
discoveredBlocks->push_back (bb);
350
- } else if (isLive == LiveOut) {
351
- // Update the existing entry to be live-out.
352
- iterAndInserted.first ->getSecond ().setLiveness (startBitNo, endBitNo,
353
- LiveOut);
341
+ } else {
342
+ // If we are dead, always update to the new liveness.
343
+ switch (iterAndInserted.first ->getSecond ().getLiveness (bitNo)) {
344
+ case Dead:
345
+ iterAndInserted.first ->getSecond ().setLiveness (bitNo, bitNo + 1 ,
346
+ isLive);
347
+ break ;
348
+ case LiveWithin:
349
+ if (isLive == LiveOut) {
350
+ // Update the existing entry to be live-out.
351
+ iterAndInserted.first ->getSecond ().setLiveness (bitNo, bitNo + 1 ,
352
+ LiveOut);
353
+ }
354
+ break ;
355
+ case LiveOut:
356
+ break ;
357
+ }
354
358
}
355
359
}
356
360
357
- void computeUseBlockLiveness (SILBasicBlock *userBB, unsigned startBitNo,
358
- unsigned endBitNo);
361
+ void markBlockLive (SILBasicBlock *bb, unsigned startBitNo, unsigned endBitNo,
362
+ IsLive isLive) {
363
+ for (unsigned index : range (startBitNo, endBitNo)) {
364
+ markBlockLive (bb, index, isLive);
365
+ }
366
+ }
367
+
368
+ private:
369
+ // / A helper routine that as a fast path handles the scalar case. We do not
370
+ // / handle the mult-bit case today since the way the code is written today
371
+ // / assumes we process a bit at a time.
372
+ // /
373
+ // / TODO: Make a multi-bit query for efficiency reasons.
374
+ void computeScalarUseBlockLiveness (SILBasicBlock *userBB,
375
+ unsigned startBitNo);
359
376
};
360
377
361
378
// / If inner borrows are 'Contained', then liveness is fully described by the
0 commit comments