28
28
#include " swift/SIL/SILInstruction.h"
29
29
#include " swift/SILOptimizer/Analysis/Analysis.h"
30
30
#include " swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
31
+ #include " swift/Basic/BlotSetVector.h"
32
+ #include " swift/Basic/FrozenMultiMap.h"
31
33
#include " swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
32
34
#include " swift/SILOptimizer/PassManager/Passes.h"
33
35
#include " swift/SILOptimizer/PassManager/Transforms.h"
37
39
using namespace swift ;
38
40
using namespace swift ::siloptimizer;
39
41
40
- using namespace swift ;
41
- using namespace swift ::siloptimizer;
42
-
43
42
namespace {
44
43
using AvailableValues = BorrowToDestructureTransform::AvailableValues;
45
44
}
@@ -202,8 +201,8 @@ void BorrowToDestructureTransform::checkDestructureUsesOnBoundary() const {
202
201
for (auto *use : destructureNeedingUses) {
203
202
LLVM_DEBUG (llvm::dbgs ()
204
203
<< " DestructureNeedingUse: " << *use->getUser ());
205
- auto destructureUse = *TypeTreeLeafTypeRange::get (use->get (), mmci);
206
- if (liveness.isWithinBoundary (use->getUser (), destructureUse )) {
204
+ auto destructureUseSpan = *TypeTreeLeafTypeRange::get (use->get (), mmci);
205
+ if (liveness.isWithinBoundary (use->getUser (), destructureUseSpan )) {
207
206
LLVM_DEBUG (llvm::dbgs () << " Within boundary! Emitting error!\n " );
208
207
// Emit an error. We have a use after free.
209
208
//
@@ -217,7 +216,7 @@ void BorrowToDestructureTransform::checkDestructureUsesOnBoundary() const {
217
216
liveness.getNumSubElements ());
218
217
liveness.computeBoundary (boundary);
219
218
diagnosticEmitter.emitObjectDestructureNeededWithinBorrowBoundary (
220
- mmci, use->getUser (), destructureUse , boundary);
219
+ mmci, use->getUser (), destructureUseSpan , boundary);
221
220
return ;
222
221
} else {
223
222
LLVM_DEBUG (llvm::dbgs () << " On boundary! No error!\n " );
@@ -1338,12 +1337,20 @@ static bool runTransform(SILFunction *fn,
1338
1337
auto *mmci = moveIntroducersToProcess.back ();
1339
1338
moveIntroducersToProcess = moveIntroducersToProcess.drop_back ();
1340
1339
1340
+ unsigned currentDiagnosticCount = diagnosticEmitter.getDiagnosticCount ();
1341
+
1341
1342
StackList<BeginBorrowInst *> borrowWorklist (mmci->getFunction ());
1342
1343
1343
1344
// If we failed to gather borrows due to the transform not understanding
1344
- // part of the SIL, fail and return false.
1345
- if (!BorrowToDestructureTransform::gatherBorrows (mmci, borrowWorklist))
1346
- return madeChange;
1345
+ // part of the SIL, emit a diagnostic, RAUW the mark must check, and
1346
+ // continue.
1347
+ if (!BorrowToDestructureTransform::gatherBorrows (mmci, borrowWorklist)) {
1348
+ diagnosticEmitter.emitCheckerDoesntUnderstandDiagnostic (mmci);
1349
+ mmci->replaceAllUsesWith (mmci->getOperand ());
1350
+ mmci->eraseFromParent ();
1351
+ madeChange = true ;
1352
+ continue ;
1353
+ }
1347
1354
1348
1355
// If we do not have any borrows to process, continue and process the next
1349
1356
// instruction.
@@ -1360,29 +1367,43 @@ static bool runTransform(SILFunction *fn,
1360
1367
poa, discoveredBlocks);
1361
1368
1362
1369
// Attempt to gather uses. Return if we saw something that we did not
1363
- // understand. Return made change so we invalidate as appropriate.
1364
- if (!transform.gatherUses (borrowWorklist))
1365
- return madeChange;
1370
+ // understand. Emit a compiler did not understand diagnostic, RAUW the mmci
1371
+ // so later passes do not see it, and set madeChange to true.
1372
+ if (!transform.gatherUses (borrowWorklist)) {
1373
+ diagnosticEmitter.emitCheckerDoesntUnderstandDiagnostic (mmci);
1374
+ mmci->replaceAllUsesWith (mmci->getOperand ());
1375
+ mmci->eraseFromParent ();
1376
+ madeChange = true ;
1377
+ continue ;
1378
+ }
1366
1379
1367
1380
// Next make sure that any destructure needing instructions are on the
1368
1381
// boundary in a per bit field sensitive manner.
1369
1382
transform.checkDestructureUsesOnBoundary ();
1370
1383
1371
- // If we emitted any diagnostic, break out. We return true since we actually
1372
- // succeeded in our processing by finding the error. We only return false if
1373
- // we want to tell the rest of the checker that there was an internal
1374
- // compiler error that we need to emit a "compiler doesn't understand
1375
- // error".
1376
- if (diagnosticEmitter.emittedAnyDiagnostics ())
1377
- return madeChange;
1384
+ // If we emitted any diagnostic, set madeChange to true, eliminate our mmci,
1385
+ // and continue.
1386
+ if (currentDiagnosticCount != diagnosticEmitter.getDiagnosticCount ()) {
1387
+ mmci->replaceAllUsesWith (mmci->getOperand ());
1388
+ mmci->eraseFromParent ();
1389
+ madeChange = true ;
1390
+ continue ;
1391
+ }
1378
1392
1379
1393
// At this point, we know that all of our destructure requiring uses are on
1380
1394
// the boundary of our live range. Now we need to do the rewriting.
1381
1395
transform.blockToAvailableValues .emplace (transform.liveness );
1382
1396
transform.rewriteUses ();
1383
1397
1384
1398
// Now that we have done our rewritting, we need to do a few cleanups.
1399
+ //
1400
+ // NOTE: We do not eliminate our mark_must_check since we want later passes
1401
+ // to do additional checking upon the mark_must_check including making sure
1402
+ // that our destructures do not need cause the need for additional copies to
1403
+ // be inserted. We only eliminate the mark_must_check if we emitted a
1404
+ // diagnostic of some sort.
1385
1405
transform.cleanup (borrowWorklist);
1406
+ madeChange = true ;
1386
1407
}
1387
1408
1388
1409
return madeChange;
@@ -1405,8 +1426,9 @@ class MoveOnlyBorrowToDestructureTransformPass : public SILFunctionTransform {
1405
1426
assert (fn->getModule ().getStage () == SILStage::Raw &&
1406
1427
" Should only run on Raw SIL" );
1407
1428
1408
- LLVM_DEBUG (llvm::dbgs () << " ===> MoveOnly Object Checker. Visiting: "
1409
- << fn->getName () << ' \n ' );
1429
+ LLVM_DEBUG (llvm::dbgs ()
1430
+ << " ===> MoveOnlyBorrowToDestructureTransform. Visiting: "
1431
+ << fn->getName () << ' \n ' );
1410
1432
1411
1433
auto *postOrderAnalysis = getAnalysis<PostOrderAnalysis>();
1412
1434
@@ -1419,14 +1441,22 @@ class MoveOnlyBorrowToDestructureTransformPass : public SILFunctionTransform {
1419
1441
invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
1420
1442
}
1421
1443
1422
- if (emitter.emittedAnyDiagnostics ())
1444
+ if (emitter.emittedAnyDiagnostics ()) {
1445
+ if (cleanupSILAfterEmittingObjectMoveOnlyDiagnostics (fn))
1446
+ invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
1423
1447
return ;
1448
+ }
1424
1449
1425
1450
auto introducers = llvm::makeArrayRef (moveIntroducersToProcess.begin (),
1426
1451
moveIntroducersToProcess.end ());
1427
1452
if (runTransform (fn, introducers, postOrderAnalysis, emitter)) {
1428
1453
invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
1429
1454
}
1455
+
1456
+ if (emitter.emittedAnyDiagnostics ()) {
1457
+ if (cleanupSILAfterEmittingObjectMoveOnlyDiagnostics (fn))
1458
+ invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
1459
+ }
1430
1460
}
1431
1461
};
1432
1462
0 commit comments