Skip to content

Commit bf2a8bf

Browse files
authored
flambda-backend: Add portability and contention (ocaml-flambda#2398)
1 parent 0b20098 commit bf2a8bf

18 files changed

+1096
-147
lines changed

testsuite/tests/formatting/test_locations.dlocations.ocamlc.reference

+4-4
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,14 @@ let rec fib = function | 0 | 1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2))
8888
<def_rec>
8989
pattern (test_locations.ml[17,534+8]..test_locations.ml[17,534+11])
9090
Tpat_var "fib"
91-
value_mode global,many,shared
91+
value_mode global,many,nonportable,shared,uncontended
9292
expression (test_locations.ml[17,534+14]..test_locations.ml[19,572+34])
9393
Texp_function
9494
region true
95-
alloc_mode global,many,shared
95+
alloc_mode global,many,nonportable,shared,uncontended
9696
[]
9797
Tfunction_cases (test_locations.ml[17,534+14]..test_locations.ml[19,572+34])
98-
alloc_mode global,many,shared
98+
alloc_mode global,many,nonportable,shared,uncontended
9999
value
100100
[
101101
<case>
@@ -110,7 +110,7 @@ let rec fib = function | 0 | 1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2))
110110
<case>
111111
pattern (test_locations.ml[19,572+4]..test_locations.ml[19,572+5])
112112
Tpat_var "n"
113-
value_mode global,many,unique
113+
value_mode global,many,portable,unique,uncontended
114114
expression (test_locations.ml[19,572+9]..test_locations.ml[19,572+34])
115115
Texp_apply
116116
apply_mode Tail

testsuite/tests/formatting/test_locations.dno-locations.ocamlc.reference

+4-4
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,14 @@ let rec fib = function | 0 | 1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2))
8888
<def_rec>
8989
pattern
9090
Tpat_var "fib"
91-
value_mode global,many,shared
91+
value_mode global,many,nonportable,shared,uncontended
9292
expression
9393
Texp_function
9494
region true
95-
alloc_mode global,many,shared
95+
alloc_mode global,many,nonportable,shared,uncontended
9696
[]
9797
Tfunction_cases
98-
alloc_mode global,many,shared
98+
alloc_mode global,many,nonportable,shared,uncontended
9999
value
100100
[
101101
<case>
@@ -110,7 +110,7 @@ let rec fib = function | 0 | 1 -> 1 | n -> (fib (n - 1)) + (fib (n - 2))
110110
<case>
111111
pattern
112112
Tpat_var "n"
113-
value_mode global,many,unique
113+
value_mode global,many,portable,unique,uncontended
114114
expression
115115
Texp_apply
116116
apply_mode Tail

testsuite/tests/typing-modes/class.ml

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
(* TEST
2+
flags += "-extension unique";
3+
expect;
4+
*)
5+
6+
(* This file tests that classes/objects are sound wrt modes. *)
7+
8+
let unique_use : 'a @ unique -> unit = fun _ -> ()
9+
10+
let portable_use : 'a @ portable -> unit = fun _ -> ()
11+
[%%expect{|
12+
val unique_use : unique_ 'a -> unit = <fun>
13+
val portable_use : 'a @ portable -> unit = <fun>
14+
|}]
15+
16+
(* There is a closure_lock of legacy around a class. We test for comonadic and
17+
monadic axes separately. *)
18+
19+
(* class cannot refer to external local things *)
20+
let foo () =
21+
let local_ s = "hello" in
22+
let module M = struct
23+
class cla = object
24+
val k = s
25+
end
26+
end in ()
27+
[%%expect{|
28+
Line 5, characters 16-17:
29+
5 | val k = s
30+
^
31+
Error: The value s is local, so cannot be used inside a class.
32+
|}]
33+
34+
(* class can refer to external unique things, but only as shared. *)
35+
let foo () =
36+
let unique_ s = "hello" in
37+
let module M = struct
38+
class cla = object
39+
val k = unique_use s
40+
end
41+
end in ()
42+
[%%expect{|
43+
Line 5, characters 27-28:
44+
5 | val k = unique_use s
45+
^
46+
Error: This value is shared but expected to be unique.
47+
Hint: This identifier cannot be used uniquely,
48+
because it is defined in a class.
49+
|}]
50+
51+
(* instance variables need to be defined as legacy *)
52+
class cla = object
53+
val x = ("world" : _ @@ local)
54+
end
55+
[%%expect{|
56+
Line 2, characters 12-34:
57+
2 | val x = ("world" : _ @@ local)
58+
^^^^^^^^^^^^^^^^^^^^^^
59+
Error: This value escapes its region.
60+
|}]
61+
62+
(* instance variables are available as legacy to methods *)
63+
class cla = object
64+
val x = ("world" : _ @@ portable)
65+
66+
method foo = portable_use x
67+
end
68+
[%%expect{|
69+
Line 4, characters 30-31:
70+
4 | method foo = portable_use x
71+
^
72+
Error: This value is nonportable but expected to be portable.
73+
|}]
74+
75+
(* values written to instance variables need to be legacy *)
76+
class cla = object
77+
val mutable x = "hello"
78+
79+
method foo = x <- ("world" : _ @@ local)
80+
end
81+
[%%expect{|
82+
Line 4, characters 22-44:
83+
4 | method foo = x <- ("world" : _ @@ local)
84+
^^^^^^^^^^^^^^^^^^^^^^
85+
Error: This value escapes its region.
86+
|}]
87+
88+
class cla = object
89+
method m = "hello"
90+
end
91+
92+
(* For Pexp_send, the object needs to be legacy *)
93+
let foo () =
94+
let local_ obj = new cla in
95+
obj#m
96+
[%%expect{|
97+
class cla : object method m : string end
98+
Line 8, characters 4-7:
99+
8 | obj#m
100+
^^^
101+
Error: This value escapes its region.
102+
|}]
103+
104+
(* methods are available as legacy *)
105+
let u =
106+
let obj = new cla in
107+
portable_use obj#m
108+
(* CR zqian: this should fail. *)
109+
[%%expect{|
110+
val u : unit = ()
111+
|}]
112+
113+
(* for methods, arguments can be of any modes *)
114+
class cla = object
115+
method foo (x : string) = portable_use x
116+
end
117+
[%%expect{|
118+
class cla : object method foo : string @ portable -> unit end
119+
|}]
120+
121+
(* the argument mode is soundly required during application *)
122+
let foo () =
123+
let x @ nonportable = "hello" in
124+
let o = new cla in
125+
o#foo x
126+
[%%expect{|
127+
Line 4, characters 10-11:
128+
4 | o#foo x
129+
^
130+
Error: This value is nonportable but expected to be portable.
131+
|}]
132+
133+
134+
(* Closing over classes affects closure's mode *)
135+
let u =
136+
let foo () = new cla in
137+
portable_use foo
138+
(* CR zqian: this should fail. *)
139+
[%%expect{|
140+
val u : unit = ()
141+
|}]
142+
143+
module type SC = sig
144+
class cla : object end
145+
end
146+
[%%expect{|
147+
module type SC = sig class cla : object end end
148+
|}]
149+
150+
let u =
151+
let foo () =
152+
let m = (module struct class cla = object end end : SC) in
153+
let module M = (val m) in
154+
new M.cla
155+
in
156+
portable_use foo
157+
[%%expect{|
158+
val u : unit = ()
159+
|}]
160+
161+
(* objects are always legacy *)
162+
let u =
163+
let obj = new cla in
164+
portable_use obj
165+
(* CR zqian: this should fail. *)
166+
[%%expect{|
167+
val u : unit = ()
168+
|}]

testsuite/tests/typing-modes/lazy.ml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
(* TEST
2+
expect;
3+
*)
4+
5+
(* lazy expression is legacy *)
6+
let u =
7+
let _x @ portable = lazy "hello" in
8+
()
9+
(* CR zqian: this should fail. *)
10+
[%%expect{|
11+
val u : unit = ()
12+
|}]
13+
14+
(* lazy body is legacy *)
15+
let x = lazy ("hello" : _ @@ local)
16+
[%%expect{|
17+
Line 1, characters 13-35:
18+
1 | let x = lazy ("hello" : _ @@ local)
19+
^^^^^^^^^^^^^^^^^^^^^^
20+
Error: This value escapes its region.
21+
|}]
22+
23+
(* Forcing lazy gives legacy, but that's in stdlib and not compiler *)

testsuite/tests/typing-modes/modes.ml

+23-1
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,28 @@ Line 1, characters 25-30:
193193
Error: The locality axis has already been specified.
194194
|}]
195195

196+
(* Mixing legacy and new modes *)
197+
type r = local_ unique_ once_ string -> string
198+
[%%expect{|
199+
type r = local_ once_ unique_ string -> string
200+
|}]
201+
202+
type r = local_ unique_ once_ string @ portable contended -> string
203+
[%%expect{|
204+
type r = local_ once_ unique_ string @ portable contended -> string
205+
|}]
206+
207+
type r = string @ local unique once portable contended -> string
208+
[%%expect{|
209+
type r = local_ once_ unique_ string @ portable contended -> string
210+
|}]
211+
212+
type r = string @ local unique once nonportable uncontended -> string
213+
[%%expect{|
214+
type r = local_ once_ unique_ string -> string
215+
|}]
216+
217+
196218
(* modality on constructor arguments and record fields *)
197219

198220
type t = Foo of string @@ global * global_ string
@@ -342,4 +364,4 @@ Line 2, characters 38-45:
342364
2 | val x : string -> string @ local @@ foo bar
343365
^^^^^^^
344366
Error: Modalities on value descriptions are not supported yet.
345-
|}]
367+
|}]

0 commit comments

Comments
 (0)