@@ -455,20 +455,72 @@ type add_result = {
455
455
let invariant_add_result ~original_t { canonical_element; alias_of_demoted_element; t; } =
456
456
if ! Clflags. flambda_invariant_checks then begin
457
457
invariant t;
458
- if not (Simple. equal canonical_element alias_of_demoted_element) then begin
459
- if not (defined_earlier t canonical_element ~than: alias_of_demoted_element) then begin
460
- Misc. fatal_errorf " Canonical element %a should be defined earlier \
461
- than %a after alias addition.@ Original alias tracker:@ %a@ \
458
+ if not (defined_earlier t canonical_element ~than: alias_of_demoted_element) then begin
459
+ Misc. fatal_errorf " Canonical element %a should be defined earlier \
460
+ than %a after alias addition.@ Original alias tracker:@ %a@ \
461
+ Resulting alias tracker:@ %a"
462
+ Simple. print canonical_element
463
+ Simple. print alias_of_demoted_element
464
+ print original_t
465
+ print t
466
+ end ;
467
+ match canonical t alias_of_demoted_element with
468
+ | Is_canonical _ ->
469
+ Misc. fatal_errorf " Alias %a must not be must not be canonical \
470
+ anymore.@ \
471
+ Original alias tracker:@ %a@ \
462
472
Resulting alias tracker:@ %a"
463
- Simple. print canonical_element
464
473
Simple. print alias_of_demoted_element
465
474
print original_t
466
475
print t
467
- end
468
- end
476
+ | Alias_of_canonical _ -> ()
469
477
end
470
478
479
+ (*
480
+ let debugging () = !Clflags.dump_rawflambda
481
+ let andop = "\u{2227}"
482
+ let canonop = "\u{21e5}"
483
+
484
+ let debugf fmt =
485
+ let k go = if debugging () then go Format.err_formatter else () in
486
+ Format.kdprintf k fmt
487
+ *)
488
+
471
489
let add_alias t element1 element2 =
490
+ (*
491
+ debugf "@[<hv2>add_alias@ ~element1:%a@ ~element2:%a@]@."
492
+ Simple.print element1
493
+ Simple.print element2;
494
+ (fun ({ canonical_element; alias_of_demoted_element = alias_of; t = _ } as ans) ->
495
+ debugf "Decision: %a %s %a@."
496
+ Simple.print alias_of
497
+ canonop
498
+ Simple.print canonical_element;
499
+ ans
500
+ ) @@ begin
501
+ begin match canonical t element1, canonical t element2 with
502
+ | Is_canonical canonical_element1, Is_canonical canonical_element2
503
+ | Alias_of_canonical
504
+ { element = _; canonical_element = canonical_element1; },
505
+ Is_canonical canonical_element2
506
+ | Is_canonical canonical_element1,
507
+ Alias_of_canonical
508
+ { element = _; canonical_element = canonical_element2; }
509
+ | Alias_of_canonical
510
+ { element = _; canonical_element = canonical_element1; },
511
+ Alias_of_canonical
512
+ { element = _; canonical_element = canonical_element2; }
513
+ ->
514
+ debugf "@[<hv2>%a %s %a@ %s@ %a %s %a@]@."
515
+ Simple.print element1
516
+ canonop
517
+ Simple.print canonical_element1
518
+ andop
519
+ Simple.print element2
520
+ canonop
521
+ Simple.print canonical_element2;
522
+ end;
523
+ *)
472
524
match canonical t element1, canonical t element2 with
473
525
| Is_canonical canonical_element1, Is_canonical canonical_element2
474
526
| Alias_of_canonical
@@ -482,40 +534,67 @@ let add_alias t element1 element2 =
482
534
Alias_of_canonical
483
535
{ element = _; canonical_element = canonical_element2; }
484
536
->
485
- let canonical_element, to_be_demoted, alias_of_demoted_element =
486
- let which_element =
487
- choose_canonical_element_to_be_demoted t
488
- ~canonical_element1 ~canonical_element2
537
+ if Simple. equal canonical_element1 canonical_element2
538
+ then
539
+ let canonical_element = canonical_element1 in
540
+ (* According to the contract for [add], [alias_of_demoted_element] must
541
+ not be canonical. Usually this is fine, but what if [element1] or
542
+ [element2] is *itself* canonical? This is true iff that element is
543
+ equal to [canonical_element1]. In that case, we can safely pick the
544
+ other element. (They cannot both be canonical because then they'd both
545
+ be equal to [canonical_element1] and we assume that [element1] and
546
+ [element2] are different.) *)
547
+ (* CR lmaurer: We should just bail out in this case; since [element1] and
548
+ [element2] have the same canonical, they're already aliases, so
549
+ [Typing_env.add_equation] doesn't actually need to do anything at all
550
+ IIUC. *)
551
+ let alias_of_demoted_element =
552
+ if Simple. equal element1 canonical_element then element2 else element1
489
553
in
490
- match which_element with
491
- | Demote_canonical_element1 ->
492
- canonical_element2, canonical_element1, element1
493
- | Demote_canonical_element2 ->
494
- canonical_element1, canonical_element2, element2
495
- in
496
- let t =
497
- add_alias_between_canonical_elements t ~canonical_element
498
- ~to_be_demoted
499
- in
500
- { t;
501
- canonical_element;
502
- alias_of_demoted_element;
503
- }
554
+ { t; canonical_element; alias_of_demoted_element; }
555
+ else
556
+ let canonical_element, to_be_demoted, alias_of_demoted_element =
557
+ let which_element =
558
+ choose_canonical_element_to_be_demoted t
559
+ ~canonical_element1 ~canonical_element2
560
+ in
561
+ match which_element with
562
+ | Demote_canonical_element1 ->
563
+ canonical_element2, canonical_element1, element1
564
+ | Demote_canonical_element2 ->
565
+ canonical_element1, canonical_element2, element2
566
+ in
567
+ let t =
568
+ add_alias_between_canonical_elements t ~canonical_element
569
+ ~to_be_demoted
570
+ in
571
+ { t;
572
+ canonical_element;
573
+ alias_of_demoted_element;
574
+ }
575
+ (*
576
+ end
577
+ *)
504
578
505
579
let add t element1 binding_time_and_mode1
506
580
element2 binding_time_and_mode2 =
507
- Simple. pattern_match element1
508
- ~name: (fun _ -> () )
509
- ~const: (fun const1 ->
510
- Simple. pattern_match element2
511
- ~name: (fun _ -> () )
512
- ~const: (fun const2 ->
513
- if not (Const. equal const1 const2) then begin
581
+ if ! Clflags. flambda_invariant_checks then begin
582
+ if Simple. equal element1 element2 then begin
583
+ Misc. fatal_errorf
584
+ " Cannot alias an element to itself: %a" Simple. print element1
585
+ end ;
586
+ Simple. pattern_match element1
587
+ ~name: (fun _ -> () )
588
+ ~const: (fun const1 ->
589
+ Simple. pattern_match element2
590
+ ~name: (fun _ -> () )
591
+ ~const: (fun const2 ->
514
592
Misc. fatal_errorf
515
- " Cannot add alias between two non-equal consts: %a <> %a"
593
+ " Cannot add alias between two consts: %a, %a"
516
594
Const. print const1
517
595
Const. print const2
518
- end ));
596
+ ));
597
+ end ;
519
598
let original_t = t in
520
599
let element1 = Simple. without_rec_info element1 in
521
600
let element2 = Simple. without_rec_info element2 in
0 commit comments