33
33
34
34
using namespace swift ;
35
35
36
- llvm::cl::opt<bool > DisableARCRRMotion (" disable-code-motion-arc" , llvm::cl::init(true ));
37
-
38
36
// ===----------------------------------------------------------------------===//
39
37
// ARC Matching Set Builder
40
38
// ===----------------------------------------------------------------------===//
@@ -43,7 +41,7 @@ llvm::cl::opt<bool> DisableARCRRMotion("disable-code-motion-arc", llvm::cl::init
43
41
// / were known safe.
44
42
Optional<MatchingSetFlags>
45
43
ARCMatchingSetBuilder::matchIncrementsToDecrements () {
46
- MatchingSetFlags Flags = {true , false };
44
+ MatchingSetFlags Flags = {true , true };
47
45
48
46
// For each increment in our list of new increments.
49
47
//
@@ -70,19 +68,16 @@ ARCMatchingSetBuilder::matchIncrementsToDecrements() {
70
68
}
71
69
72
70
// We need to be known safe over all increments/decrements we are matching
73
- // up
74
- // to ignore insertion points.
71
+ // up to ignore insertion points.
75
72
bool BUIsKnownSafe = (*BURefCountState)->second .isKnownSafe ();
76
73
DEBUG (llvm::dbgs () << " KNOWNSAFE: "
77
74
<< (BUIsKnownSafe ? " true" : " false" ) << " \n " );
78
75
Flags.KnownSafe &= BUIsKnownSafe;
79
76
80
- // We can only move instructions if we know that we are not partial. We can
81
- // still delete instructions in such cases though.
82
- bool BUIsPartial = (*BURefCountState)->second .isPartial ();
83
- DEBUG (llvm::dbgs () << " PARTIAL: "
84
- << (BUIsPartial ? " true" : " false" ) << " \n " );
85
- Flags.Partial |= BUIsPartial;
77
+ bool BUCodeMotionSafe = (*BURefCountState)->second .isCodeMotionSafe ();
78
+ DEBUG (llvm::dbgs () << " KNOWNSAFE: "
79
+ << (BUIsKnownSafe ? " true" : " false" ) << " \n " );
80
+ Flags.CodeMotionSafe &= BUCodeMotionSafe;
86
81
87
82
// Now that we know we have an inst, grab the decrement.
88
83
for (auto DecIter : (*BURefCountState)->second .getInstructions ()) {
@@ -103,8 +98,7 @@ ARCMatchingSetBuilder::matchIncrementsToDecrements() {
103
98
" decrement.\n " );
104
99
105
100
// Make sure the increment we are looking at is also matched to our
106
- // decrement.
107
- // Otherwise bail.
101
+ // decrement. Otherwise bail.
108
102
if (!(*TDRefCountState)->second .isTrackingRefCountInst () ||
109
103
!(*TDRefCountState)->second .containsInstruction (Increment)) {
110
104
DEBUG (
@@ -121,10 +115,6 @@ ARCMatchingSetBuilder::matchIncrementsToDecrements() {
121
115
continue ;
122
116
}
123
117
124
- // Collect the increment insertion point if it has one.
125
- for (auto InsertPt : (*TDRefCountState)->second .getInsertPts ()) {
126
- MatchSet.IncrementInsertPts .insert (InsertPt);
127
- }
128
118
NewDecrements.push_back (Decrement);
129
119
}
130
120
}
@@ -134,7 +124,7 @@ ARCMatchingSetBuilder::matchIncrementsToDecrements() {
134
124
135
125
Optional<MatchingSetFlags>
136
126
ARCMatchingSetBuilder::matchDecrementsToIncrements () {
137
- MatchingSetFlags Flags = {true , false };
127
+ MatchingSetFlags Flags = {true , true };
138
128
139
129
// For each increment in our list of new increments.
140
130
//
@@ -161,19 +151,16 @@ ARCMatchingSetBuilder::matchDecrementsToIncrements() {
161
151
}
162
152
163
153
// We need to be known safe over all increments/decrements we are matching
164
- // up
165
- // to ignore insertion points.
154
+ // up to ignore insertion points.
166
155
bool TDIsKnownSafe = (*TDRefCountState)->second .isKnownSafe ();
167
156
DEBUG (llvm::dbgs () << " KNOWNSAFE: "
168
157
<< (TDIsKnownSafe ? " true" : " false" ) << " \n " );
169
158
Flags.KnownSafe &= TDIsKnownSafe;
170
159
171
- // We can only move instructions if we know that we are not partial. We can
172
- // still delete instructions in such cases though.
173
- bool TDIsPartial = (*TDRefCountState)->second .isPartial ();
174
- DEBUG (llvm::dbgs () << " PARTIAL: "
175
- << (TDIsPartial ? " true" : " false" ) << " \n " );
176
- Flags.Partial |= TDIsPartial;
160
+ bool TDCodeMotionSafe = (*TDRefCountState)->second .isCodeMotionSafe ();
161
+ DEBUG (llvm::dbgs () << " KNOWNSAFE: "
162
+ << (TDIsKnownSafe ? " true" : " false" ) << " \n " );
163
+ Flags.CodeMotionSafe &= TDCodeMotionSafe;
177
164
178
165
// Now that we know we have an inst, grab the decrement.
179
166
for (auto IncIter : (*TDRefCountState)->second .getInstructions ()) {
@@ -213,10 +200,6 @@ ARCMatchingSetBuilder::matchDecrementsToIncrements() {
213
200
continue ;
214
201
}
215
202
216
- // Collect the decrement insertion point if we have one.
217
- for (auto InsertPtIter : (*BURefCountState)->second .getInsertPts ()) {
218
- MatchSet.DecrementInsertPts .insert (InsertPtIter);
219
- }
220
203
NewIncrements.push_back (Increment);
221
204
}
222
205
}
@@ -231,13 +214,13 @@ ARCMatchingSetBuilder::matchDecrementsToIncrements() {
231
214
bool ARCMatchingSetBuilder::matchUpIncDecSetsForPtr () {
232
215
bool KnownSafeTD = true ;
233
216
bool KnownSafeBU = true ;
234
- bool Partial = false ;
217
+ bool CodeMotionSafeTD = true ;
218
+ bool CodeMotionSafeBU = true ;
235
219
236
220
while (true ) {
237
221
DEBUG (llvm::dbgs () << " Attempting to match up increments -> decrements:\n " );
238
222
// For each increment in our list of new increments, attempt to match them
239
- // up
240
- // with decrements and gather the insertion points of the decrements.
223
+ // up with decrements and gather the insertion points of the decrements.
241
224
auto Result = matchIncrementsToDecrements ();
242
225
if (!Result) {
243
226
DEBUG (llvm::dbgs () << " FAILED TO MATCH INCREMENTS -> DECREMENTS!\n " );
@@ -247,10 +230,11 @@ bool ARCMatchingSetBuilder::matchUpIncDecSetsForPtr() {
247
230
DEBUG (llvm::dbgs () << " NOT KNOWN SAFE!\n " );
248
231
KnownSafeTD = false ;
249
232
}
250
- if (Result->Partial ) {
251
- DEBUG (llvm::dbgs () << " IS PARTIAL !\n " );
252
- Partial = true ;
233
+ if (! Result->CodeMotionSafe ) {
234
+ DEBUG (llvm::dbgs () << " NOT CODE MOTION SAFE !\n " );
235
+ CodeMotionSafeTD = false ;
253
236
}
237
+
254
238
NewIncrements.clear ();
255
239
256
240
// If we do not have any decrements to attempt to match up with, bail.
@@ -267,9 +251,9 @@ bool ARCMatchingSetBuilder::matchUpIncDecSetsForPtr() {
267
251
DEBUG (llvm::dbgs () << " NOT KNOWN SAFE!\n " );
268
252
KnownSafeBU = false ;
269
253
}
270
- if (Result->Partial ) {
271
- DEBUG (llvm::dbgs () << " IS PARTIAL !\n " );
272
- Partial = true ;
254
+ if (! Result->CodeMotionSafe ) {
255
+ DEBUG (llvm::dbgs () << " NOT CODE MOTION SAFE !\n " );
256
+ CodeMotionSafeBU = false ;
273
257
}
274
258
NewDecrements.clear ();
275
259
@@ -278,42 +262,29 @@ bool ARCMatchingSetBuilder::matchUpIncDecSetsForPtr() {
278
262
break ;
279
263
}
280
264
265
+ // There is no way we can get a top-down code motion but not a bottom-up, or vice
266
+ // versa.
267
+ assert (CodeMotionSafeTD == CodeMotionSafeBU && " Asymmetric code motion safety" );
268
+
281
269
bool UnconditionallySafe = (KnownSafeTD && KnownSafeBU);
282
- if (UnconditionallySafe) {
283
- DEBUG (llvm::dbgs () << " UNCONDITIONALLY SAFE! DELETING INSTS.\n " );
284
- MatchSet.IncrementInsertPts .clear ();
285
- MatchSet.DecrementInsertPts .clear ();
270
+ bool CodeMotionSafe = (CodeMotionSafeTD && CodeMotionSafeBU);
271
+ if (UnconditionallySafe || CodeMotionSafe) {
272
+ DEBUG (llvm::dbgs () << " UNCONDITIONALLY OR CODE MOTION SAFE! DELETING INSTS.\n " );
286
273
} else {
287
- DEBUG (llvm::dbgs () << " NOT UNCONDITIONALLY SAFE!\n " );
288
- }
289
-
290
- bool HaveIncInsertPts = !MatchSet.IncrementInsertPts .empty ();
291
- bool HaveDecInsertPts = !MatchSet.DecrementInsertPts .empty ();
292
-
293
- // We should not have the case which retains have to be anchored topdown and
294
- // releases do not have to be bottomup, or vice-versa.
295
- assert (HaveIncInsertPts == HaveDecInsertPts &&
296
- " Asymmetric insertion points for retains and releases" );
297
-
298
- bool CodeMotionBlocked = HaveIncInsertPts || HaveDecInsertPts;
299
- if (DisableARCRRMotion && CodeMotionBlocked && !UnconditionallySafe) {
300
- DEBUG (llvm::dbgs () << " Code motion blocked. Bailing!\n " );
274
+ DEBUG (llvm::dbgs () << " NOT UNCONDITIONALLY SAFE AND CODE MOTION BLOCKED!\n " );
301
275
return false ;
302
276
}
303
277
304
- // If we have insertion points and partial merges, return false to avoid
305
- // control dependency issues.
306
- if ((HaveIncInsertPts || HaveDecInsertPts) && Partial) {
307
- DEBUG (llvm::dbgs () << " Found partial merge and insert pts. Bailing!\n " );
308
- return false ;
309
- }
278
+ // Make sure we always have increments and decrements in the match set.
279
+ assert (MatchSet.Increments .empty () == MatchSet.Decrements .empty () &&
280
+ " Match set without increments or decrements" );
310
281
311
282
// If we do not have any insertion points but we do have increments, we must
312
283
// be eliminating pairs.
313
- if (!HaveIncInsertPts && ! MatchSet.Increments .empty ())
284
+ if (!MatchSet.Increments .empty ())
314
285
MatchedPair = true ;
315
286
316
287
// Success!
317
- DEBUG (llvm::dbgs () << " SUCCESS! We can move, remove things.\n " );
288
+ DEBUG (llvm::dbgs () << " SUCCESS! We can remove things.\n " );
318
289
return true ;
319
290
}
0 commit comments