Skip to content

Commit 286f975

Browse files
authored
Merge pull request #82320 from xedin/hide-solver-hacks-behind-a-flag
[ConstraintSystem] Guard all the performance hacks with a flag
2 parents d526a2f + fc573b6 commit 286f975

File tree

13 files changed

+65
-65
lines changed

13 files changed

+65
-65
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -983,9 +983,6 @@ namespace swift {
983983
/// is for testing purposes.
984984
std::vector<std::string> DebugForbidTypecheckPrefixes;
985985

986-
/// Disable the shrink phase of the expression type checker.
987-
bool SolverDisableShrink = false;
988-
989986
/// Enable experimental operator designated types feature.
990987
bool EnableOperatorDesignatedTypes = false;
991988

include/swift/Option/FrontendOptions.td

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -856,10 +856,6 @@ def solver_scope_threshold_EQ : Joined<["-"], "solver-scope-threshold=">,
856856
def solver_trail_threshold_EQ : Joined<["-"], "solver-trail-threshold=">,
857857
HelpText<"Expression type checking trail change limit">;
858858

859-
def solver_disable_shrink :
860-
Flag<["-"], "solver-disable-shrink">,
861-
HelpText<"Disable the shrink phase of expression type checking">;
862-
863859
def solver_disable_splitter : Flag<["-"], "solver-disable-splitter">,
864860
HelpText<"Disable the component splitter phase of expression type checking">;
865861

include/swift/Sema/ConstraintSystem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3586,6 +3586,13 @@ class ConstraintSystem {
35863586
return Options.contains(ConstraintSystemFlags::ForCodeCompletion);
35873587
}
35883588

3589+
/// Check whether type-checker performance hacks has been explicitly
3590+
/// disabled by a flag.
3591+
bool performanceHacksEnabled() const {
3592+
return !getASTContext()
3593+
.TypeCheckerOpts.DisableConstraintSolverPerformanceHacks;
3594+
}
3595+
35893596
/// Log and record the application of the fix. Return true iff any
35903597
/// subsequent solution would be worse than the best known solution.
35913598
bool recordFix(ConstraintFix *fix, unsigned impact = 1);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,9 +2037,6 @@ static bool ParseTypeCheckerArgs(TypeCheckerOptions &Opts, ArgList &Args,
20372037
Opts.DebugForbidTypecheckPrefixes.push_back(A);
20382038
}
20392039

2040-
if (Args.getLastArg(OPT_solver_disable_shrink))
2041-
Opts.SolverDisableShrink = true;
2042-
20432040
if (Args.getLastArg(OPT_solver_disable_splitter))
20442041
Opts.SolverDisableSplitter = true;
20452042

lib/Sema/CSGen.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,11 +1168,13 @@ namespace {
11681168
/*trailingClosureMatching=*/std::nullopt,
11691169
CurDC, fnLocator);
11701170

1171-
Type fixedOutputType =
1172-
CS.getFixedTypeRecursive(outputTy, /*wantRValue=*/false);
1173-
if (!fixedOutputType->isTypeVariableOrMember()) {
1174-
CS.setFavoredType(anchor, fixedOutputType.getPointer());
1175-
outputTy = fixedOutputType;
1171+
if (CS.performanceHacksEnabled()) {
1172+
Type fixedOutputType =
1173+
CS.getFixedTypeRecursive(outputTy, /*wantRValue=*/false);
1174+
if (!fixedOutputType->isTypeVariableOrMember()) {
1175+
CS.setFavoredType(anchor, fixedOutputType.getPointer());
1176+
outputTy = fixedOutputType;
1177+
}
11761178
}
11771179

11781180
return outputTy;
@@ -1614,9 +1616,11 @@ namespace {
16141616
}
16151617
}
16161618

1617-
if (!knownType->hasPlaceholder()) {
1618-
// Set the favored type for this expression to the known type.
1619-
CS.setFavoredType(E, knownType.getPointer());
1619+
if (CS.performanceHacksEnabled()) {
1620+
if (!knownType->hasPlaceholder()) {
1621+
// Set the favored type for this expression to the known type.
1622+
CS.setFavoredType(E, knownType.getPointer());
1623+
}
16201624
}
16211625
}
16221626
}
@@ -2089,8 +2093,10 @@ namespace {
20892093
CS.getASTContext());
20902094
}
20912095

2092-
if (auto favoredTy = CS.getFavoredType(expr->getSubExpr())) {
2093-
CS.setFavoredType(expr, favoredTy);
2096+
if (CS.performanceHacksEnabled()) {
2097+
if (auto favoredTy = CS.getFavoredType(expr->getSubExpr())) {
2098+
CS.setFavoredType(expr, favoredTy);
2099+
}
20942100
}
20952101
return CS.getType(expr->getSubExpr());
20962102
}
@@ -3377,11 +3383,13 @@ namespace {
33773383

33783384
// If we ended up resolving the result type variable to a concrete type,
33793385
// set it as the favored type for this expression.
3380-
Type fixedType =
3381-
CS.getFixedTypeRecursive(resultType, /*wantRvalue=*/true);
3382-
if (!fixedType->isTypeVariableOrMember()) {
3383-
CS.setFavoredType(expr, fixedType.getPointer());
3384-
resultType = fixedType;
3386+
if (CS.performanceHacksEnabled()) {
3387+
Type fixedType =
3388+
CS.getFixedTypeRecursive(resultType, /*wantRvalue=*/true);
3389+
if (!fixedType->isTypeVariableOrMember()) {
3390+
CS.setFavoredType(expr, fixedType.getPointer());
3391+
resultType = fixedType;
3392+
}
33853393
}
33863394

33873395
return resultType;
@@ -5175,7 +5183,7 @@ ConstraintSystem::applyPropertyWrapperToParameter(
51755183
}
51765184

51775185
void ConstraintSystem::optimizeConstraints(Expr *e) {
5178-
if (getASTContext().TypeCheckerOpts.DisableConstraintSolverPerformanceHacks)
5186+
if (!performanceHacksEnabled())
51795187
return;
51805188

51815189
SmallVector<Expr *, 16> linkedExprs;

lib/Sema/CSRanking.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,6 @@ void ConstraintSystem::clearScore() {
168168
}
169169

170170
bool ConstraintSystem::worseThanBestSolution() const {
171-
if (getASTContext().TypeCheckerOpts.DisableConstraintSolverPerformanceHacks)
172-
return false;
173-
174171
if (!solverState || !solverState->BestScore ||
175172
CurrentScore <= *solverState->BestScore)
176173
return false;

lib/Sema/CSSimplify.cpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10200,13 +10200,15 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1020010200
if (path.back().getKind() == ConstraintLocator::ConstructorMember)
1020110201
isImplicitInit = true;
1020210202

10203-
if (auto *applyExpr = getAsExpr<ApplyExpr>(anchor)) {
10204-
if (auto *argExpr = applyExpr->getArgs()->getUnlabeledUnaryExpr()) {
10205-
favoredType = getFavoredType(argExpr);
10206-
10207-
if (!favoredType) {
10208-
optimizeConstraints(argExpr);
10203+
if (performanceHacksEnabled()) {
10204+
if (auto *applyExpr = getAsExpr<ApplyExpr>(anchor)) {
10205+
if (auto *argExpr = applyExpr->getArgs()->getUnlabeledUnaryExpr()) {
1020910206
favoredType = getFavoredType(argExpr);
10207+
10208+
if (!favoredType) {
10209+
optimizeConstraints(argExpr);
10210+
favoredType = getFavoredType(argExpr);
10211+
}
1021010212
}
1021110213
}
1021210214
}
@@ -10321,22 +10323,24 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1032110323
// If the invocation's argument expression has a favored type,
1032210324
// use that information to determine whether a specific overload for
1032310325
// the candidate should be favored.
10324-
if (isa<ConstructorDecl>(decl) && favoredType &&
10325-
result.FavoredChoice == ~0U) {
10326-
auto *ctor = cast<ConstructorDecl>(decl);
10327-
10328-
// Only try and favor monomorphic unary initializers.
10329-
if (!ctor->isGenericContext()) {
10330-
if (!ctor->getMethodInterfaceType()->hasError()) {
10331-
// The constructor might have an error type because we don't skip
10332-
// invalid decls for code completion
10333-
auto args = ctor->getMethodInterfaceType()
10334-
->castTo<FunctionType>()
10335-
->getParams();
10336-
if (args.size() == 1 && !args[0].hasLabel() &&
10337-
args[0].getPlainType()->isEqual(favoredType)) {
10338-
if (!isDeclUnavailable(decl, memberLocator))
10339-
result.FavoredChoice = result.ViableCandidates.size();
10326+
if (performanceHacksEnabled()) {
10327+
if (isa<ConstructorDecl>(decl) && favoredType &&
10328+
result.FavoredChoice == ~0U) {
10329+
auto *ctor = cast<ConstructorDecl>(decl);
10330+
10331+
// Only try and favor monomorphic unary initializers.
10332+
if (!ctor->isGenericContext()) {
10333+
if (!ctor->getMethodInterfaceType()->hasError()) {
10334+
// The constructor might have an error type because we don't skip
10335+
// invalid decls for code completion
10336+
auto args = ctor->getMethodInterfaceType()
10337+
->castTo<FunctionType>()
10338+
->getParams();
10339+
if (args.size() == 1 && !args[0].hasLabel() &&
10340+
args[0].getPlainType()->isEqual(favoredType)) {
10341+
if (!isDeclUnavailable(decl, memberLocator))
10342+
result.FavoredChoice = result.ViableCandidates.size();
10343+
}
1034010344
}
1034110345
}
1034210346
}

lib/Sema/CSSolver.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ Solution ConstraintSystem::finalize() {
7474

7575
// Update the best score we've seen so far.
7676
auto &ctx = getASTContext();
77-
assert(ctx.TypeCheckerOpts.DisableConstraintSolverPerformanceHacks ||
78-
!solverState->BestScore || CurrentScore <= *solverState->BestScore);
77+
assert(!solverState->BestScore || CurrentScore <= *solverState->BestScore);
7978

8079
if (!solverState->BestScore || CurrentScore <= *solverState->BestScore) {
8180
solverState->BestScore = CurrentScore;
@@ -979,7 +978,7 @@ void ConstraintSystem::Candidate::applySolutions(
979978
}
980979

981980
void ConstraintSystem::shrink(Expr *expr) {
982-
if (getASTContext().TypeCheckerOpts.SolverDisableShrink)
981+
if (!performanceHacksEnabled())
983982
return;
984983

985984
using DomainMap = llvm::SmallDenseMap<Expr *, ArrayRef<ValueDecl *>>;

lib/Sema/CSStep.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -638,9 +638,6 @@ bool DisjunctionStep::shouldSkip(const DisjunctionChoice &choice) const {
638638
if (choice.isUnavailable() && !CS.shouldAttemptFixes())
639639
return skip("unavailable");
640640

641-
if (ctx.TypeCheckerOpts.DisableConstraintSolverPerformanceHacks)
642-
return false;
643-
644641
// If the solver already found a solution with a better overload choice that
645642
// can be unconditionally substituted by the current choice, skip the current
646643
// choice.
@@ -726,15 +723,10 @@ bool swift::isSIMDOperator(ValueDecl *value) {
726723

727724
bool DisjunctionStep::shortCircuitDisjunctionAt(
728725
Constraint *currentChoice, Constraint *lastSuccessfulChoice) const {
729-
auto &ctx = CS.getASTContext();
730-
731726
// Anything without a fix is better than anything with a fix.
732727
if (currentChoice->getFix() && !lastSuccessfulChoice->getFix())
733728
return true;
734729

735-
if (ctx.TypeCheckerOpts.DisableConstraintSolverPerformanceHacks)
736-
return false;
737-
738730
if (auto restriction = currentChoice->getRestriction()) {
739731
// Non-optional conversions are better than optional-to-optional
740732
// conversions.

lib/Sema/CSStep.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,9 @@ class DisjunctionStep final : public BindingStep<DisjunctionChoiceProducer> {
684684
// chained together. If so, disable choices which differ
685685
// from currently selected representative.
686686
void pruneOverloadSet(Constraint *disjunction) {
687+
if (!CS.performanceHacksEnabled())
688+
return;
689+
687690
auto *choice = disjunction->getNestedConstraints().front();
688691
if (choice->getKind() != ConstraintKind::BindOverload)
689692
return;

validation-test/Sema/type_checker_perf/fast/array_concatenation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -solver-disable-shrink
1+
// RUN: %target-typecheck-verify-swift -disable-constraint-solver-performance-hacks
22

33
// Self-contained test case
44
protocol P1 {}; func f<T: P1>(_: T, _: T) -> T { fatalError() }

validation-test/Sema/type_checker_perf/fast/property_vs_unapplied_func.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1 -solver-disable-shrink
1+
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1
22
// REQUIRES: tools-release,no_asan
33

44
struct Date {

validation-test/Sema/type_checker_perf/slow/rdar26564101.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1 -solver-disable-shrink
1+
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1 -disable-constraint-solver-performance-hacks
22
// REQUIRES: tools-release,no_asan
33
// UNSUPPORTED: swift_test_mode_optimize_none && OS=linux-gnu
44

0 commit comments

Comments
 (0)