Skip to content

Commit abe7c8f

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-rebranch
2 parents 892b430 + 8ea5df1 commit abe7c8f

File tree

13 files changed

+1479
-384
lines changed

13 files changed

+1479
-384
lines changed

include/swift/SIL/MemoryLifetime.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ class MemoryLocations {
183183
return &locations[index];
184184
}
185185

186+
/// Registers an address projection instruction for a location.
187+
void registerProjection(SingleValueInstruction *projection, unsigned locIdx) {
188+
addr2LocIdx[projection] = locIdx;
189+
}
190+
186191
/// Sets the location bits os \p addr in \p bits, if \p addr is associated
187192
/// with a location.
188193
void setBits(Bits &bits, SILValue addr) {
@@ -341,13 +346,29 @@ class MemoryDataflow {
341346
/// Calculates the BlockState::exitReachable flags.
342347
void exitReachableAnalysis();
343348

349+
using JoinOperation = std::function<void (Bits &dest, const Bits &src)>;
350+
344351
/// Derives the block exit sets from the entry sets by applying the gen and
345352
/// kill sets.
346-
void solveDataflowForward();
353+
/// At control flow joins, the \p join operation is applied.
354+
void solveForward(JoinOperation join);
355+
356+
/// Calls solveForward() with a bit-intersection as join operation.
357+
void solveForwardWithIntersect();
358+
359+
/// Calls solveForward() with a bit-union as join operation.
360+
void solveForwardWithUnion();
347361

348362
/// Derives the block entry sets from the exit sets by applying the gen and
349363
/// kill sets.
350-
void solveDataflowBackward();
364+
/// At control flow joins, the \p join operation is applied.
365+
void solveBackward(JoinOperation join);
366+
367+
/// Calls solveBackward() with a bit-intersection as join operation.
368+
void solveBackwardWithIntersect();
369+
370+
/// Calls solveBackward() with a bit-union as join operation.
371+
void solveBackwardWithUnion();
351372

352373
/// Debug dump the MemoryLifetime internals.
353374
void dump() const;

include/swift/SIL/SILInstruction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3240,6 +3240,9 @@ class LoadInst
32403240
return LoadOwnershipQualifier(
32413241
SILInstruction::Bits.LoadInst.OwnershipQualifier);
32423242
}
3243+
void setOwnershipQualifier(LoadOwnershipQualifier qualifier) {
3244+
SILInstruction::Bits.LoadInst.OwnershipQualifier = unsigned(qualifier);
3245+
}
32433246
};
32443247

32453248
// *NOTE* When serializing, we can only represent up to 4 values here. If more
@@ -3279,6 +3282,9 @@ class StoreInst
32793282
return StoreOwnershipQualifier(
32803283
SILInstruction::Bits.StoreInst.OwnershipQualifier);
32813284
}
3285+
void setOwnershipQualifier(StoreOwnershipQualifier qualifier) {
3286+
SILInstruction::Bits.StoreInst.OwnershipQualifier = unsigned(qualifier);
3287+
}
32823288
};
32833289

32843290
class EndBorrowInst;

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ PASS(DeadObjectElimination, "deadobject-elim",
132132
"Dead Object Elimination for Classes with Trivial Destruction")
133133
PASS(DefiniteInitialization, "definite-init",
134134
"Definite Initialization for Diagnostics")
135+
PASS(DestroyHoisting, "destroy-hoisting",
136+
"Hoisting of value destroys")
135137
PASS(Devirtualizer, "devirtualizer",
136138
"Indirect Call Devirtualization")
137139
PASS(DiagnoseInfiniteRecursion, "diagnose-infinite-recursion",

lib/SIL/MemoryLifetime.cpp

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ bool MemoryLocations::analyzeAddrProjection(
299299
subLocationMap)) {
300300
return false;
301301
}
302-
addr2LocIdx[projection] = subLocIdx;
302+
registerProjection(projection, subLocIdx);
303303
collectedVals.push_back(projection);
304304
return true;
305305
}
@@ -395,7 +395,7 @@ void MemoryDataflow::exitReachableAnalysis() {
395395
}
396396
}
397397

398-
void MemoryDataflow::solveDataflowForward() {
398+
void MemoryDataflow::solveForward(JoinOperation join) {
399399
// Pretty standard data flow solving.
400400
bool changed = false;
401401
bool firstRound = true;
@@ -405,7 +405,7 @@ void MemoryDataflow::solveDataflowForward() {
405405
Bits bits = st.entrySet;
406406
assert(!bits.empty());
407407
for (SILBasicBlock *pred : st.block->getPredecessorBlocks()) {
408-
bits &= block2State[pred]->exitSet;
408+
join(bits, block2State[pred]->exitSet);
409409
}
410410
if (firstRound || bits != st.entrySet) {
411411
changed = true;
@@ -419,7 +419,19 @@ void MemoryDataflow::solveDataflowForward() {
419419
} while (changed);
420420
}
421421

422-
void MemoryDataflow::solveDataflowBackward() {
422+
void MemoryDataflow::solveForwardWithIntersect() {
423+
solveForward([](Bits &entry, const Bits &predExit){
424+
entry &= predExit;
425+
});
426+
}
427+
428+
void MemoryDataflow::solveForwardWithUnion() {
429+
solveForward([](Bits &entry, const Bits &predExit){
430+
entry |= predExit;
431+
});
432+
}
433+
434+
void MemoryDataflow::solveBackward(JoinOperation join) {
423435
// Pretty standard data flow solving.
424436
bool changed = false;
425437
bool firstRound = true;
@@ -429,7 +441,7 @@ void MemoryDataflow::solveDataflowBackward() {
429441
Bits bits = st.exitSet;
430442
assert(!bits.empty());
431443
for (SILBasicBlock *succ : st.block->getSuccessorBlocks()) {
432-
bits &= block2State[succ]->entrySet;
444+
join(bits, block2State[succ]->entrySet);
433445
}
434446
if (firstRound || bits != st.exitSet) {
435447
changed = true;
@@ -443,6 +455,18 @@ void MemoryDataflow::solveDataflowBackward() {
443455
} while (changed);
444456
}
445457

458+
void MemoryDataflow::solveBackwardWithIntersect() {
459+
solveBackward([](Bits &entry, const Bits &predExit){
460+
entry &= predExit;
461+
});
462+
}
463+
464+
void MemoryDataflow::solveBackwardWithUnion() {
465+
solveBackward([](Bits &entry, const Bits &predExit){
466+
entry |= predExit;
467+
});
468+
}
469+
446470
void MemoryDataflow::dump() const {
447471
for (const BlockState &st : blockStates) {
448472
llvm::dbgs() << "bb" << st.block->getDebugID() << ":\n"
@@ -894,7 +918,7 @@ void MemoryLifetimeVerifier::verify() {
894918
MemoryDataflow dataFlow(function, locations.getNumLocations());
895919
dataFlow.entryReachabilityAnalysis();
896920
initDataflow(dataFlow);
897-
dataFlow.solveDataflowForward();
921+
dataFlow.solveForwardWithIntersect();
898922
checkFunction(dataFlow);
899923
}
900924
// Second step: handle single-block locations.

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ static void addMandatoryOptPipeline(SILPassPipelinePlan &P) {
104104
P.addClosureLifetimeFixup();
105105
if (Options.shouldOptimize()) {
106106
P.addSemanticARCOpts();
107+
P.addDestroyHoisting();
107108
}
108109
if (!Options.StripOwnershipAfterSerialization)
109110
P.addOwnershipModelEliminator();

lib/SILOptimizer/Transforms/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ silopt_register_sources(
1515
DeadCodeElimination.cpp
1616
DeadObjectElimination.cpp
1717
DeadStoreElimination.cpp
18+
DestroyHoisting.cpp
1819
Devirtualizer.cpp
1920
GenericSpecializer.cpp
2021
MergeCondFail.cpp

lib/SILOptimizer/Transforms/CopyForwarding.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,10 +1604,7 @@ void TempRValueOptPass::run() {
16041604
++II;
16051605

16061606
// Remove identity copies which are a result of this optimization.
1607-
if (CopyInst && CopyInst->getSrc() == CopyInst->getDest() &&
1608-
// Identity copies cannot take the source. This check is just here
1609-
// to be on the safe side.
1610-
!CopyInst->isTakeOfSrc()) {
1607+
if (CopyInst && CopyInst->getSrc() == CopyInst->getDest()) {
16111608
// This is either the CopyInst which just got optimized or it is a
16121609
// follow-up from an earlier iteration, where another copy_addr copied
16131610
// the temporary back to the source location.
@@ -1725,9 +1722,8 @@ bool TempRValueOptPass::collectLoads(
17251722

17261723
case SILInstructionKind::CopyAddrInst: {
17271724
// copy_addr which read from the temporary are like loads.
1728-
// TODO: Handle copy_addr [take]. But this doesn't seem to be important.
17291725
auto *copyFromTmp = cast<CopyAddrInst>(user);
1730-
if (copyFromTmp->getDest() == address || copyFromTmp->isTakeOfSrc()) {
1726+
if (copyFromTmp->getDest() == address) {
17311727
LLVM_DEBUG(llvm::dbgs() << " Temp written or taken" << *user);
17321728
return false;
17331729
}
@@ -1774,7 +1770,7 @@ bool TempRValueOptPass::checkNoSourceModification(CopyAddrInst *copyInst,
17741770

17751771
/// Tries to perform the temporary rvalue copy elimination for \p copyInst
17761772
bool TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
1777-
if (copyInst->isTakeOfSrc() || !copyInst->isInitializationOfDest())
1773+
if (!copyInst->isInitializationOfDest())
17781774
return false;
17791775

17801776
auto *tempObj = dyn_cast<AllocStackInst>(copyInst->getDest());
@@ -1818,10 +1814,25 @@ bool TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
18181814
SILInstruction *user = use->getUser();
18191815
switch (user->getKind()) {
18201816
case SILInstructionKind::DestroyAddrInst:
1817+
if (copyInst->isTakeOfSrc()) {
1818+
use->set(copyInst->getSrc());
1819+
} else {
1820+
user->eraseFromParent();
1821+
}
1822+
break;
18211823
case SILInstructionKind::DeallocStackInst:
18221824
user->eraseFromParent();
18231825
break;
1824-
case SILInstructionKind::CopyAddrInst:
1826+
case SILInstructionKind::CopyAddrInst: {
1827+
auto *CAI = cast<CopyAddrInst>(user);
1828+
if (CAI != copyInst) {
1829+
assert(CAI->getSrc() == tempObj);
1830+
if (CAI->isTakeOfSrc() && !copyInst->isTakeOfSrc())
1831+
CAI->setIsTakeOfSrc(IsNotTake);
1832+
}
1833+
use->set(copyInst->getSrc());
1834+
break;
1835+
}
18251836
case SILInstructionKind::StructElementAddrInst:
18261837
case SILInstructionKind::TupleElementAddrInst:
18271838
case SILInstructionKind::LoadInst:

0 commit comments

Comments
 (0)