10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
12
//
13
- //
14
13
// This file implements the algorithm for computing a minimal set of rules from
15
14
// a confluent rewrite system. A minimal set of rules is:
16
15
//
@@ -76,7 +75,10 @@ using namespace rewriting;
76
75
llvm::SmallVector<unsigned , 1 >
77
76
RewriteLoop::findRulesAppearingOnceInEmptyContext (
78
77
const RewriteSystem &system) const {
78
+ // Rules appearing in empty context (possibly more than once).
79
79
llvm::SmallDenseSet<unsigned , 2 > rulesInEmptyContext;
80
+
81
+ // The number of times each rule appears (with or without context).
80
82
llvm::SmallDenseMap<unsigned , unsigned , 2 > ruleMultiplicity;
81
83
82
84
RewritePathEvaluator evaluator (Basepoint);
@@ -100,6 +102,7 @@ RewriteLoop::findRulesAppearingOnceInEmptyContext(
100
102
step.apply (evaluator, system);
101
103
}
102
104
105
+ // Collect all rules that we saw exactly once in empty context.
103
106
SmallVector<unsigned , 1 > result;
104
107
for (auto rule : rulesInEmptyContext) {
105
108
auto found = ruleMultiplicity.find (rule);
@@ -759,8 +762,10 @@ void RewriteSystem::minimizeRewriteSystem() {
759
762
// Now find a minimal set of generating conformances.
760
763
//
761
764
// FIXME: For now this just produces a set of redundant conformances, but
762
- // it should actually compute the full generating conformance basis, since
763
- // we want to use the same information for finding conformance access paths.
765
+ // it should actually output the canonical generating conformance equation
766
+ // for each non-generating conformance. We can then use information to
767
+ // compute conformance access paths, instead of the current "brute force"
768
+ // algorithm used for that purpose.
764
769
llvm::DenseSet<unsigned > redundantConformances;
765
770
computeGeneratingConformances (redundantConformances);
766
771
@@ -774,10 +779,14 @@ void RewriteSystem::minimizeRewriteSystem() {
774
779
}
775
780
776
781
// / Collect all non-permanent, non-redundant rules whose domain is equal to
777
- // / one of the protocols in \p proto. These rules form the requirement
778
- // / signatures of these protocols.
782
+ // / one of the protocols in \p proto. In other words, the first symbol of the
783
+ // / left hand side term is either a protocol symbol or associated type symbol
784
+ // / whose protocol is in \p proto.
785
+ // /
786
+ // / These rules form the requirement signatures of these protocols.
779
787
llvm::DenseMap<const ProtocolDecl *, std::vector<unsigned >>
780
- RewriteSystem::getMinimizedRules (ArrayRef<const ProtocolDecl *> protos) {
788
+ RewriteSystem::getMinimizedProtocolRules (
789
+ ArrayRef<const ProtocolDecl *> protos) const {
781
790
assert (Minimized);
782
791
783
792
llvm::DenseMap<const ProtocolDecl *, std::vector<unsigned >> rules;
@@ -801,6 +810,33 @@ RewriteSystem::getMinimizedRules(ArrayRef<const ProtocolDecl *> protos) {
801
810
return rules;
802
811
}
803
812
813
+ // / Collect all non-permanent, non-redundant rules whose left hand side
814
+ // / begins with a generic parameter symbol.
815
+ // /
816
+ // / These rules form the top-level generic signature for this rewrite system.
817
+ std::vector<unsigned >
818
+ RewriteSystem::getMinimizedGenericSignatureRules () const {
819
+ assert (Minimized);
820
+
821
+ std::vector<unsigned > rules;
822
+ for (unsigned ruleID : indices (Rules)) {
823
+ const auto &rule = getRule (ruleID);
824
+
825
+ if (rule.isPermanent ())
826
+ continue ;
827
+
828
+ if (rule.isRedundant ())
829
+ continue ;
830
+
831
+ if (rule.getLHS ()[0 ].getKind () != Symbol::Kind::GenericParam)
832
+ continue ;
833
+
834
+ rules.push_back (ruleID);
835
+ }
836
+
837
+ return rules;
838
+ }
839
+
804
840
// / Verify that each loop begins and ends at its basepoint.
805
841
void RewriteSystem::verifyRewriteLoops () const {
806
842
#ifndef NDEBUG
@@ -831,6 +867,7 @@ void RewriteSystem::verifyRewriteLoops() const {
831
867
// / since this suggests a misunderstanding on my part.
832
868
void RewriteSystem::verifyRedundantConformances (
833
869
llvm::DenseSet<unsigned > redundantConformances) const {
870
+ #ifndef NDEBUG
834
871
for (unsigned ruleID : redundantConformances) {
835
872
const auto &rule = getRule (ruleID);
836
873
assert (!rule.isPermanent () &&
@@ -848,11 +885,13 @@ void RewriteSystem::verifyRedundantConformances(
848
885
abort ();
849
886
}
850
887
}
888
+ #endif
851
889
}
852
890
853
891
// Assert if homotopy reduction failed to eliminate a rewrite rule it was
854
892
// supposed to delete.
855
893
void RewriteSystem::verifyMinimizedRules () const {
894
+ #ifndef NDEBUG
856
895
for (const auto &rule : Rules) {
857
896
// Note that sometimes permanent rules can be simplified, but they can never
858
897
// be redundant.
@@ -890,4 +929,5 @@ void RewriteSystem::verifyMinimizedRules() const {
890
929
abort ();
891
930
}
892
931
}
932
+ #endif
893
933
}
0 commit comments