1010//
1111// ===----------------------------------------------------------------------===//
1212//
13- //
1413// This file implements the algorithm for computing a minimal set of rules from
1514// a confluent rewrite system. A minimal set of rules is:
1615//
@@ -76,7 +75,10 @@ using namespace rewriting;
7675llvm::SmallVector<unsigned , 1 >
7776RewriteLoop::findRulesAppearingOnceInEmptyContext (
7877 const RewriteSystem &system) const {
78+ // Rules appearing in empty context (possibly more than once).
7979 llvm::SmallDenseSet<unsigned , 2 > rulesInEmptyContext;
80+
81+ // The number of times each rule appears (with or without context).
8082 llvm::SmallDenseMap<unsigned , unsigned , 2 > ruleMultiplicity;
8183
8284 RewritePathEvaluator evaluator (Basepoint);
@@ -100,6 +102,7 @@ RewriteLoop::findRulesAppearingOnceInEmptyContext(
100102 step.apply (evaluator, system);
101103 }
102104
105+ // Collect all rules that we saw exactly once in empty context.
103106 SmallVector<unsigned , 1 > result;
104107 for (auto rule : rulesInEmptyContext) {
105108 auto found = ruleMultiplicity.find (rule);
@@ -759,8 +762,10 @@ void RewriteSystem::minimizeRewriteSystem() {
759762 // Now find a minimal set of generating conformances.
760763 //
761764 // 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.
764769 llvm::DenseSet<unsigned > redundantConformances;
765770 computeGeneratingConformances (redundantConformances);
766771
@@ -774,10 +779,14 @@ void RewriteSystem::minimizeRewriteSystem() {
774779}
775780
776781// / 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.
779787llvm::DenseMap<const ProtocolDecl *, std::vector<unsigned >>
780- RewriteSystem::getMinimizedRules (ArrayRef<const ProtocolDecl *> protos) {
788+ RewriteSystem::getMinimizedProtocolRules (
789+ ArrayRef<const ProtocolDecl *> protos) const {
781790 assert (Minimized);
782791
783792 llvm::DenseMap<const ProtocolDecl *, std::vector<unsigned >> rules;
@@ -801,6 +810,33 @@ RewriteSystem::getMinimizedRules(ArrayRef<const ProtocolDecl *> protos) {
801810 return rules;
802811}
803812
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+
804840// / Verify that each loop begins and ends at its basepoint.
805841void RewriteSystem::verifyRewriteLoops () const {
806842#ifndef NDEBUG
@@ -831,6 +867,7 @@ void RewriteSystem::verifyRewriteLoops() const {
831867// / since this suggests a misunderstanding on my part.
832868void RewriteSystem::verifyRedundantConformances (
833869 llvm::DenseSet<unsigned > redundantConformances) const {
870+ #ifndef NDEBUG
834871 for (unsigned ruleID : redundantConformances) {
835872 const auto &rule = getRule (ruleID);
836873 assert (!rule.isPermanent () &&
@@ -848,11 +885,13 @@ void RewriteSystem::verifyRedundantConformances(
848885 abort ();
849886 }
850887 }
888+ #endif
851889}
852890
853891// Assert if homotopy reduction failed to eliminate a rewrite rule it was
854892// supposed to delete.
855893void RewriteSystem::verifyMinimizedRules () const {
894+ #ifndef NDEBUG
856895 for (const auto &rule : Rules) {
857896 // Note that sometimes permanent rules can be simplified, but they can never
858897 // be redundant.
@@ -890,4 +929,5 @@ void RewriteSystem::verifyMinimizedRules() const {
890929 abort ();
891930 }
892931 }
932+ #endif
893933}
0 commit comments