@@ -455,20 +455,72 @@ type add_result = {
455455let invariant_add_result ~original_t { canonical_element; alias_of_demoted_element; t; } =
456456 if ! Clflags. flambda_invariant_checks then begin
457457 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@ \
462472 Resulting alias tracker:@ %a"
463- Simple. print canonical_element
464473 Simple. print alias_of_demoted_element
465474 print original_t
466475 print t
467- end
468- end
476+ | Alias_of_canonical _ -> ()
469477 end
470478
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+
471489let 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+ *)
472524 match canonical t element1, canonical t element2 with
473525 | Is_canonical canonical_element1, Is_canonical canonical_element2
474526 | Alias_of_canonical
@@ -482,40 +534,67 @@ let add_alias t element1 element2 =
482534 Alias_of_canonical
483535 { element = _; canonical_element = canonical_element2; }
484536 ->
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
489553 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+ *)
504578
505579let add t element1 binding_time_and_mode1
506580 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 ->
514592 Misc. fatal_errorf
515- " Cannot add alias between two non-equal consts: %a <> %a"
593+ " Cannot add alias between two consts: %a, %a"
516594 Const. print const1
517595 Const. print const2
518- end ));
596+ ));
597+ end ;
519598 let original_t = t in
520599 let element1 = Simple. without_rec_info element1 in
521600 let element2 = Simple. without_rec_info element2 in
0 commit comments