@@ -123,44 +123,52 @@ class ElementUseCollector {
123
123
} // end anonymous namespace
124
124
125
125
bool ElementUseCollector::collectFrom () {
126
- bool shouldOptimize = false ;
127
-
128
- if (auto *ABI = TheMemory.getContainer ()) {
129
- shouldOptimize = collectContainerUses (ABI);
130
- } else {
131
- shouldOptimize = collectUses (TheMemory.getAddress ());
132
- }
133
-
134
- if (!shouldOptimize)
135
- return false ;
136
-
137
- // Collect information about the retain count result as well.
138
- for (auto *op : TheMemory.MemoryInst ->getUses ()) {
139
- auto *user = op->getUser ();
140
-
141
- // If this is a strong_release, stash it.
142
- if (isa<StrongReleaseInst>(user)) {
143
- Releases.push_back (user);
144
- }
126
+ if (auto *abi = TheMemory.getContainer ()) {
127
+ return collectContainerUses (abi);
145
128
}
146
129
147
- return true ;
130
+ return collectUses (TheMemory. getAddress ()) ;
148
131
}
149
132
150
- bool ElementUseCollector::collectContainerUses (AllocBoxInst *ABI ) {
151
- for (Operand *UI : ABI ->getUses ()) {
152
- auto *User = UI ->getUser ();
133
+ bool ElementUseCollector::collectContainerUses (AllocBoxInst *abi ) {
134
+ for (auto *ui : abi ->getUses ()) {
135
+ auto *user = ui ->getUser ();
153
136
154
- // Deallocations and retain/release don't affect the value directly.
155
- if (isa<DeallocBoxInst>(User))
137
+ // dealloc_box deallocated a box containing uninitialized memory. This can
138
+ // not effect any value stored into the box.
139
+ if (isa<DeallocBoxInst>(user))
156
140
continue ;
157
- if (isa<StrongRetainInst>(User))
141
+
142
+ // Retaining the box doesn't effect the value inside the box.
143
+ if (isa<StrongRetainInst>(user) || isa<RetainValueInst>(user))
158
144
continue ;
159
- if (isa<StrongReleaseInst>(User))
145
+
146
+ // Since we are trying to promote loads/stores, any releases of the box are
147
+ // not considered uses of the underlying value due to:
148
+ //
149
+ // 1. If this is not the last release of the box, then the underlying value
150
+ // is not effected implying we do not add this value.
151
+ //
152
+ // 2. If this is the last release of the box, then the box's destruction
153
+ // will result in a release of the underlying value. If there are any
154
+ // loads/stores after this point, the behavior would be undefined so we can
155
+ // ignore this possibility.
156
+ //
157
+ // That being said, if we want to eliminate the box completely we need to
158
+ // know where the releases are so that we can release the value that would
159
+ // have been at +1 in the box at that time. So we add these to the Releases
160
+ // array.
161
+ //
162
+ // FIXME: Since we do not support promoting strong_release or release_value
163
+ // today this will cause the underlying allocation to never be
164
+ // eliminated. That should be implemented and fixed.
165
+ if (isa<StrongReleaseInst>(user) || isa<ReleaseValueInst>(user)) {
166
+ Releases.push_back (user);
160
167
continue ;
168
+ }
161
169
162
- if (auto project = dyn_cast<ProjectBoxInst>(User )) {
163
- if (!collectUses (project ))
170
+ if (auto *p = dyn_cast<ProjectBoxInst>(user )) {
171
+ if (!collectUses (p ))
164
172
return false ;
165
173
continue ;
166
174
}
@@ -170,7 +178,7 @@ bool ElementUseCollector::collectContainerUses(AllocBoxInst *ABI) {
170
178
//
171
179
// This will cause the dataflow to stop propagating any information at the
172
180
// use block.
173
- Uses.emplace_back (User , PMOUseKind::Escape);
181
+ Uses.emplace_back (user , PMOUseKind::Escape);
174
182
}
175
183
176
184
return true ;
0 commit comments