@@ -52,6 +52,64 @@ using namespace swift::siloptimizer::borrowtodestructure;
52
52
// MARK: Utilities
53
53
// ===----------------------------------------------------------------------===//
54
54
55
+ // / Return a loc that can be used regardless if \p inst is a terminator or not.
56
+ static SILLocation getSafeLoc (SILInstruction *inst) {
57
+ if (isa<TermInst>(inst))
58
+ return RegularLocation::getDiagnosticsOnlyLocation (inst->getLoc (),
59
+ inst->getModule ());
60
+ return inst->getLoc ();
61
+ }
62
+
63
+ // ===----------------------------------------------------------------------===//
64
+ // MARK: Available Values
65
+ // ===----------------------------------------------------------------------===//
66
+
67
+ namespace {
68
+
69
+ // We reserve more bits that we need at the beginning so that we can avoid
70
+ // reallocating and potentially breaking our internal mutable array ref
71
+ // points into the data store.
72
+ struct AvailableValues {
73
+ MutableArrayRef<SILValue> values;
74
+
75
+ SILValue operator [](unsigned index) const { return values[index]; }
76
+ SILValue &operator [](unsigned index) { return values[index]; }
77
+ unsigned size () const { return values.size (); }
78
+
79
+ AvailableValues () : values() {}
80
+ AvailableValues (MutableArrayRef<SILValue> values) : values(values) {}
81
+
82
+ void print (llvm::raw_ostream &os, const char *prefix = nullptr ) const ;
83
+ SWIFT_DEBUG_DUMP;
84
+ };
85
+
86
+ struct AvailableValueStore {
87
+ std::vector<SILValue> dataStore;
88
+ llvm::DenseMap<SILBasicBlock *, AvailableValues> blockToValues;
89
+ unsigned nextOffset = 0 ;
90
+ unsigned numBits;
91
+
92
+ AvailableValueStore (const FieldSensitivePrunedLiveness &liveness)
93
+ : dataStore(liveness.getDiscoveredBlocks().size() *
94
+ liveness.getNumSubElements()),
95
+ numBits (liveness.getNumSubElements()) {}
96
+
97
+ std::pair<AvailableValues *, bool > get (SILBasicBlock *block) {
98
+ auto iter = blockToValues.try_emplace (block, AvailableValues ());
99
+
100
+ if (!iter.second ) {
101
+ return {&iter.first ->second , false };
102
+ }
103
+
104
+ iter.first ->second .values =
105
+ MutableArrayRef<SILValue>(&dataStore[nextOffset], numBits);
106
+ nextOffset += numBits;
107
+ return {&iter.first ->second , true };
108
+ }
109
+ };
110
+
111
+ } // namespace
112
+
55
113
void AvailableValues::print (llvm::raw_ostream &os, const char *prefix) const {
56
114
if (prefix)
57
115
os << prefix;
@@ -70,21 +128,18 @@ void AvailableValues::print(llvm::raw_ostream &os, const char *prefix) const {
70
128
71
129
void AvailableValues::dump () const { print (llvm::dbgs (), nullptr ); }
72
130
73
- // / Return a loc that can be used regardless if \p inst is a terminator or not.
74
- static SILLocation getSafeLoc (SILInstruction *inst) {
75
- if (isa<TermInst>(inst))
76
- return RegularLocation::getDiagnosticsOnlyLocation (inst->getLoc (),
77
- inst->getModule ());
78
- return inst->getLoc ();
79
- }
80
-
81
131
// ===----------------------------------------------------------------------===//
82
132
// MARK: Private Implementation
83
133
// ===----------------------------------------------------------------------===//
84
134
85
135
struct borrowtodestructure ::Implementation {
86
136
BorrowToDestructureTransform &interface;
87
137
138
+ Optional<AvailableValueStore> blockToAvailableValues;
139
+
140
+ Implementation (BorrowToDestructureTransform &interface)
141
+ : interface(interface) {}
142
+
88
143
bool gatherUses (SILValue value);
89
144
90
145
// / Once we have gathered up all of our destructure uses and liveness
@@ -654,7 +709,7 @@ AvailableValues &Implementation::computeAvailableValues(SILBasicBlock *block) {
654
709
// First grab our block. If we already have state for the block, just return
655
710
// its available values. We already computed the available values and
656
711
// potentially updated it with new destructured values for our block.
657
- auto pair = interface. blockToAvailableValues ->get (block);
712
+ auto pair = blockToAvailableValues->get (block);
658
713
if (!pair.second ) {
659
714
LLVM_DEBUG (llvm::dbgs ()
660
715
<< " Already have values! Returning them!\n " );
@@ -1535,7 +1590,7 @@ bool BorrowToDestructureTransform::transform() {
1535
1590
1536
1591
// Attempt to gather uses. Return false if we saw something that we did not
1537
1592
// understand.
1538
- Implementation impl{ *this } ;
1593
+ Implementation impl ( *this ) ;
1539
1594
for (auto *bbi : borrowWorklist) {
1540
1595
if (!impl.gatherUses (bbi))
1541
1596
return false ;
@@ -1568,7 +1623,7 @@ bool BorrowToDestructureTransform::transform() {
1568
1623
1569
1624
// At this point, we know that all of our destructure requiring uses are on
1570
1625
// the boundary of our live range. Now we need to do the rewriting.
1571
- blockToAvailableValues.emplace (*liveness);
1626
+ impl. blockToAvailableValues .emplace (*liveness);
1572
1627
impl.rewriteUses ();
1573
1628
1574
1629
// Now that we have done our rewritting, we need to do a few cleanups.
0 commit comments