Skip to content

Commit e7b351d

Browse files
committed
[CSOptimizer] NFC: Use builder pattern to construct DisjunctionInfo
1 parent 125abed commit e7b351d

File tree

1 file changed

+66
-29
lines changed

1 file changed

+66
-29
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,50 @@ struct DisjunctionInfo {
4242
/// If the score is nullopt it means that the disjunction is not optimizable.
4343
std::optional<double> Score;
4444

45-
/// Whether the decisions were based on speculative information
46-
/// i.e. literal argument candidates or initializer type inference.
47-
bool IsSpeculative = false;
48-
4945
/// The highest scoring choices that could be favored when disjunction
5046
/// is attempted.
5147
llvm::TinyPtrVector<Constraint *> FavoredChoices;
5248

49+
/// Whether the decisions were based on speculative information
50+
/// i.e. literal argument candidates or initializer type inference.
51+
bool IsSpeculative;
52+
5353
DisjunctionInfo() = default;
54-
DisjunctionInfo(double score, bool speculative = false,
55-
ArrayRef<Constraint *> favoredChoices = {})
56-
: Score(score), IsSpeculative(speculative),
57-
FavoredChoices(favoredChoices) {}
54+
DisjunctionInfo(std::optional<double> score,
55+
ArrayRef<Constraint *> favoredChoices, bool speculative)
56+
: Score(score), FavoredChoices(favoredChoices),
57+
IsSpeculative(speculative) {}
58+
59+
static DisjunctionInfo none() { return {std::nullopt, {}, false}; }
60+
};
61+
62+
class DisjunctionInfoBuilder {
63+
std::optional<double> Score;
64+
SmallVector<Constraint *, 2> FavoredChoices;
65+
bool IsSpeculative;
66+
67+
public:
68+
DisjunctionInfoBuilder(std::optional<double> score)
69+
: DisjunctionInfoBuilder(score, {}) {}
70+
71+
DisjunctionInfoBuilder(std::optional<double> score,
72+
ArrayRef<Constraint *> favoredChoices)
73+
: Score(score),
74+
FavoredChoices(favoredChoices.begin(), favoredChoices.end()),
75+
IsSpeculative(false) {}
76+
77+
void setFavoredChoices(ArrayRef<Constraint *> choices) {
78+
FavoredChoices.clear();
79+
FavoredChoices.append(choices.begin(), choices.end());
80+
}
81+
82+
void addFavoredChoice(Constraint *constraint) {
83+
FavoredChoices.push_back(constraint);
84+
}
85+
86+
void setSpeculative(bool value = true) { IsSpeculative = value; }
87+
88+
DisjunctionInfo build() { return {Score, FavoredChoices, IsSpeculative}; }
5889
};
5990

6091
static DeclContext *getDisjunctionDC(Constraint *disjunction) {
@@ -624,7 +655,7 @@ static std::optional<DisjunctionInfo> preserveFavoringOfUnlabeledUnaryArgument(
624655
isExpr<SubscriptExpr>(argument) ||
625656
isExpr<DynamicSubscriptExpr>(argument) ||
626657
isExpr<LiteralExpr>(argument) || isExpr<BinaryExpr>(argument)))
627-
return {/*score=*/0};
658+
return DisjunctionInfo::none();
628659

629660
auto argumentType = cs.getType(argument)->getRValueType();
630661

@@ -633,7 +664,7 @@ static std::optional<DisjunctionInfo> preserveFavoringOfUnlabeledUnaryArgument(
633664
if (isa<BinaryExpr>(argument)) {
634665
auto chainTy = inferTypeOfArithmeticOperatorChain(cs.DC, argument);
635666
if (!chainTy)
636-
return {/*score=*/0};
667+
return DisjunctionInfo::none();
637668

638669
argumentType = chainTy;
639670
}
@@ -643,19 +674,19 @@ static std::optional<DisjunctionInfo> preserveFavoringOfUnlabeledUnaryArgument(
643674
if (auto *LE = dyn_cast<LiteralExpr>(argument)) {
644675
auto *P = TypeChecker::getLiteralProtocol(cs.getASTContext(), LE);
645676
if (!P)
646-
return {/*score=*/0};
677+
return DisjunctionInfo::none();
647678

648679
auto defaultTy = TypeChecker::getDefaultType(P, cs.DC);
649680
if (!defaultTy)
650-
return {/*score=*/0};
681+
return DisjunctionInfo::none();
651682

652683
argumentType = defaultTy;
653684
}
654685

655686
ASSERT(argumentType);
656687

657688
if (argumentType->hasTypeVariable() || argumentType->hasDependentMember())
658-
return {/*score=*/0};
689+
return DisjunctionInfo::none();
659690

660691
SmallVector<Constraint *, 2> favoredChoices;
661692
forEachDisjunctionChoice(
@@ -677,8 +708,9 @@ static std::optional<DisjunctionInfo> preserveFavoringOfUnlabeledUnaryArgument(
677708
favoredChoices.push_back(choice);
678709
});
679710

680-
return DisjunctionInfo(/*score=*/favoredChoices.empty() ? 0 : 1,
681-
/*speculative=*/false, favoredChoices);
711+
return DisjunctionInfoBuilder(/*score=*/favoredChoices.empty() ? 0 : 1,
712+
favoredChoices)
713+
.build();
682714
}
683715

684716
} // end anonymous namespace
@@ -703,11 +735,12 @@ static void determineBestChoicesInContext(
703735
// initializers for CGFloat<->Double conversions and restrictions with
704736
// multiple choices.
705737
if (disjunction->countFavoredNestedConstraints() > 0) {
706-
DisjunctionInfo info(/*score=*/2.0);
707-
llvm::copy_if(disjunction->getNestedConstraints(),
708-
std::back_inserter(info.FavoredChoices),
709-
[](Constraint *choice) { return choice->isFavored(); });
710-
recordResult(disjunction, std::move(info));
738+
DisjunctionInfoBuilder info(/*score=*/2.0);
739+
for (auto *choice : disjunction->getNestedConstraints()) {
740+
if (choice->isFavored())
741+
info.addFavoredChoice(choice);
742+
}
743+
recordResult(disjunction, info.build());
711744
continue;
712745
}
713746

@@ -742,8 +775,9 @@ static void determineBestChoicesInContext(
742775
return decl &&
743776
!decl->getInterfaceType()->is<AnyFunctionType>();
744777
});
745-
recordResult(disjunction, {/*score=*/1.0, /*speculative=*/false,
746-
favoredChoices});
778+
recordResult(
779+
disjunction,
780+
DisjunctionInfoBuilder(/*score=*/1.0, favoredChoices).build());
747781
continue;
748782
}
749783

@@ -783,8 +817,9 @@ static void determineBestChoicesInContext(
783817
});
784818

785819
if (!favoredChoices.empty()) {
786-
recordResult(disjunction,
787-
{/*score=*/0.01, /*speculative=*/false, favoredChoices});
820+
recordResult(
821+
disjunction,
822+
DisjunctionInfoBuilder(/*score=*/0.01, favoredChoices).build());
788823
continue;
789824
}
790825
}
@@ -1633,14 +1668,16 @@ static void determineBestChoicesInContext(
16331668
(!canUseContextualResultTypes ||
16341669
!anyNonSpeculativeResultTypes(resultTypes));
16351670

1636-
DisjunctionInfo info(/*score=*/bestScore, isSpeculative);
1671+
DisjunctionInfoBuilder info(/*score=*/bestScore);
1672+
1673+
info.setSpeculative(isSpeculative);
16371674

16381675
for (const auto &choice : favoredChoices) {
16391676
if (choice.second == bestScore)
1640-
info.FavoredChoices.push_back(choice.first);
1677+
info.addFavoredChoice(choice.first);
16411678
}
16421679

1643-
recordResult(disjunction, std::move(info));
1680+
recordResult(disjunction, info.build());
16441681
}
16451682

16461683
if (cs.isDebugMode() && bestOverallScore > 0) {
@@ -1751,9 +1788,9 @@ ConstraintSystem::selectDisjunction() {
17511788
if (auto preference = isPreferable(*this, first, second))
17521789
return preference.value();
17531790

1754-
auto &[firstScore, isFirstSpeculative, firstFavoredChoices] =
1791+
auto &[firstScore, firstFavoredChoices, isFirstSpeculative] =
17551792
favorings[first];
1756-
auto &[secondScore, isSecondSpeculative, secondFavoredChoices] =
1793+
auto &[secondScore, secondFavoredChoices, isSecondSpeculative] =
17571794
favorings[second];
17581795

17591796
bool isFirstOperator = isOperatorDisjunction(first);

0 commit comments

Comments
 (0)