@@ -414,177 +414,6 @@ void PropertyMap::buildPropertyMap() {
414
414
verify ();
415
415
}
416
416
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
-
588
417
void PropertyMap::dump (llvm::raw_ostream &out) const {
589
418
out << " Property map: {\n " ;
590
419
for (const auto &props : Entries) {
0 commit comments