Skip to content

Commit 9de7e25

Browse files
authored
Merge pull request #78278 from slavapestov/optimize-connected-components
Sema: Optimize ConstraintGraph::computeConnectedComponents()
2 parents 419d87d + 0c128e5 commit 9de7e25

File tree

4 files changed

+126
-161
lines changed

4 files changed

+126
-161
lines changed

include/swift/Sema/ConstraintGraph.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -311,14 +311,6 @@ class ConstraintGraph {
311311
llvm::function_ref<bool(Constraint *)> acceptConstraint =
312312
[](Constraint *constraint) { return true; });
313313

314-
/// Retrieve the type variables that correspond to nodes in the graph.
315-
///
316-
/// The subscript operator can be used to retrieve the nodes that
317-
/// correspond to these type variables.
318-
ArrayRef<TypeVariableType *> getTypeVariables() const {
319-
return TypeVariables;
320-
}
321-
322314
/// Describes a single component, as produced by the connected components
323315
/// algorithm.
324316
struct Component {
@@ -462,9 +454,6 @@ class ConstraintGraph {
462454
/// The constraint system.
463455
ConstraintSystem &CS;
464456

465-
/// The type variables in this graph, in stable order.
466-
std::vector<TypeVariableType *> TypeVariables;
467-
468457
/// Constraints that are "orphaned" because they contain no type variables.
469458
SmallVector<Constraint *, 4> OrphanedConstraints;
470459

include/swift/Sema/ConstraintSystem.h

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "swift/Sema/SolutionResult.h"
4040
#include "swift/Sema/SyntacticElementTarget.h"
4141
#include "llvm/ADT/MapVector.h"
42+
#include "llvm/ADT/PointerIntPair.h"
4243
#include "llvm/ADT/PointerUnion.h"
4344
#include "llvm/ADT/STLExtras.h"
4445
#include "llvm/ADT/SetOperations.h"
@@ -339,21 +340,17 @@ class TypeVariableType::Implementation {
339340
/// The corresponding node in the constraint graph.
340341
constraints::ConstraintGraphNode *GraphNode = nullptr;
341342

342-
/// Index into the list of type variables, as used by the
343-
/// constraint graph.
344-
unsigned GraphIndex;
343+
/// Temporary state for ConstraintGraph::computeConnectedComponents(),
344+
/// stored inline for performance.
345+
llvm::PointerIntPair<TypeVariableType *, 1, unsigned> Component;
345346

346347
friend class constraints::SolverTrail;
347348

348349
public:
349350
/// Retrieve the type variable associated with this implementation.
350-
TypeVariableType *getTypeVariable() {
351-
return reinterpret_cast<TypeVariableType *>(this) - 1;
352-
}
353-
354-
/// Retrieve the type variable associated with this implementation.
355-
const TypeVariableType *getTypeVariable() const {
356-
return reinterpret_cast<const TypeVariableType *>(this) - 1;
351+
TypeVariableType *getTypeVariable() const {
352+
return reinterpret_cast<TypeVariableType *>(
353+
const_cast<Implementation *>(this)) - 1;
357354
}
358355

359356
explicit Implementation(constraints::ConstraintLocator *locator,
@@ -406,17 +403,6 @@ class TypeVariableType::Implementation {
406403
void setGraphNode(constraints::ConstraintGraphNode *newNode) {
407404
GraphNode = newNode;
408405
}
409-
410-
/// Retrieve the index into the constraint graph's list of type variables.
411-
unsigned getGraphIndex() const {
412-
assert(GraphNode && "Graph node isn't set");
413-
return GraphIndex;
414-
}
415-
416-
/// Set the index into the constraint graph's list of type variables.
417-
void setGraphIndex(unsigned newIndex) {
418-
GraphIndex = newIndex;
419-
}
420406

421407
/// Check whether this type variable either has a representative that
422408
/// is not itself or has a fixed type binding.
@@ -430,6 +416,12 @@ class TypeVariableType::Implementation {
430416
return ParentOrFixed.get<TypeVariableType *>() != getTypeVariable();
431417
}
432418

419+
/// Low-level accessor; use getRepresentative() or getFixedType() instead.
420+
llvm::PointerUnion<TypeVariableType *, TypeBase *>
421+
getRepresentativeOrFixed() const {
422+
return ParentOrFixed;
423+
}
424+
433425
/// Record the current type-variable binding.
434426
void recordBinding(constraints::SolverTrail &trail) {
435427
trail.recordChange(constraints::SolverTrail::Change::UpdatedTypeVariable(
@@ -647,6 +639,37 @@ class TypeVariableType::Implementation {
647639
impl.getTypeVariable()->Bits.TypeVariableType.Options |= TVO_CanBindToHole;
648640
}
649641

642+
void setComponent(TypeVariableType *parent) {
643+
Component.setPointerAndInt(parent, /*valid=*/false);
644+
}
645+
646+
TypeVariableType *getComponent() const {
647+
auto *rep = getTypeVariable();
648+
while (rep != rep->getImpl().Component.getPointer())
649+
rep = rep->getImpl().Component.getPointer();
650+
651+
// Path compression
652+
if (rep != getTypeVariable()) {
653+
const_cast<TypeVariableType::Implementation *>(this)
654+
->Component.setPointer(rep);
655+
}
656+
657+
return rep;
658+
}
659+
660+
bool isValidComponent() const {
661+
ASSERT(Component.getPointer() == getTypeVariable());
662+
return Component.getInt();
663+
}
664+
665+
bool markValidComponent() {
666+
if (Component.getInt())
667+
return false;
668+
ASSERT(Component.getPointer() == getTypeVariable());
669+
Component.setInt(1);
670+
return true;
671+
}
672+
650673
/// Print the type variable to the given output stream.
651674
void print(llvm::raw_ostream &OS);
652675

@@ -2339,7 +2362,7 @@ class ConstraintSystem {
23392362
ConstraintList InactiveConstraints;
23402363

23412364
/// The constraint graph.
2342-
ConstraintGraph &CG;
2365+
ConstraintGraph CG;
23432366

23442367
/// A mapping from constraint locators to the set of opened types associated
23452368
/// with that locator.
@@ -2707,7 +2730,7 @@ class ConstraintSystem {
27072730
~ConstraintSystem();
27082731

27092732
/// Retrieve the constraint graph associated with this constraint system.
2710-
ConstraintGraph &getConstraintGraph() const { return CG; }
2733+
ConstraintGraph &getConstraintGraph() { return CG; }
27112734

27122735
/// Retrieve the AST context.
27132736
ASTContext &getASTContext() const { return Context; }

0 commit comments

Comments
 (0)