@@ -414,177 +414,6 @@ void PropertyMap::buildPropertyMap() {
414414 verify ();
415415}
416416
417- // / Similar to RewriteSystem::simplifySubstitutions(), but also replaces type
418- // / parameters with concrete types and builds a type difference describing
419- // / the transformation.
420- // /
421- // / Returns None if the concrete type symbol cannot be simplified further.
422- // /
423- // / Otherwise returns an index which can be passed to
424- // / RewriteSystem::getTypeDifference().
425- Optional<unsigned >
426- PropertyMap::concretelySimplifySubstitutions (Term baseTerm, Symbol symbol,
427- RewritePath *path) const {
428- assert (symbol.hasSubstitutions ());
429-
430- // Fast path if the type is fully concrete.
431- auto substitutions = symbol.getSubstitutions ();
432- if (substitutions.empty ())
433- return None;
434-
435- // Save the original rewrite path length so that we can reset if if we don't
436- // find anything to simplify.
437- unsigned oldSize = (path ? path->size () : 0 );
438-
439- if (path) {
440- // The term is at the top of the primary stack. Push all substitutions onto
441- // the primary stack.
442- path->add (RewriteStep::forDecompose (substitutions.size (),
443- /* inverse=*/ false ));
444-
445- // Move all substitutions but the first one to the secondary stack.
446- for (unsigned i = 1 ; i < substitutions.size (); ++i)
447- path->add (RewriteStep::forShift (/* inverse=*/ false ));
448- }
449-
450- // Simplify and collect substitutions.
451- llvm::SmallVector<std::pair<unsigned , Term>, 1 > sameTypes;
452- llvm::SmallVector<std::pair<unsigned , Symbol>, 1 > concreteTypes;
453-
454- for (unsigned index : indices (substitutions)) {
455- // Move the next substitution from the secondary stack to the primary stack.
456- if (index != 0 && path)
457- path->add (RewriteStep::forShift (/* inverse=*/ true ));
458-
459- auto term = symbol.getSubstitutions ()[index];
460- MutableTerm mutTerm (term);
461-
462- // Note that it's of course possible that the term both requires
463- // simplification, and the simplified term has a concrete type.
464- //
465- // This isn't handled with our current representation of
466- // TypeDifference, but that should be fine since the caller
467- // has to iterate until fixed point anyway.
468- //
469- // This should be rare in practice.
470- if (System.simplify (mutTerm, path)) {
471- // Record a mapping from this substitution to the simplified term.
472- sameTypes.emplace_back (index, Term::get (mutTerm, Context));
473- } else {
474- auto *props = lookUpProperties (mutTerm);
475-
476- if (props && props->ConcreteType ) {
477- // The property map entry might apply to a suffix of the substitution
478- // term, so prepend the appropriate prefix to its own substitutions.
479- auto prefix = props->getPrefixAfterStrippingKey (mutTerm);
480- auto concreteSymbol =
481- props->ConcreteType ->prependPrefixToConcreteSubstitutions (
482- prefix, Context);
483-
484- // Record a mapping from this substitution to the concrete type.
485- concreteTypes.emplace_back (index, concreteSymbol);
486-
487- // If U.V is the substitution term and V is the property map key,
488- // apply the rewrite step U.(V => V.[concrete: C]) followed by
489- // prepending the prefix U to each substitution in the concrete type
490- // symbol if |U| > 0.
491- if (path) {
492- path->add (RewriteStep::forRewriteRule (/* startOffset=*/ prefix.size (),
493- /* endOffset=*/ 0 ,
494- /* ruleID=*/ *props->ConcreteTypeRule ,
495- /* inverse=*/ true ));
496-
497- if (!prefix.empty ()) {
498- path->add (RewriteStep::forPrefixSubstitutions (/* length=*/ prefix.size (),
499- /* endOffset=*/ 0 ,
500- /* inverse=*/ false ));
501- }
502- }
503- }
504- }
505- }
506-
507- // If nothing changed, we don't have to build the type difference.
508- if (sameTypes.empty () && concreteTypes.empty ()) {
509- if (path) {
510- // The rewrite path should consist of a Decompose, followed by a number
511- // of Shifts, followed by a Compose.
512- #ifndef NDEBUG
513- for (auto iter = path->begin () + oldSize; iter < path->end (); ++iter) {
514- assert (iter->Kind == RewriteStep::Shift ||
515- iter->Kind == RewriteStep::Decompose);
516- }
517- #endif
518-
519- path->resize (oldSize);
520- }
521- return None;
522- }
523-
524- auto difference = buildTypeDifference (baseTerm, symbol,
525- sameTypes, concreteTypes,
526- Context);
527- assert (difference.LHS != difference.RHS );
528-
529- unsigned differenceID = System.recordTypeDifference (difference);
530-
531- // All simplified substitutions are now on the primary stack. Collect them to
532- // produce the new term.
533- if (path) {
534- path->add (RewriteStep::forDecomposeConcrete (differenceID,
535- /* inverse=*/ true ));
536- }
537-
538- return differenceID;
539- }
540-
541- void PropertyMap::concretelySimplifyLeftHandSideSubstitutions () const {
542- for (unsigned ruleID = 0 , e = System.getRules ().size (); ruleID < e; ++ruleID) {
543- auto &rule = System.getRule (ruleID);
544- if (rule.isLHSSimplified () ||
545- rule.isRHSSimplified () ||
546- rule.isSubstitutionSimplified ())
547- continue ;
548-
549- auto optSymbol = rule.isPropertyRule ();
550- if (!optSymbol || !optSymbol->hasSubstitutions ())
551- continue ;
552-
553- auto symbol = *optSymbol;
554-
555- RewritePath path;
556-
557- auto differenceID = concretelySimplifySubstitutions (
558- rule.getRHS (), symbol, &path);
559- if (!differenceID)
560- continue ;
561-
562- rule.markSubstitutionSimplified ();
563-
564- auto difference = System.getTypeDifference (*differenceID);
565- assert (difference.LHS == symbol);
566-
567- // If the original rule is (T.[concrete: C] => T) and [concrete: C'] is
568- // the simplified symbol, then difference.LHS == [concrete: C] and
569- // difference.RHS == [concrete: C'], and the rewrite path we just
570- // built takes T.[concrete: C] to T.[concrete: C'].
571- //
572- // We want a path from T.[concrete: C'] to T, so invert the path to get
573- // a path from T.[concrete: C'] to T.[concrete: C], and add a final step
574- // applying the original rule (T.[concrete: C] => T).
575- path.invert ();
576- path.add (RewriteStep::forRewriteRule (/* startOffset=*/ 0 ,
577- /* endOffset=*/ 0 ,
578- /* ruleID=*/ ruleID,
579- /* inverted=*/ false ));
580- MutableTerm rhs (rule.getRHS ());
581- MutableTerm lhs (rhs);
582- lhs.add (difference.RHS );
583-
584- System.addRule (lhs, rhs, &path);
585- }
586- }
587-
588417void PropertyMap::dump (llvm::raw_ostream &out) const {
589418 out << " Property map: {\n " ;
590419 for (const auto &props : Entries) {
0 commit comments