@@ -194,9 +194,11 @@ void EscapeAnalysis::ConnectionGraph::mergeAllScheduledNodes() {
194
194
Defers->removeFromPreds (Predecessor (From, EdgeType::Defer));
195
195
}
196
196
// Redirect the incoming defer edges. This may trigger other node merges.
197
- for (Predecessor Pred : From->Preds ) {
198
- CGNode *PredNode = Pred.getPointer ();
199
- if (Pred.getInt () == EdgeType::Defer) {
197
+ // Note that the Pred iterator may be invalidated (because we may add
198
+ // edges in the loop). So we don't do: for (Pred : From->Preds) {...}
199
+ for (unsigned PredIdx = 0 ; PredIdx < From->Preds .size (); ++PredIdx) {
200
+ CGNode *PredNode = From->Preds [PredIdx].getPointer ();
201
+ if (From->Preds [PredIdx].getInt () == EdgeType::Defer) {
200
202
assert (PredNode != From && " defer edge may not form a self-cycle" );
201
203
addDeferEdge (PredNode, To);
202
204
}
@@ -206,32 +208,36 @@ void EscapeAnalysis::ConnectionGraph::mergeAllScheduledNodes() {
206
208
for (CGNode *Defers : From->defersTo ) {
207
209
addDeferEdge (To, Defers);
208
210
}
209
-
210
- // Ensure that graph invariance 4) is kept. At this point there may be still
211
- // some violations because of the new adjacent edges of the To node.
212
- for (Predecessor Pred : To->Preds ) {
213
- if (Pred.getInt () == EdgeType::PointsTo) {
214
- CGNode *PredNode = Pred.getPointer ();
215
- for (Predecessor PredOfPred : PredNode->Preds ) {
216
- if (PredOfPred.getInt () == EdgeType::Defer)
217
- updatePointsTo (PredOfPred.getPointer (), To);
218
- }
219
- for (CGNode *Def : PredNode->defersTo ) {
220
- updatePointsTo (Def, To);
211
+ // There is no point in updating the pointsTo if the To node will be
212
+ // merged to another node eventually.
213
+ if (!To->mergeTo ) {
214
+ // Ensure that graph invariance 4) is kept. At this point there may be still
215
+ // some violations because of the new adjacent edges of the To node.
216
+ for (unsigned PredIdx = 0 ; PredIdx < To->Preds .size (); ++PredIdx) {
217
+ if (To->Preds [PredIdx].getInt () == EdgeType::PointsTo) {
218
+ CGNode *PredNode = To->Preds [PredIdx].getPointer ();
219
+ for (unsigned PPIdx = 0 ; PPIdx < PredNode->Preds .size (); ++PPIdx) {
220
+ if (PredNode->Preds [PPIdx].getInt () == EdgeType::Defer)
221
+ updatePointsTo (PredNode->Preds [PPIdx].getPointer (), To);
222
+ }
223
+ for (CGNode *Def : PredNode->defersTo ) {
224
+ updatePointsTo (Def, To);
225
+ }
221
226
}
222
227
}
223
- }
224
- if (CGNode *ToPT = To->getPointsToEdge ()) {
225
- for (CGNode *ToDef : To->defersTo ) {
226
- updatePointsTo (ToDef, ToPT);
227
- }
228
- for (Predecessor Pred : To->Preds ) {
229
- if (Pred.getInt () == EdgeType::Defer)
230
- updatePointsTo (Pred.getPointer (), ToPT);
228
+ if (CGNode *ToPT = To->getPointsToEdge ()) {
229
+ ToPT = ToPT->getMergeTarget ();
230
+ for (CGNode *ToDef : To->defersTo ) {
231
+ updatePointsTo (ToDef, ToPT);
232
+ assert (!ToPT->mergeTo );
233
+ }
234
+ for (unsigned PredIdx = 0 ; PredIdx < To->Preds .size (); ++PredIdx) {
235
+ if (To->Preds [PredIdx].getInt () == EdgeType::Defer)
236
+ updatePointsTo (To->Preds [PredIdx].getPointer (), ToPT);
237
+ }
231
238
}
239
+ To->mergeEscapeState (From->State );
232
240
}
233
- To->mergeEscapeState (From->State );
234
-
235
241
// Cleanup the merged node.
236
242
From->isMerged = true ;
237
243
From->Preds .clear ();
@@ -243,10 +249,11 @@ void EscapeAnalysis::ConnectionGraph::mergeAllScheduledNodes() {
243
249
void EscapeAnalysis::ConnectionGraph::
244
250
updatePointsTo (CGNode *InitialNode, CGNode *pointsTo) {
245
251
// Visit all nodes in the defer web, which don't have the right pointsTo set.
252
+ assert (!pointsTo->mergeTo );
246
253
llvm::SmallVector<CGNode *, 8 > WorkList;
247
254
WorkList.push_back (InitialNode);
248
255
InitialNode->isInWorkList = true ;
249
- bool isInitialSet = (InitialNode-> pointsTo == nullptr ) ;
256
+ bool isInitialSet = false ;
250
257
for (unsigned Idx = 0 ; Idx < WorkList.size (); ++Idx) {
251
258
auto *Node = WorkList[Idx];
252
259
if (Node->pointsTo == pointsTo)
@@ -255,6 +262,8 @@ updatePointsTo(CGNode *InitialNode, CGNode *pointsTo) {
255
262
if (Node->pointsTo ) {
256
263
// Mismatching: we need to merge!
257
264
scheduleToMerge (Node->pointsTo , pointsTo);
265
+ } else {
266
+ isInitialSet = true ;
258
267
}
259
268
260
269
// If the node already has a pointsTo _edge_ we don't change it (we don't
@@ -265,8 +274,6 @@ updatePointsTo(CGNode *InitialNode, CGNode *pointsTo) {
265
274
// We create an edge to pointsTo (agreed, this changes the structure of
266
275
// the graph but adding this edge is harmless).
267
276
Node->setPointsTo (pointsTo);
268
- assert (isInitialSet &&
269
- " when replacing the points-to, there should already be an edge" );
270
277
} else {
271
278
Node->pointsTo = pointsTo;
272
279
}
0 commit comments