Skip to content

Commit f46ddec

Browse files
authored
flambda-backend: Use Meet_with for mode crossing (#2363)
* cleaning up of mode system * use meet_with for mode crossing * add comment
1 parent 9ba5508 commit f46ddec

File tree

4 files changed

+176
-168
lines changed

4 files changed

+176
-168
lines changed

typing/ctype.ml

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5559,10 +5559,8 @@ let build_submode posi m =
55595559
if posi then build_submode_pos (Alloc.allow_left m)
55605560
else build_submode_neg (Alloc.allow_right m)
55615561

5562-
(* CR layouts v2.8: use the meet-with-constant morphism when available *)
55635562
(* CR layouts v2.8: merge with Typecore.mode_cross_left when [Value] and
55645563
[Alloc] get unified *)
5565-
(* The approach here works only for 2-element modal axes. *)
55665564
let mode_cross_left env ty mode =
55675565
(* CR layouts v2.8: The old check didn't check for principality, and so
55685566
this one doesn't either. I think it should. But actually test results
@@ -5571,49 +5569,16 @@ let mode_cross_left env ty mode =
55715569
now; will return and figure this out later. *)
55725570
let jkind = type_jkind_purely env ty in
55735571
let upper_bounds = Jkind.get_modal_upper_bounds jkind in
5574-
let mode = Alloc.disallow_right mode in
5575-
let mode =
5576-
if Locality.Const.le upper_bounds.locality Locality.Const.min
5577-
then Alloc.meet_with_locality Locality.Const.min mode
5578-
else mode
5579-
in
5580-
let mode =
5581-
if Linearity.Const.le upper_bounds.linearity Linearity.Const.min
5582-
then Alloc.meet_with_linearity Linearity.Const.min mode
5583-
else mode
5584-
in
5585-
let mode =
5586-
if Uniqueness.Const.le upper_bounds.uniqueness Uniqueness.Const.min
5587-
then Alloc.meet_with_uniqueness Uniqueness.Const.min mode
5588-
else mode
5589-
in
5590-
mode
5572+
Alloc.meet_with upper_bounds mode
55915573

55925574
(* CR layouts v2.8: merge with Typecore.expect_mode_cross when [Value]
55935575
and [Alloc] get unified *)
5594-
(* The approach here works only for 2-element modal axes. *)
55955576
let mode_cross_right env ty mode =
55965577
(* CR layouts v2.8: This should probably check for principality. See
55975578
similar comment in [mode_cross_left]. *)
55985579
let jkind = type_jkind_purely env ty in
55995580
let upper_bounds = Jkind.get_modal_upper_bounds jkind in
5600-
let mode = Alloc.disallow_left mode in
5601-
let mode =
5602-
if Locality.Const.le upper_bounds.locality Locality.Const.min
5603-
then Alloc.join_with_locality Locality.Const.max mode
5604-
else mode
5605-
in
5606-
let mode =
5607-
if Linearity.Const.le upper_bounds.linearity Linearity.Const.min
5608-
then Alloc.join_with_linearity Linearity.Const.max mode
5609-
else mode
5610-
in
5611-
let mode =
5612-
if Uniqueness.Const.le upper_bounds.uniqueness Uniqueness.Const.min
5613-
then Alloc.join_with_uniqueness Uniqueness.Const.max mode
5614-
else mode
5615-
in
5616-
mode
5581+
Alloc.imply upper_bounds mode
56175582

56185583
let rec build_subtype env (visited : transient_expr list)
56195584
(loops : (int * type_expr) list) posi level t =

typing/mode.ml

Lines changed: 114 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,7 @@ module Comonadic_with_regionality = struct
12591259
end
12601260

12611261
include Common (Obj)
1262+
open Obj
12621263

12631264
type error =
12641265
[ `Regionality of Regionality.error
@@ -1308,6 +1309,11 @@ module Comonadic_with_regionality = struct
13081309
(Meet_with (C.max_with Obj.obj Linearity c))
13091310
(S.Positive.disallow_right m)
13101311

1312+
let meet_with c m =
1313+
Solver.via_monotone obj (Meet_with c) (Solver.disallow_right m)
1314+
1315+
let imply c m = Solver.via_monotone obj (Imply c) (Solver.disallow_left m)
1316+
13111317
let zap_to_legacy m =
13121318
let regionality = regionality m |> Regionality.zap_to_legacy in
13131319
let linearity = linearity m |> Linearity.zap_to_legacy in
@@ -1351,6 +1357,7 @@ module Comonadic_with_locality = struct
13511357
end
13521358

13531359
include Common (Obj)
1360+
open Obj
13541361

13551362
type error =
13561363
[ `Locality of Locality.error
@@ -1405,6 +1412,11 @@ module Comonadic_with_locality = struct
14051412
let linearity = linearity m |> Linearity.zap_to_legacy in
14061413
locality, linearity
14071414

1415+
let meet_with c m =
1416+
Solver.via_monotone obj (Meet_with c) (Solver.disallow_right m)
1417+
1418+
let imply c m = Solver.via_monotone obj (Imply c) (Solver.disallow_left m)
1419+
14081420
let legacy = of_const Const.legacy
14091421

14101422
(* overriding to report the offending axis *)
@@ -1443,6 +1455,7 @@ module Monadic = struct
14431455
end
14441456

14451457
include Common (Obj)
1458+
open Obj
14461459

14471460
type error = [`Uniqueness of Uniqueness.error]
14481461

@@ -1473,6 +1486,11 @@ module Monadic = struct
14731486
(Join_with (C.min_with Obj.obj Uniqueness c))
14741487
(S.Negative.disallow_right m)
14751488

1489+
let meet_with c m =
1490+
Solver.via_monotone obj (Join_with c) (Solver.disallow_right m)
1491+
1492+
let imply c m = Solver.via_monotone obj (Subtract c) (Solver.disallow_left m)
1493+
14761494
let zap_to_legacy m =
14771495
let uniqueness = uniqueness m |> Uniqueness.zap_to_legacy in
14781496
uniqueness, ()
@@ -1514,6 +1532,12 @@ module Value = struct
15141532

15151533
type lr = (allowed * allowed) t
15161534

1535+
type ('a, 'b, 'c) modes =
1536+
{ regionality : 'a;
1537+
linearity : 'b;
1538+
uniqueness : 'c
1539+
}
1540+
15171541
let min = { comonadic = Comonadic.min; monadic = Monadic.min }
15181542

15191543
let max =
@@ -1604,23 +1628,26 @@ module Value = struct
16041628

16051629
let zap_to_floor { comonadic; monadic } =
16061630
match Monadic.zap_to_floor monadic, Comonadic.zap_to_floor comonadic with
1607-
| (uniqueness, ()), (locality, linearity) -> locality, linearity, uniqueness
1631+
| (uniqueness, ()), (regionality, linearity) ->
1632+
{ regionality; linearity; uniqueness }
16081633

16091634
let zap_to_ceil { comonadic; monadic } =
16101635
match Monadic.zap_to_ceil monadic, Comonadic.zap_to_ceil comonadic with
1611-
| (uniqueness, ()), (locality, linearity) -> locality, linearity, uniqueness
1636+
| (uniqueness, ()), (regionality, linearity) ->
1637+
{ regionality; linearity; uniqueness }
16121638

16131639
let zap_to_legacy { comonadic; monadic } =
16141640
match Monadic.zap_to_legacy monadic, Comonadic.zap_to_legacy comonadic with
1615-
| (uniqueness, ()), (locality, linearity) -> locality, linearity, uniqueness
1641+
| (uniqueness, ()), (regionality, linearity) ->
1642+
{ regionality; linearity; uniqueness }
16161643

16171644
let check_const { comonadic; monadic } =
1618-
let locality, linearity = Comonadic.check_const comonadic in
1645+
let regionality, linearity = Comonadic.check_const comonadic in
16191646
let uniqueness = Monadic.check_const monadic in
1620-
locality, linearity, uniqueness
1647+
{ regionality; linearity; uniqueness }
16211648

1622-
let of_const (locality, linearity, uniqueness) =
1623-
let comonadic = Comonadic.of_const (locality, linearity) in
1649+
let of_const { regionality; linearity; uniqueness } =
1650+
let comonadic = Comonadic.of_const (regionality, linearity) in
16241651
let monadic = Monadic.of_const (uniqueness, ()) in
16251652
{ comonadic; monadic }
16261653

@@ -1720,34 +1747,68 @@ module Value = struct
17201747
(Comonadic_to_monadic Comonadic.Obj.obj) m
17211748

17221749
module Const = struct
1723-
type t = Regionality.Const.t * Linearity.Const.t * Uniqueness.Const.t
1750+
type t = (Regionality.Const.t, Linearity.Const.t, Uniqueness.Const.t) modes
17241751

1725-
let min = Regionality.Const.min, Linearity.Const.min, Uniqueness.Const.min
1752+
let split { regionality; linearity; uniqueness } =
1753+
let monadic = uniqueness, () in
1754+
let comonadic = regionality, linearity in
1755+
{ comonadic; monadic }
17261756

1727-
let max = Regionality.Const.max, Linearity.Const.max, Uniqueness.Const.max
1757+
let _merge { comonadic; monadic } =
1758+
let regionality, linearity = comonadic in
1759+
let uniqueness, () = monadic in
1760+
{ regionality; linearity; uniqueness }
17281761

1729-
let le (locality0, linearity0, uniqueness0)
1730-
(locality1, linearity1, uniqueness1) =
1731-
Regionality.Const.le locality0 locality1
1732-
&& Uniqueness.Const.le uniqueness0 uniqueness1
1733-
&& Linearity.Const.le linearity0 linearity1
1762+
let min =
1763+
{ regionality = Regionality.Const.min;
1764+
linearity = Linearity.Const.min;
1765+
uniqueness = Uniqueness.Const.min
1766+
}
1767+
1768+
let max =
1769+
{ regionality = Regionality.Const.max;
1770+
linearity = Linearity.Const.max;
1771+
uniqueness = Uniqueness.Const.max
1772+
}
1773+
1774+
let le m0 m1 =
1775+
Regionality.Const.le m0.regionality m1.regionality
1776+
&& Uniqueness.Const.le m0.uniqueness m1.uniqueness
1777+
&& Linearity.Const.le m0.linearity m1.linearity
17341778

17351779
let print ppf m = print () ppf (of_const m)
17361780

17371781
let legacy =
1738-
Regionality.Const.legacy, Linearity.Const.legacy, Uniqueness.Const.legacy
1782+
{ regionality = Regionality.Const.legacy;
1783+
linearity = Linearity.Const.legacy;
1784+
uniqueness = Uniqueness.Const.legacy
1785+
}
17391786

1740-
let meet (l0, l1, l2) (r0, r1, r2) =
1741-
( Regionality.Const.meet l0 r0,
1742-
Linearity.Const.meet l1 r1,
1743-
Uniqueness.Const.meet l2 r2 )
1787+
let meet m0 m1 =
1788+
let regionality = Regionality.Const.meet m0.regionality m1.regionality in
1789+
let linearity = Linearity.Const.meet m0.linearity m1.linearity in
1790+
let uniqueness = Uniqueness.Const.meet m0.uniqueness m1.uniqueness in
1791+
{ regionality; linearity; uniqueness }
17441792

1745-
let join (l0, l1, l2) (r0, r1, r2) =
1746-
( Regionality.Const.join l0 r0,
1747-
Linearity.Const.join l1 r1,
1748-
Uniqueness.Const.join l2 r2 )
1793+
let join m0 m1 =
1794+
let regionality = Regionality.Const.join m0.regionality m1.regionality in
1795+
let linearity = Linearity.Const.join m0.linearity m1.linearity in
1796+
let uniqueness = Uniqueness.Const.join m0.uniqueness m1.uniqueness in
1797+
{ regionality; linearity; uniqueness }
17491798
end
17501799

1800+
let meet_with c { comonadic; monadic } =
1801+
let c = Const.split c in
1802+
let comonadic = Comonadic.meet_with c.comonadic comonadic in
1803+
let monadic = Monadic.meet_with c.monadic monadic in
1804+
{ monadic; comonadic }
1805+
1806+
let imply c { comonadic; monadic } =
1807+
let c = Const.split c in
1808+
let comonadic = Comonadic.imply c.comonadic comonadic in
1809+
let monadic = Monadic.imply c.monadic monadic in
1810+
{ monadic; comonadic }
1811+
17511812
module List = struct
17521813
type nonrec 'd t = 'd t list
17531814

@@ -1777,6 +1838,12 @@ module Alloc = struct
17771838

17781839
type lr = (allowed * allowed) t
17791840

1841+
type ('a, 'b, 'c) modes =
1842+
{ locality : 'a;
1843+
linearity : 'b;
1844+
uniqueness : 'c
1845+
}
1846+
17801847
let min = { comonadic = Comonadic.min; monadic = Monadic.min }
17811848

17821849
let max = { comonadic = Comonadic.min; monadic = Monadic.max }
@@ -1961,20 +2028,14 @@ module Alloc = struct
19612028
S.Positive.via_antitone Comonadic.Obj.obj Monadic_to_comonadic_min
19622029
(Monadic.disallow_left m)
19632030

1964-
module Const = struct
1965-
type ('loc, 'lin, 'uni) modes =
1966-
{ locality : 'loc;
1967-
linearity : 'lin;
1968-
uniqueness : 'uni
1969-
}
2031+
let of_const { locality; linearity; uniqueness } =
2032+
let comonadic = Comonadic.of_const (locality, linearity) in
2033+
let monadic = Monadic.of_const (uniqueness, ()) in
2034+
{ comonadic; monadic }
19702035

2036+
module Const = struct
19712037
type t = (Locality.Const.t, Linearity.Const.t, Uniqueness.Const.t) modes
19722038

1973-
let of_const { locality; linearity; uniqueness } =
1974-
let comonadic = Comonadic.of_const (locality, linearity) in
1975-
let monadic = Monadic.of_const (uniqueness, ()) in
1976-
{ comonadic; monadic }
1977-
19782039
let min =
19792040
let locality = Locality.Const.min in
19802041
let linearity = Linearity.Const.min in
@@ -2059,7 +2120,17 @@ module Alloc = struct
20592120
merge { comonadic; monadic }
20602121
end
20612122

2062-
let of_const = Const.of_const
2123+
let meet_with c { comonadic; monadic } =
2124+
let c = Const.split c in
2125+
let comonadic = Comonadic.meet_with c.comonadic comonadic in
2126+
let monadic = Monadic.meet_with c.monadic monadic in
2127+
{ monadic; comonadic }
2128+
2129+
let imply c { comonadic; monadic } =
2130+
let c = Const.split c in
2131+
let comonadic = Comonadic.imply c.comonadic comonadic in
2132+
let monadic = Monadic.imply c.monadic monadic in
2133+
{ monadic; comonadic }
20632134

20642135
let zap_to_floor { comonadic; monadic } : Const.t =
20652136
match Monadic.zap_to_floor monadic, Comonadic.zap_to_floor comonadic with
@@ -2104,6 +2175,13 @@ module Alloc = struct
21042175
{ comonadic; monadic }
21052176
end
21062177

2178+
module Const = struct
2179+
let alloc_as_value ({ locality; linearity; uniqueness } : Alloc.Const.t) :
2180+
Value.Const.t =
2181+
let regionality = C.locality_as_regionality locality in
2182+
{ regionality; linearity; uniqueness }
2183+
end
2184+
21072185
let alloc_as_value m =
21082186
let { comonadic; monadic } = m in
21092187
let comonadic =

0 commit comments

Comments
 (0)