Skip to content

Commit 9e67408

Browse files
committed
MemoryLifetime: Make the dataflow solving functions of MemoryDataflow more flexible.
Add the possibility to solve with a custom join operator.
1 parent 8b11e7c commit 9e67408

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
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;

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.

0 commit comments

Comments
 (0)