mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Constraint graph] Add preVisit hook for depth-first search.
Refactoring so we can use this in a moment.
This commit is contained in:
@@ -814,19 +814,29 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a depth-first search to produce a from the given type variable,
|
/// Perform a depth-first search to produce a from the given type variable,
|
||||||
/// notifying the function object \c postVisit after each reachable
|
/// notifying the function object.
|
||||||
/// type variable has been visited.
|
///
|
||||||
|
/// \param getAdjacencies Called to retrieve the set of type variables
|
||||||
|
/// that are adjacent to the given type variable.
|
||||||
|
///
|
||||||
|
/// \param preVisit Called before visiting the adjacencies of the given
|
||||||
|
/// type variable. When it returns \c true, the adjacencies of this type
|
||||||
|
/// variable will be visited. When \c false, the adjacencies will not be
|
||||||
|
/// visited and \c postVisit will not be called.
|
||||||
|
///
|
||||||
|
/// \param postVisit Called after visiting the adjacencies of the given
|
||||||
|
/// type variable.
|
||||||
static void postorderDepthFirstSearchRec(
|
static void postorderDepthFirstSearchRec(
|
||||||
TypeVariableType *typeVar,
|
TypeVariableType *typeVar,
|
||||||
llvm::function_ref<
|
llvm::function_ref<
|
||||||
ArrayRef<TypeVariableType *>(TypeVariableType *)> getAdjacencies,
|
ArrayRef<TypeVariableType *>(TypeVariableType *)> getAdjacencies,
|
||||||
llvm::function_ref<void(TypeVariableType *)> postVisit,
|
llvm::function_ref<bool(TypeVariableType *)> preVisit,
|
||||||
SmallPtrSet<TypeVariableType *, 4> &visited) {
|
llvm::function_ref<void(TypeVariableType *)> postVisit) {
|
||||||
if (!visited.insert(typeVar).second)
|
if (!preVisit(typeVar))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto adj : getAdjacencies(typeVar)) {
|
for (auto adj : getAdjacencies(typeVar)) {
|
||||||
postorderDepthFirstSearchRec(adj, getAdjacencies, postVisit, visited);
|
postorderDepthFirstSearchRec(adj, getAdjacencies, preVisit, postVisit);
|
||||||
}
|
}
|
||||||
|
|
||||||
postVisit(typeVar);
|
postVisit(typeVar);
|
||||||
@@ -855,14 +865,16 @@ namespace {
|
|||||||
|
|
||||||
return oneWayComponent->second.inAdjacencies;
|
return oneWayComponent->second.inAdjacencies;
|
||||||
},
|
},
|
||||||
|
[&](TypeVariableType *typeVar) {
|
||||||
|
return visited.insert(typeVar).second;
|
||||||
|
},
|
||||||
[&](TypeVariableType *dependsOn) {
|
[&](TypeVariableType *dependsOn) {
|
||||||
// Don't record dependency on ourselves.
|
// Don't record dependency on ourselves.
|
||||||
if (dependsOn == inAdj)
|
if (dependsOn == inAdj)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
indirectlyReachable.insert(dependsOn);
|
indirectlyReachable.insert(dependsOn);
|
||||||
},
|
});
|
||||||
visited);
|
|
||||||
|
|
||||||
// Remove any in-adjacency of this component that is indirectly
|
// Remove any in-adjacency of this component that is indirectly
|
||||||
// reachable.
|
// reachable.
|
||||||
@@ -922,13 +934,15 @@ namespace {
|
|||||||
|
|
||||||
return oneWayComponent->second.outAdjacencies;
|
return oneWayComponent->second.outAdjacencies;
|
||||||
},
|
},
|
||||||
|
[&](TypeVariableType *typeVar) {
|
||||||
|
return visited.insert(typeVar).second;
|
||||||
|
},
|
||||||
[&](TypeVariableType *typeVar) {
|
[&](TypeVariableType *typeVar) {
|
||||||
// Record this type variable, if it's one of the representative
|
// Record this type variable, if it's one of the representative
|
||||||
// type variables.
|
// type variables.
|
||||||
if (validComponents.count(typeVar) > 0)
|
if (validComponents.count(typeVar) > 0)
|
||||||
orderedReps.push_back(typeVar);
|
orderedReps.push_back(typeVar);
|
||||||
},
|
});
|
||||||
visited);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(orderedReps.size() == representativeTypeVars.size());
|
assert(orderedReps.size() == representativeTypeVars.size());
|
||||||
|
|||||||
Reference in New Issue
Block a user