Skip to content

Commit d4732f5

Browse files
committed
RequirementMachine: Move RewritePath and RewriteLoop methods from HomotopyReduction.cpp to RewriteLoop.cpp
1 parent 755941c commit d4732f5

File tree

2 files changed

+295
-295
lines changed

2 files changed

+295
-295
lines changed

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 0 additions & 295 deletions
Original file line numberDiff line numberDiff line change
@@ -65,93 +65,6 @@
6565
using namespace swift;
6666
using namespace rewriting;
6767

68-
/// Recompute various cached values if needed.
69-
void RewriteLoop::recompute(const RewriteSystem &system) {
70-
if (!Dirty)
71-
return;
72-
Dirty = 0;
73-
74-
Useful = 0;
75-
ProjectionCount = 0;
76-
DecomposeCount = 0;
77-
HasConcreteTypeAliasRule = 0;
78-
79-
RewritePathEvaluator evaluator(Basepoint);
80-
for (auto step : Path) {
81-
switch (step.Kind) {
82-
case RewriteStep::Rule: {
83-
Useful |= (!step.isInContext() && !evaluator.isInContext());
84-
85-
const auto &rule = system.getRule(step.getRuleID());
86-
if (rule.isDerivedFromConcreteProtocolTypeAliasRule())
87-
HasConcreteTypeAliasRule = 1;
88-
89-
break;
90-
}
91-
92-
case RewriteStep::LeftConcreteProjection:
93-
++ProjectionCount;
94-
break;
95-
96-
case RewriteStep::Decompose:
97-
++DecomposeCount;
98-
break;
99-
100-
case RewriteStep::PrefixSubstitutions:
101-
case RewriteStep::Shift:
102-
case RewriteStep::Relation:
103-
case RewriteStep::DecomposeConcrete:
104-
case RewriteStep::RightConcreteProjection:
105-
break;
106-
}
107-
108-
evaluator.apply(step, system);
109-
}
110-
111-
RulesInEmptyContext = Path.getRulesInEmptyContext(Basepoint, system);
112-
}
113-
114-
/// A rewrite rule is redundant if it appears exactly once in a loop
115-
/// without context.
116-
ArrayRef<unsigned>
117-
RewriteLoop::findRulesAppearingOnceInEmptyContext(
118-
const RewriteSystem &system) const {
119-
const_cast<RewriteLoop *>(this)->recompute(system);
120-
return RulesInEmptyContext;
121-
}
122-
123-
/// The number of LeftConcreteProjection steps, used by the elimination order to
124-
/// prioritize loops that are not concrete unification projections.
125-
unsigned RewriteLoop::getProjectionCount(
126-
const RewriteSystem &system) const {
127-
const_cast<RewriteLoop *>(this)->recompute(system);
128-
return ProjectionCount;
129-
}
130-
131-
/// The number of Decompose steps, used by the elimination order to prioritize
132-
/// loops that are not concrete simplifications.
133-
unsigned RewriteLoop::getDecomposeCount(
134-
const RewriteSystem &system) const {
135-
const_cast<RewriteLoop *>(this)->recompute(system);
136-
return DecomposeCount;
137-
}
138-
139-
/// Returns true if the loop contains at least one concrete protocol typealias rule,
140-
/// which have the form ([P].A.[concrete: C] => [P].A).
141-
bool RewriteLoop::hasConcreteTypeAliasRule(
142-
const RewriteSystem &system) const {
143-
const_cast<RewriteLoop *>(this)->recompute(system);
144-
return HasConcreteTypeAliasRule;
145-
}
146-
147-
/// The number of Decompose steps, used by the elimination order to prioritize
148-
/// loops that are not concrete simplifications.
149-
bool RewriteLoop::isUseful(
150-
const RewriteSystem &system) const {
151-
const_cast<RewriteLoop *>(this)->recompute(system);
152-
return Useful;
153-
}
154-
15568
/// If a rewrite loop contains an explicit rule in empty context, propagate the
15669
/// explicit bit to all other rules appearing in empty context within the same
15770
/// loop.
@@ -268,214 +181,6 @@ void RewriteSystem::processConflicts() {
268181
}
269182
}
270183

271-
/// Given a rewrite rule which appears exactly once in a loop
272-
/// without context, return a new definition for this rewrite rule.
273-
/// The new definition is the path obtained by deleting the
274-
/// rewrite rule from the loop.
275-
RewritePath RewritePath::splitCycleAtRule(unsigned ruleID) const {
276-
// A cycle is a path from the basepoint to the basepoint.
277-
// Somewhere in this path, an application of \p ruleID
278-
// appears in an empty context.
279-
280-
// First, we split the cycle into two paths:
281-
//
282-
// (1) A path from the basepoint to the rule's
283-
// left hand side,
284-
RewritePath basepointToLhs;
285-
// (2) And a path from the rule's right hand side
286-
// to the basepoint.
287-
RewritePath rhsToBasepoint;
288-
289-
// Because the rule only appears once, we know that basepointToLhs
290-
// and rhsToBasepoint do not involve the rule itself.
291-
292-
// If the rule is inverted, we have to invert the whole thing
293-
// again at the end.
294-
bool ruleWasInverted = false;
295-
296-
bool sawRule = false;
297-
298-
for (auto step : Steps) {
299-
switch (step.Kind) {
300-
case RewriteStep::Rule: {
301-
if (step.getRuleID() != ruleID)
302-
break;
303-
304-
assert(!sawRule && "Rule appears more than once?");
305-
assert(!step.isInContext() && "Rule appears in context?");
306-
307-
ruleWasInverted = step.Inverse;
308-
sawRule = true;
309-
continue;
310-
}
311-
case RewriteStep::PrefixSubstitutions:
312-
case RewriteStep::Shift:
313-
case RewriteStep::Decompose:
314-
case RewriteStep::Relation:
315-
case RewriteStep::DecomposeConcrete:
316-
case RewriteStep::LeftConcreteProjection:
317-
case RewriteStep::RightConcreteProjection:
318-
break;
319-
}
320-
321-
if (sawRule)
322-
rhsToBasepoint.add(step);
323-
else
324-
basepointToLhs.add(step);
325-
}
326-
327-
// Build a path from the rule's lhs to the rule's rhs via the
328-
// basepoint.
329-
RewritePath result = rhsToBasepoint;
330-
result.append(basepointToLhs);
331-
332-
// We want a path from the lhs to the rhs, so invert it unless
333-
// the rewrite step was also inverted.
334-
if (!ruleWasInverted)
335-
result.invert();
336-
337-
return result;
338-
}
339-
340-
/// Replace every rewrite step involving the given rewrite rule with
341-
/// either the replacement path (or its inverse, if the step was
342-
/// inverted).
343-
///
344-
/// The replacement path is re-contextualized at each occurrence of a
345-
/// rewrite step involving the given rule.
346-
///
347-
/// Returns true if any rewrite steps were replaced; false means the
348-
/// rule did not appear in this path.
349-
bool RewritePath::replaceRuleWithPath(unsigned ruleID,
350-
const RewritePath &path) {
351-
bool foundAny = false;
352-
353-
for (const auto &step : Steps) {
354-
if (step.Kind == RewriteStep::Rule &&
355-
step.getRuleID() == ruleID) {
356-
foundAny = true;
357-
break;
358-
}
359-
}
360-
361-
if (!foundAny)
362-
return false;
363-
364-
SmallVector<RewriteStep, 4> newSteps;
365-
366-
for (const auto &step : Steps) {
367-
switch (step.Kind) {
368-
case RewriteStep::Rule: {
369-
// All other rewrite rules remain unchanged.
370-
if (step.getRuleID() != ruleID) {
371-
newSteps.push_back(step);
372-
break;
373-
}
374-
375-
// Ok, we found a rewrite step referencing the redundant rule.
376-
// Replace this step with the provided path. If this rewrite step has
377-
// context, the path's own steps must be re-contextualized.
378-
379-
// Keep track of rewrite step pairs which push and pop the stack. Any
380-
// rewrite steps enclosed with a push/pop are not re-contextualized.
381-
unsigned pushCount = 0;
382-
383-
auto recontextualizeStep = [&](RewriteStep newStep) {
384-
bool inverse = newStep.Inverse ^ step.Inverse;
385-
386-
if (newStep.pushesTermsOnStack() && inverse) {
387-
assert(pushCount > 0);
388-
--pushCount;
389-
}
390-
391-
if (pushCount == 0) {
392-
newStep.StartOffset += step.StartOffset;
393-
newStep.EndOffset += step.EndOffset;
394-
}
395-
396-
newStep.Inverse = inverse;
397-
newSteps.push_back(newStep);
398-
399-
if (newStep.pushesTermsOnStack() && !inverse) {
400-
++pushCount;
401-
}
402-
};
403-
404-
// If this rewrite step is inverted, invert the entire path.
405-
if (step.Inverse) {
406-
for (auto newStep : llvm::reverse(path))
407-
recontextualizeStep(newStep);
408-
} else {
409-
for (auto newStep : path)
410-
recontextualizeStep(newStep);
411-
}
412-
413-
// Rewrite steps which push and pop the stack must come in balanced pairs.
414-
assert(pushCount == 0);
415-
416-
break;
417-
}
418-
case RewriteStep::PrefixSubstitutions:
419-
case RewriteStep::Shift:
420-
case RewriteStep::Decompose:
421-
case RewriteStep::Relation:
422-
case RewriteStep::DecomposeConcrete:
423-
case RewriteStep::LeftConcreteProjection:
424-
case RewriteStep::RightConcreteProjection:
425-
newSteps.push_back(step);
426-
break;
427-
}
428-
}
429-
430-
std::swap(newSteps, Steps);
431-
return true;
432-
}
433-
434-
SmallVector<unsigned, 1>
435-
RewritePath::getRulesInEmptyContext(const MutableTerm &term,
436-
const RewriteSystem &system) {
437-
// Rules appearing in empty context (possibly more than once).
438-
llvm::SmallDenseSet<unsigned, 2> rulesInEmptyContext;
439-
// The number of times each rule appears (with or without context).
440-
llvm::SmallDenseMap<unsigned, unsigned, 2> ruleFrequency;
441-
442-
RewritePathEvaluator evaluator(term);
443-
for (auto step : Steps) {
444-
switch (step.Kind) {
445-
case RewriteStep::Rule: {
446-
if (!step.isInContext() && !evaluator.isInContext())
447-
rulesInEmptyContext.insert(step.getRuleID());
448-
449-
++ruleFrequency[step.getRuleID()];
450-
break;
451-
}
452-
453-
case RewriteStep::LeftConcreteProjection:
454-
case RewriteStep::Decompose:
455-
case RewriteStep::PrefixSubstitutions:
456-
case RewriteStep::Shift:
457-
case RewriteStep::Relation:
458-
case RewriteStep::DecomposeConcrete:
459-
case RewriteStep::RightConcreteProjection:
460-
break;
461-
}
462-
463-
evaluator.apply(step, system);
464-
}
465-
466-
// Collect all rules that we saw exactly once in empty context.
467-
SmallVector<unsigned, 1> rulesOnceInEmptyContext;
468-
for (auto rule : rulesInEmptyContext) {
469-
auto found = ruleFrequency.find(rule);
470-
assert(found != ruleFrequency.end());
471-
472-
if (found->second == 1)
473-
rulesOnceInEmptyContext.push_back(rule);
474-
}
475-
476-
return rulesOnceInEmptyContext;
477-
}
478-
479184
/// Find a rule to delete by looking through all loops for rewrite rules appearing
480185
/// once in empty context. Returns a pair consisting of a loop ID and a rule ID,
481186
/// otherwise returns None.

0 commit comments

Comments
 (0)