Skip to content

Commit dc8dce7

Browse files
committed
EscapeAnalysis: some fixes and improvements in the basic graph utility functions.
1 parent 4a905b2 commit dc8dce7

File tree

1 file changed

+35
-28
lines changed

1 file changed

+35
-28
lines changed

lib/SILOptimizer/Analysis/EscapeAnalysis.cpp

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,11 @@ void EscapeAnalysis::ConnectionGraph::mergeAllScheduledNodes() {
194194
Defers->removeFromPreds(Predecessor(From, EdgeType::Defer));
195195
}
196196
// 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) {
200202
assert(PredNode != From && "defer edge may not form a self-cycle");
201203
addDeferEdge(PredNode, To);
202204
}
@@ -206,32 +208,36 @@ void EscapeAnalysis::ConnectionGraph::mergeAllScheduledNodes() {
206208
for (CGNode *Defers : From->defersTo) {
207209
addDeferEdge(To, Defers);
208210
}
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+
}
221226
}
222227
}
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+
}
231238
}
239+
To->mergeEscapeState(From->State);
232240
}
233-
To->mergeEscapeState(From->State);
234-
235241
// Cleanup the merged node.
236242
From->isMerged = true;
237243
From->Preds.clear();
@@ -243,10 +249,11 @@ void EscapeAnalysis::ConnectionGraph::mergeAllScheduledNodes() {
243249
void EscapeAnalysis::ConnectionGraph::
244250
updatePointsTo(CGNode *InitialNode, CGNode *pointsTo) {
245251
// Visit all nodes in the defer web, which don't have the right pointsTo set.
252+
assert(!pointsTo->mergeTo);
246253
llvm::SmallVector<CGNode *, 8> WorkList;
247254
WorkList.push_back(InitialNode);
248255
InitialNode->isInWorkList = true;
249-
bool isInitialSet = (InitialNode->pointsTo == nullptr);
256+
bool isInitialSet = false;
250257
for (unsigned Idx = 0; Idx < WorkList.size(); ++Idx) {
251258
auto *Node = WorkList[Idx];
252259
if (Node->pointsTo == pointsTo)
@@ -255,6 +262,8 @@ updatePointsTo(CGNode *InitialNode, CGNode *pointsTo) {
255262
if (Node->pointsTo) {
256263
// Mismatching: we need to merge!
257264
scheduleToMerge(Node->pointsTo, pointsTo);
265+
} else {
266+
isInitialSet = true;
258267
}
259268

260269
// 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) {
265274
// We create an edge to pointsTo (agreed, this changes the structure of
266275
// the graph but adding this edge is harmless).
267276
Node->setPointsTo(pointsTo);
268-
assert(isInitialSet &&
269-
"when replacing the points-to, there should already be an edge");
270277
} else {
271278
Node->pointsTo = pointsTo;
272279
}

0 commit comments

Comments
 (0)