Skip to content

Commit 3bfe8a6

Browse files
authored
Merge pull request #27663 from eeckstein/dse
DeadStoreElimination: don't require values stored back to memory if the control flow ends in an unreachable
2 parents 07c0e2a + f372d70 commit 3bfe8a6

File tree

4 files changed

+75
-14
lines changed

4 files changed

+75
-14
lines changed

include/swift/SIL/MemoryLifetime.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@
2222

2323
namespace swift {
2424

25+
void printBitsAsArray(llvm::raw_ostream &OS, const SmallBitVector &bits);
26+
27+
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
28+
const SmallBitVector &bits) {
29+
printBitsAsArray(OS, bits);
30+
return OS;
31+
}
32+
33+
void dumpBits(const SmallBitVector &bits);
34+
2535
/// The MemoryLocations utility provides functions to analyze memory locations.
2636
///
2737
/// Memory locations are limited to addresses which are guaranteed to

lib/SIL/MemoryLifetime.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,28 @@ llvm::cl::opt<bool> DontAbortOnMemoryLifetimeErrors(
2828
llvm::cl::desc("Don't abort compliation if the memory lifetime checker "
2929
"detects an error."));
3030

31-
namespace swift {
32-
namespace {
33-
34-
//===----------------------------------------------------------------------===//
35-
// Utility functions
36-
//===----------------------------------------------------------------------===//
37-
3831
/// Debug dump a location bit vector.
39-
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
40-
const SmallBitVector &bits) {
32+
void swift::printBitsAsArray(llvm::raw_ostream &OS, const SmallBitVector &bits) {
4133
const char *separator = "";
4234
OS << '[';
4335
for (int idx = bits.find_first(); idx >= 0; idx = bits.find_next(idx)) {
4436
OS << separator << idx;
4537
separator = ",";
4638
}
4739
OS << ']';
48-
return OS;
4940
}
5041

42+
void swift::dumpBits(const SmallBitVector &bits) {
43+
llvm::dbgs() << bits << '\n';
44+
}
45+
46+
namespace swift {
47+
namespace {
48+
49+
//===----------------------------------------------------------------------===//
50+
// Utility functions
51+
//===----------------------------------------------------------------------===//
52+
5153
/// Enlarge the bitset if needed to set the bit with \p idx.
5254
static void setBitAndResize(SmallBitVector &bits, unsigned idx) {
5355
if (bits.size() <= idx)
@@ -240,10 +242,6 @@ void MemoryLocations::dump() const {
240242
}
241243
}
242244

243-
void MemoryLocations::dumpBits(const Bits &bits) {
244-
llvm::errs() << bits << '\n';
245-
}
246-
247245
void MemoryLocations::clear() {
248246
locations.clear();
249247
addr2LocIdx.clear();

lib/SILOptimizer/Transforms/DeadStoreElimination.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include "swift/SIL/Projection.h"
6161
#include "swift/SIL/SILArgument.h"
6262
#include "swift/SIL/SILBuilder.h"
63+
#include "swift/SIL/MemoryLifetime.h"
6364
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
6465
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
6566
#include "swift/SILOptimizer/PassManager/Passes.h"
@@ -269,6 +270,8 @@ class BlockState {
269270
init(LocationNum, Optimistic);
270271
}
271272

273+
void dump();
274+
272275
/// Initialize the bitvectors for the current basic block.
273276
void init(unsigned LocationNum, bool Optimistic);
274277

@@ -448,6 +451,8 @@ enum class ProcessKind {
448451
llvm::SpecificBumpPtrAllocator<BlockState> &BPA)
449452
: Mod(M), F(F), PM(PM), AA(AA), TE(TE), EAFI(EAFI), BPA(BPA) {}
450453

454+
void dump();
455+
451456
/// Entry point for dead store elimination.
452457
bool run();
453458

@@ -481,6 +486,12 @@ enum class ProcessKind {
481486

482487
} // end anonymous namespace
483488

489+
void BlockState::dump() {
490+
llvm::dbgs() << " block " << BB->getDebugID() << ": in=" << BBWriteSetIn
491+
<< ", out=" << BBWriteSetOut << ", mid=" << BBWriteSetMid
492+
<< ", gen=" << BBGenSet << ", kill=" << BBKillSet << '\n';
493+
}
494+
484495
void BlockState::init(unsigned LocationNum, bool Optimistic) {
485496
// For function that requires just 1 iteration of the data flow to converge
486497
// we set the initial state of BBWriteSetIn to 0.
@@ -513,6 +524,21 @@ void BlockState::init(unsigned LocationNum, bool Optimistic) {
513524
BBDeallocateLocation.resize(LocationNum, false);
514525
}
515526

527+
#if __has_attribute(used)
528+
__attribute((used))
529+
#endif
530+
void DSEContext::dump() {
531+
llvm::dbgs() << "Locations:\n";
532+
unsigned idx = 0;
533+
for (const LSLocation &loc : LocationVault) {
534+
llvm::dbgs() << " #" << idx << ": " << loc.getBase();
535+
++idx;
536+
}
537+
for (SILBasicBlock &BB : *F) {
538+
getBlockState(&BB)->dump();
539+
}
540+
}
541+
516542
unsigned DSEContext::getLocationBit(const LSLocation &Loc) {
517543
// Return the bit position of the given Loc in the LocationVault. The bit
518544
// position is then used to set/reset the bitvector kept by each BlockState.
@@ -691,6 +717,10 @@ void DSEContext::mergeSuccessorLiveIns(SILBasicBlock *BB) {
691717
// dead for block with no successor.
692718
BlockState *C = getBlockState(BB);
693719
if (BB->succ_empty()) {
720+
if (isa<UnreachableInst>(BB->getTerminator())) {
721+
C->BBWriteSetOut.set();
722+
return;
723+
}
694724
C->BBWriteSetOut |= C->BBDeallocateLocation;
695725
return;
696726
}

test/SILOptimizer/dead_store_elim.sil

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,29 @@ bb3:
291291
return %9999 : $()
292292
}
293293

294+
// CHECK-LABEL: sil @handle_unreachable : $@convention(thin) (@inout Builtin.Int32) -> () {
295+
// CHECK: bb0
296+
// CHECK-NEXT: integer_literal
297+
// CHECK-NEXT: cond_br
298+
// CHECK: return
299+
sil @handle_unreachable : $@convention(thin) (@inout Builtin.Int32) -> () {
300+
bb0(%0 : $*Builtin.Int32):
301+
%1 = integer_literal $Builtin.Int32, 0
302+
store %1 to %0 : $*Builtin.Int32
303+
cond_br undef, bb1, bb2
304+
305+
bb1:
306+
unreachable
307+
308+
bb2:
309+
br bb3
310+
311+
bb3:
312+
store %1 to %0 : $*Builtin.Int32
313+
%9999 = tuple()
314+
return %9999 : $()
315+
}
316+
294317
// CHECK-LABEL: sil @post_dominating_dead_store_partial : $@convention(thin) (@inout Builtin.Int32) -> () {
295318
// CHECK: bb0(
296319
// CHECK-NOT: {{ store}}

0 commit comments

Comments
 (0)