Skip to content

Commit b149341

Browse files
committed
[Constraint system] Generalize recording of pattern binding entry targets.
Rather than storing the record of each pattern binding entry's solution application targets as part of an applied function builder, store them within the constraint system and solution using a newly-generalized form of SolutionApplicationTargetsKey.
1 parent 7d4da10 commit b149341

File tree

2 files changed

+130
-14
lines changed

2 files changed

+130
-14
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class BuilderClosureVisitor
288288
continue;
289289

290290
// Keep track of this binding entry.
291-
applied.patternBindingEntries.insert({{patternBinding, index}, target});
291+
cs->setSolutionApplicationTarget({patternBinding, index}, target);
292292
}
293293
}
294294

@@ -1035,11 +1035,11 @@ class BuilderClosureRewriter
10351035
for (unsigned index : range(patternBinding->getNumPatternEntries())) {
10361036
// Find the solution application target for this.
10371037
auto knownTarget =
1038-
builderTransform.patternBindingEntries.find({patternBinding, index});
1039-
assert(knownTarget != builderTransform.patternBindingEntries.end());
1038+
*solution.getConstraintSystem().getSolutionApplicationTarget(
1039+
{patternBinding, index});
10401040

10411041
// Rewrite the target.
1042-
auto resultTarget = rewriteTarget(knownTarget->second);
1042+
auto resultTarget = rewriteTarget(knownTarget);
10431043
if (!resultTarget)
10441044
continue;
10451045

lib/Sema/ConstraintSystem.h

Lines changed: 126 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -724,13 +724,6 @@ struct AppliedBuilderTransform {
724724

725725
/// The return expression, capturing the last value to be emitted.
726726
Expr *returnExpr = nullptr;
727-
728-
using PatternEntry = std::pair<const PatternBindingDecl *, unsigned>;
729-
730-
/// Mapping from specific pattern binding entries to the solution application
731-
/// targets capturing their initialization.
732-
llvm::DenseMap<PatternEntry, SolutionApplicationTarget>
733-
patternBindingEntries;
734727
};
735728

736729
/// Describes the fixed score of a solution to the constraint system.
@@ -855,8 +848,111 @@ struct ForEachStmtInfo {
855848

856849
/// Key to the constraint solver's mapping from AST nodes to their corresponding
857850
/// solution application targets.
858-
using SolutionApplicationTargetsKey =
859-
PointerUnion<const StmtConditionElement *, const Stmt *>;
851+
class SolutionApplicationTargetsKey {
852+
public:
853+
enum class Kind {
854+
empty,
855+
tombstone,
856+
stmtCondElement,
857+
stmt,
858+
patternBindingEntry,
859+
};
860+
861+
private:
862+
Kind kind;
863+
864+
union {
865+
const StmtConditionElement *stmtCondElement;
866+
867+
const Stmt *stmt;
868+
869+
struct PatternBindingEntry {
870+
const PatternBindingDecl *patternBinding;
871+
unsigned index;
872+
} patternBindingEntry;
873+
} storage;
874+
875+
public:
876+
SolutionApplicationTargetsKey(Kind kind) {
877+
assert(kind == Kind::empty || kind == Kind::tombstone);
878+
this->kind = kind;
879+
}
880+
881+
SolutionApplicationTargetsKey(const StmtConditionElement *stmtCondElement) {
882+
kind = Kind::stmtCondElement;
883+
storage.stmtCondElement = stmtCondElement;
884+
}
885+
886+
SolutionApplicationTargetsKey(const Stmt *stmt) {
887+
kind = Kind::stmt;
888+
storage.stmt = stmt;
889+
}
890+
891+
SolutionApplicationTargetsKey(
892+
const PatternBindingDecl *patternBinding, unsigned index) {
893+
kind = Kind::stmt;
894+
storage.patternBindingEntry.patternBinding = patternBinding;
895+
storage.patternBindingEntry.index = index;
896+
}
897+
898+
friend bool operator==(
899+
SolutionApplicationTargetsKey lhs, SolutionApplicationTargetsKey rhs) {
900+
if (lhs.kind != rhs.kind)
901+
return false;
902+
903+
switch (lhs.kind) {
904+
case Kind::empty:
905+
case Kind::tombstone:
906+
return true;
907+
908+
case Kind::stmtCondElement:
909+
return lhs.storage.stmtCondElement == rhs.storage.stmtCondElement;
910+
911+
case Kind::stmt:
912+
return lhs.storage.stmt == rhs.storage.stmt;
913+
914+
case Kind::patternBindingEntry:
915+
return (lhs.storage.patternBindingEntry.patternBinding
916+
== rhs.storage.patternBindingEntry.patternBinding) &&
917+
(lhs.storage.patternBindingEntry.index
918+
== rhs.storage.patternBindingEntry.index);
919+
}
920+
}
921+
922+
friend bool operator!=(
923+
SolutionApplicationTargetsKey lhs, SolutionApplicationTargetsKey rhs) {
924+
return !(lhs == rhs);
925+
}
926+
927+
unsigned getHashValue() const {
928+
using llvm::hash_combine;
929+
using llvm::DenseMapInfo;
930+
931+
switch (kind) {
932+
case Kind::empty:
933+
case Kind::tombstone:
934+
return llvm::DenseMapInfo<unsigned>::getHashValue(static_cast<unsigned>(kind));
935+
936+
case Kind::stmtCondElement:
937+
return hash_combine(
938+
DenseMapInfo<unsigned>::getHashValue(static_cast<unsigned>(kind)),
939+
DenseMapInfo<void *>::getHashValue(storage.stmtCondElement));
940+
941+
case Kind::stmt:
942+
return hash_combine(
943+
DenseMapInfo<unsigned>::getHashValue(static_cast<unsigned>(kind)),
944+
DenseMapInfo<void *>::getHashValue(storage.stmt));
945+
946+
case Kind::patternBindingEntry:
947+
return hash_combine(
948+
DenseMapInfo<unsigned>::getHashValue(static_cast<unsigned>(kind)),
949+
DenseMapInfo<void *>::getHashValue(
950+
storage.patternBindingEntry.patternBinding),
951+
DenseMapInfo<unsigned>::getHashValue(
952+
storage.patternBindingEntry.index));
953+
}
954+
}
955+
};
860956

861957
/// A complete solution to a constraint system.
862958
///
@@ -2610,7 +2706,6 @@ class ConstraintSystem {
26102706

26112707
void setSolutionApplicationTarget(
26122708
SolutionApplicationTargetsKey key, SolutionApplicationTarget target) {
2613-
assert(key && "Expected non-null solution application target key!");
26142709
assert(solutionApplicationTargets.count(key) == 0 &&
26152710
"Already set this solution application target");
26162711
solutionApplicationTargets.insert({key, target});
@@ -5501,4 +5596,25 @@ void forEachExprInConstraintSystem(
55015596

55025597
} // end namespace swift
55035598

5599+
namespace llvm {
5600+
template<>
5601+
struct DenseMapInfo<swift::constraints::SolutionApplicationTargetsKey> {
5602+
using Key = swift::constraints::SolutionApplicationTargetsKey;
5603+
5604+
static inline Key getEmptyKey() {
5605+
return Key(Key::Kind::empty);
5606+
}
5607+
static inline Key getTombstoneKey() {
5608+
return Key(Key::Kind::tombstone);
5609+
}
5610+
static inline unsigned getHashValue(Key key) {
5611+
return key.getHashValue();
5612+
}
5613+
static bool isEqual(Key a, Key b) {
5614+
return a == b;
5615+
}
5616+
};
5617+
5618+
}
5619+
55045620
#endif // LLVM_SWIFT_SEMA_CONSTRAINT_SYSTEM_H

0 commit comments

Comments
 (0)