Skip to content

Commit 3819ddf

Browse files
committed
[CSOptimizer] Record best scores for each disjunction and use them in selectDisjunction
If there is no single best disjunction use best scores first to determine minimum with fallback to favored and/or active choice counts.
1 parent cf05405 commit 3819ddf

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ static bool isOverloadedDeclRef(Constraint *disjunction) {
102102
/// favored choices in the current context.
103103
static Constraint *determineBestChoicesInContext(
104104
ConstraintSystem &cs, SmallVectorImpl<Constraint *> &disjunctions,
105-
llvm::DenseMap<Constraint *, llvm::TinyPtrVector<Constraint *>>
105+
llvm::DenseMap<Constraint *,
106+
std::pair<double, llvm::TinyPtrVector<Constraint *>>>
106107
&favorings) {
107108
double bestOverallScore = 0.0;
108109
// Tops scores across all of the disjunctions.
@@ -617,11 +618,10 @@ static Constraint *determineBestChoicesInContext(
617618
}
618619

619620
for (auto &entry : disjunctionScores) {
620-
if (entry.second != bestOverallScore)
621-
continue;
622-
621+
TinyPtrVector<Constraint *> favoredChoices;
623622
for (auto *choice : favoredChoicesPerDisjunction[entry.first])
624-
favorings[entry.first].push_back(choice);
623+
favoredChoices.push_back(choice);
624+
favorings[entry.first] = std::make_pair(entry.second, favoredChoices);
625625
}
626626

627627
if (bestOverallScore == 0)
@@ -710,10 +710,12 @@ ConstraintSystem::selectDisjunction() {
710710
if (auto *disjunction = selectBestBindingDisjunction(*this, disjunctions))
711711
return std::make_pair(disjunction, llvm::TinyPtrVector<Constraint *>());
712712

713-
llvm::DenseMap<Constraint *, llvm::TinyPtrVector<Constraint *>> favorings;
713+
llvm::DenseMap<Constraint *,
714+
std::pair</*bestScore=*/double, llvm::TinyPtrVector<Constraint *>>>
715+
favorings;
714716
if (auto *bestDisjunction =
715717
determineBestChoicesInContext(*this, disjunctions, favorings))
716-
return std::make_pair(bestDisjunction, favorings[bestDisjunction]);
718+
return std::make_pair(bestDisjunction, favorings[bestDisjunction].second);
717719

718720
// Pick the disjunction with the smallest number of favored, then active
719721
// choices.
@@ -722,21 +724,29 @@ ConstraintSystem::selectDisjunction() {
722724
[&](Constraint *first, Constraint *second) -> bool {
723725
unsigned firstActive = first->countActiveNestedConstraints();
724726
unsigned secondActive = second->countActiveNestedConstraints();
725-
unsigned firstFavored = favorings[first].size();
726-
unsigned secondFavored = favorings[second].size();
727727

728-
if (firstFavored == secondFavored) {
728+
auto &[firstScore, firstFavoredChoices] = favorings[first];
729+
auto &[secondScore, secondFavoredChoices] = favorings[second];
730+
731+
if (firstScore > secondScore)
732+
return true;
733+
734+
unsigned numFirstFavored = firstFavoredChoices.size();
735+
unsigned numSecondFavored = secondFavoredChoices.size();
736+
737+
if (numFirstFavored == numSecondFavored) {
729738
if (firstActive != secondActive)
730739
return firstActive < secondActive;
731740
}
732741

733-
firstFavored = firstFavored ? firstFavored : firstActive;
734-
secondFavored = secondFavored ? secondFavored : secondActive;
735-
return firstFavored < secondFavored;
742+
numFirstFavored = numFirstFavored ? numFirstFavored : firstActive;
743+
numSecondFavored = numSecondFavored ? numSecondFavored : secondActive;
744+
745+
return numFirstFavored < numSecondFavored;
736746
});
737747

738748
if (bestDisjunction != disjunctions.end())
739-
return std::make_pair(*bestDisjunction, favorings[*bestDisjunction]);
749+
return std::make_pair(*bestDisjunction, favorings[*bestDisjunction].second);
740750

741751
return std::nullopt;
742752
}

0 commit comments

Comments
 (0)