@@ -364,197 +364,6 @@ void PropertyMap::addSuperclassProperty(
364
364
}
365
365
}
366
366
367
- // / Given a rule (V.[LHS] => V) and a rewrite path (T.[RHS] => T) where
368
- // / T == U.V, build a rewrite path from T.[RHS] to T.[LHS].
369
- void RewriteSystem::buildRewritePathForUnifier (Term key,
370
- unsigned lhsRuleID,
371
- const RewritePath &rhsPath,
372
- RewritePath *path) const {
373
- unsigned lhsLength = getRule (lhsRuleID).getRHS ().size ();
374
- unsigned lhsPrefix = key.size () - lhsLength;
375
-
376
- path->append (rhsPath);
377
-
378
- // Apply the inverted rule U.(V => V.[LHS]).
379
- path->add (RewriteStep::forRewriteRule (
380
- /* startOffset=*/ lhsPrefix, /* endOffset=*/ 0 ,
381
- /* ruleID=*/ lhsRuleID, /* inverse=*/ true ));
382
-
383
- // If the rule was actually (V.[LHS] => V) with T == U.V for some
384
- // |U| > 0, prefix each substitution of [LHS] with U.
385
- if (lhsPrefix > 0 ) {
386
- path->add (RewriteStep::forPrefixSubstitutions (/* prefix=*/ lhsPrefix,
387
- /* endOffset=*/ 0 ,
388
- /* inverse=*/ false ));
389
- }
390
- }
391
-
392
- // / Build a rewrite path for a rule induced by concrete type unification.
393
- // /
394
- // / Consider two concrete type rules (T.[LHS] => T) and (T.[RHS] => T), a
395
- // / TypeDifference describing the transformation from LHS to RHS, and the
396
- // / index of a substitution Xn from [C] which is transformed into its
397
- // / replacement f(Xn).
398
- // /
399
- // / The rewrite path should allow us to eliminate the induced rule
400
- // / (f(Xn) => Xn), so the induced rule will appear without context, and
401
- // / the concrete type rules (T.[LHS] => T) and (T.[RHS] => T) will appear
402
- // / in context.
403
- // /
404
- // / There are two cases:
405
- // /
406
- // / a) The substitution Xn remains a type parameter in [RHS], but becomes
407
- // / a canonical term Xn', so f(Xn) = Xn'.
408
- // /
409
- // / In the first case, the induced rule (Xn => Xn'), described by a
410
- // / rewrite path as follows:
411
- // /
412
- // / Xn
413
- // / Xn' T.[RHS] // RightConcreteProjection(n) pushes T.[RHS]
414
- // / Xn' T // Application of (T.[RHS] => T) in context
415
- // / Xn' T.[LHS] // Application of (T => T.[LHS]) in context
416
- // / Xn' // LeftConcreteProjection(n) pops T.[LHS]
417
- // /
418
- // / Now when this path is composed with a rewrite step for the inverted
419
- // / induced rule (Xn' => Xn), we get a rewrite loop at Xn in which the
420
- // / new rule appears in empty context.
421
- // /
422
- // / b) The substitution Xn becomes a concrete type [D] in [C'], so
423
- // / f(Xn) = Xn.[D].
424
- // /
425
- // / In the second case, the induced rule is (Xn.[D] => Xn), described
426
- // / by a rewrite path (going in the other direction) as follows:
427
- // /
428
- // / Xn
429
- // / Xn.[D] T.[RHS] // RightConcreteProjection(n) pushes T.[RHS]
430
- // / Xn.[D] T // Application of (T.[RHS] => T) in context
431
- // / Xn.[D] T.[LHS] // Application of (T => T.[LHS]) in context
432
- // / Xn.[D] // LeftConcreteProjection(n) pops T.[LHS]
433
- // /
434
- // / Now when this path is composed with a rewrite step for the induced
435
- // / rule (Xn.[D] => Xn), we get a rewrite loop at Xn in which the
436
- // / new rule appears in empty context.
437
- // /
438
- // / There is a minor complication; the concrete type rules T.[LHS] and
439
- // / T.[RHS] might actually be T.[LHS] and V.[RHS] where V is a suffix of
440
- // / T, so T = U.V for some |U| > 0, (or vice versa). In this case we need
441
- // / an additional step in the middle to prefix the concrete substitutions
442
- // / of [LHS] (or [LHS]) with U.
443
- static void buildRewritePathForInducedRule (Term key,
444
- unsigned differenceID,
445
- unsigned lhsRuleID,
446
- const RewritePath &rhsPath,
447
- unsigned substitutionIndex,
448
- const RewriteSystem &system,
449
- RewritePath *path) {
450
- // Replace f(Xn) with Xn and push T.[RHS] on the stack.
451
- path->add (RewriteStep::forRightConcreteProjection (
452
- differenceID, substitutionIndex, /* inverse=*/ false ));
453
-
454
- system.buildRewritePathForUnifier (key, lhsRuleID, rhsPath, path);
455
-
456
- // Pop T.[LHS] from the stack, leaving behind Xn.
457
- path->add (RewriteStep::forLeftConcreteProjection (
458
- differenceID, substitutionIndex, /* inverse=*/ true ));
459
- }
460
-
461
- // / Given that LHS and RHS are known to simplify to the same term, build a
462
- // / rewrite path from RHS to LHS.
463
- void RewriteSystem::buildRewritePathForJoiningTerms (MutableTerm lhsTerm,
464
- MutableTerm rhsTerm,
465
- RewritePath *path) const {
466
- (void ) simplify (rhsTerm, path);
467
-
468
- RewritePath lhsPath;
469
- (void ) simplify (lhsTerm, &lhsPath);
470
- lhsPath.invert ();
471
-
472
- path->append (lhsPath);
473
-
474
- assert (lhsTerm == rhsTerm);
475
- }
476
-
477
- // / Given two concrete type rules (T.[LHS] => T) and (T.[RHS] => T) and
478
- // / TypeDifference describing the transformation from LHS to RHS,
479
- // / record rules for transforming each substitution of LHS into a
480
- // / more canonical type parameter or concrete type from RHS.
481
- // /
482
- // / This also records rewrite paths relating induced rules to the original
483
- // / concrete type rules, since the concrete type rules imply the induced
484
- // / rules and make them redundant.
485
- // /
486
- // / Finally, builds a rewrite loop relating the two concrete type rules
487
- // / via the induced rules.
488
- void RewriteSystem::processTypeDifference (const TypeDifference &difference,
489
- unsigned differenceID,
490
- unsigned lhsRuleID,
491
- const RewritePath &rhsPath) {
492
- bool debug = Debug.contains (DebugFlags::ConcreteUnification);
493
-
494
- if (debug) {
495
- difference.dump (llvm::dbgs ());
496
- }
497
-
498
- RewritePath unificationPath;
499
-
500
- auto substitutions = difference.LHS .getSubstitutions ();
501
-
502
- // The term is at the top of the primary stack. Push all substitutions onto
503
- // the primary stack.
504
- unificationPath.add (RewriteStep::forDecompose (substitutions.size (),
505
- /* inverse=*/ false ));
506
-
507
- // Move all substitutions but the first one to the secondary stack.
508
- for (unsigned i = 1 ; i < substitutions.size (); ++i)
509
- unificationPath.add (RewriteStep::forShift (/* inverse=*/ false ));
510
-
511
- for (unsigned index : indices (substitutions)) {
512
- // Move the next substitution from the secondary stack to the primary stack.
513
- if (index != 0 )
514
- unificationPath.add (RewriteStep::forShift (/* inverse=*/ true ));
515
-
516
- auto lhsTerm = difference.getReplacementSubstitution (index);
517
- auto rhsTerm = difference.getOriginalSubstitution (index);
518
-
519
- RewritePath inducedRulePath;
520
- buildRewritePathForInducedRule (difference.BaseTerm , differenceID,
521
- lhsRuleID, rhsPath, index,
522
- *this , &inducedRulePath);
523
-
524
- if (debug) {
525
- llvm::dbgs () << " %% Induced rule " << lhsTerm
526
- << " => " << rhsTerm << " with path " ;
527
- inducedRulePath.dump (llvm::dbgs (), lhsTerm, *this );
528
- llvm::dbgs () << " \n " ;
529
- }
530
-
531
- addRule (lhsTerm, rhsTerm, &inducedRulePath);
532
- buildRewritePathForJoiningTerms (lhsTerm, rhsTerm, &unificationPath);
533
- }
534
-
535
- // All simplified substitutions are now on the primary stack. Collect them to
536
- // produce the new term.
537
- unificationPath.add (RewriteStep::forDecomposeConcrete (differenceID,
538
- /* inverse=*/ true ));
539
-
540
- // We now have a unification path from T.[RHS] to T.[LHS] using the
541
- // newly-recorded induced rules. Close the loop with a path from
542
- // T.[RHS] to R.[LHS] via the concrete type rules being unified.
543
- buildRewritePathForUnifier (difference.BaseTerm , lhsRuleID, rhsPath,
544
- &unificationPath);
545
-
546
- // Record a rewrite loop at T.[LHS].
547
- MutableTerm basepoint (difference.BaseTerm );
548
- basepoint.add (difference.LHS );
549
- recordRewriteLoop (basepoint, unificationPath);
550
-
551
- // Optimization: If the LHS rule applies to the entire base term and not
552
- // a suffix, mark it substitution-simplified so that we can skip recording
553
- // the same rewrite loop in concretelySimplifyLeftHandSideSubstitutions().
554
- auto &lhsRule = getRule (lhsRuleID);
555
- if (lhsRule.getRHS () == difference.BaseTerm )
556
- lhsRule.markSubstitutionSimplified ();
557
- }
558
367
559
368
// / Utility used by addSuperclassProperty() and addConcreteTypeProperty().
560
369
void PropertyMap::unifyConcreteTypes (
0 commit comments