Skip to content

Commit 1f48f50

Browse files
committed
[move-only-addr] Extract out multi-block liveness initialization into a helper function.
Just more refactoring in preparation for some fixes. NFCI.
1 parent 2327e77 commit 1f48f50

File tree

1 file changed

+53
-48
lines changed

1 file changed

+53
-48
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyAddressChecker.cpp

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,12 @@ struct BlockSummaries {
12661266
}
12671267

12681268
void summarize(SILBasicBlock &block);
1269+
1270+
/// After we have summarized all of our blocks, initialize the given pruned
1271+
/// liveness with the information needed from our summaries to perform
1272+
/// multi-block liveness dataflow.
1273+
void initializeLiveness(FieldSensitiveAddressPrunedLiveness &liveness,
1274+
SmallPtrSetImpl<SILInstruction *> &inoutTermUsers);
12691275
};
12701276

12711277
} // anonymous namespace
@@ -1433,6 +1439,48 @@ void BlockSummaries::summarize(SILBasicBlock &block) {
14331439
}
14341440
}
14351441

1442+
void BlockSummaries::initializeLiveness(
1443+
FieldSensitiveAddressPrunedLiveness &liveness,
1444+
SmallPtrSetImpl<SILInstruction *> &inoutTermUsers) {
1445+
// At this point, we have handled all of the single block cases and have
1446+
// simplified the remaining cases to global cases that we compute using
1447+
// liveness. We begin by using all of our init down blocks as def blocks.
1448+
for (auto initInstAndValue : initDownInsts)
1449+
liveness.initializeDefBlock(initInstAndValue.first->getParent(),
1450+
initInstAndValue.second);
1451+
1452+
// Then add all of the takes that we saw propagated up to the top of our
1453+
// block. Since we have done this for all of our defs
1454+
for (auto takeInstAndValue : takeUpInsts)
1455+
liveness.updateForUse(takeInstAndValue.first, takeInstAndValue.second,
1456+
true /*lifetime ending*/);
1457+
// Do the same for our borrow and liveness insts.
1458+
for (auto livenessInstAndValue : livenessUpInsts)
1459+
liveness.updateForUse(livenessInstAndValue.first,
1460+
livenessInstAndValue.second,
1461+
false /*lifetime ending*/);
1462+
1463+
// Finally, if we have an inout argument, add a liveness use of the entire
1464+
// value on terminators in blocks that are exits from the function. This
1465+
// ensures that along all paths, if our inout is not reinitialized before we
1466+
// exit the function, we will get an error. We also stash these users into
1467+
// inoutTermUser so we can quickly recognize them later and emit a better
1468+
// error msg.
1469+
if (auto *fArg = dyn_cast<SILFunctionArgument>(markedAddress->getOperand())) {
1470+
if (fArg->getArgumentConvention() ==
1471+
SILArgumentConvention::Indirect_Inout) {
1472+
SmallVector<SILBasicBlock *, 8> exitBlocks;
1473+
markedAddress->getFunction()->findExitingBlocks(exitBlocks);
1474+
for (auto *block : exitBlocks) {
1475+
inoutTermUsers.insert(block->getTerminator());
1476+
liveness.updateForUse(block->getTerminator(),
1477+
TypeTreeLeafTypeRange(markedAddress),
1478+
false /*lifetime ending*/);
1479+
}
1480+
}
1481+
}
1482+
}
1483+
14361484
//===----------------------------------------------------------------------===//
14371485
// MARK: Main Pass Implementation
14381486
//===----------------------------------------------------------------------===//
@@ -1607,66 +1655,23 @@ bool MoveOnlyChecker::performSingleCheck(MarkMustCheckInst *markedAddress) {
16071655
// Multi-Block Liveness Dataflow
16081656
//
16091657

1610-
SmallVectorImpl<InstLeafTypePair> &initDownInsts = summaries.initDownInsts;
1611-
SmallVectorImpl<InstLeafTypePair> &takeDownInsts = summaries.takeDownInsts;
1612-
SmallVectorImpl<InstLeafTypePair> &takeUpInsts = summaries.takeUpInsts;
1613-
SmallVectorImpl<InstLeafTypePair> &livenessUpInsts =
1614-
summaries.livenessUpInsts;
1615-
BlockState::Map &blockToState = summaries.blockToState;
1616-
16171658
SmallVector<SILBasicBlock *, 32> discoveredBlocks;
16181659
FieldSensitiveAddressPrunedLiveness liveness(fn, markedAddress,
16191660
&discoveredBlocks);
1661+
SmallPtrSet<SILInstruction *, 8> inoutTermUsers;
16201662

1621-
// At this point, we have handled all of the single block cases and have
1622-
// simplified the remaining cases to global cases that we compute using
1623-
// liveness. We begin by using all of our init down blocks as def blocks.
1624-
for (auto initInstAndValue : initDownInsts)
1625-
liveness.initializeDefBlock(initInstAndValue.first->getParent(),
1626-
initInstAndValue.second);
1627-
1628-
// Then add all of the takes that we saw propagated up to the top of our
1629-
// block. Since we have done this for all of our defs
1630-
for (auto takeInstAndValue : takeUpInsts)
1631-
liveness.updateForUse(takeInstAndValue.first, takeInstAndValue.second,
1632-
true /*lifetime ending*/);
1633-
// Do the same for our borrow and liveness insts.
1634-
for (auto livenessInstAndValue : livenessUpInsts)
1635-
liveness.updateForUse(livenessInstAndValue.first,
1636-
livenessInstAndValue.second,
1637-
false /*lifetime ending*/);
1638-
1639-
// Finally, if we have an inout argument, add a liveness use of the entire
1640-
// value on terminators in blocks that are exits from the function. This
1641-
// ensures that along all paths, if our inout is not reinitialized before we
1642-
// exit the function, we will get an error. We also stash these users into
1643-
// inoutTermUser so we can quickly recognize them later and emit a better
1644-
// error msg.
1645-
SmallPtrSet<SILInstruction *, 8> inoutTermUser;
1646-
if (auto *fArg = dyn_cast<SILFunctionArgument>(markedAddress->getOperand())) {
1647-
if (fArg->getArgumentConvention() ==
1648-
SILArgumentConvention::Indirect_Inout) {
1649-
SmallVector<SILBasicBlock *, 8> exitBlocks;
1650-
markedAddress->getFunction()->findExitingBlocks(exitBlocks);
1651-
for (auto *block : exitBlocks) {
1652-
inoutTermUser.insert(block->getTerminator());
1653-
liveness.updateForUse(block->getTerminator(),
1654-
TypeTreeLeafTypeRange(markedAddress),
1655-
false /*lifetime ending*/);
1656-
}
1657-
}
1658-
}
1663+
summaries.initializeLiveness(liveness, inoutTermUsers);
16591664

16601665
// If we have multiple blocks in the function, now run the global pruned
16611666
// liveness dataflow.
16621667
if (std::next(fn->begin()) != fn->end()) {
16631668
// Then compute the takes that are within the cumulative boundary of
16641669
// liveness that we have computed. If we find any, they are the errors ones.
1665-
LivenessChecker emitter(markedAddress, liveness, inoutTermUser,
1666-
blockToState, diagnosticEmitter);
1670+
LivenessChecker emitter(markedAddress, liveness, inoutTermUsers,
1671+
summaries.blockToState, diagnosticEmitter);
16671672

16681673
// If we had any errors, we do not want to modify the SIL... just bail.
1669-
if (emitter.compute(takeUpInsts, takeDownInsts)) {
1674+
if (emitter.compute(summaries.takeUpInsts, summaries.takeDownInsts)) {
16701675
// TODO: Remove next line.
16711676
valuesWithDiagnostics.insert(markedAddress);
16721677
return true;

0 commit comments

Comments
 (0)