Skip to content

Commit 73200c0

Browse files
authored
flambda-backend: zero alloc: assume on calls (ocaml-flambda#2165)
1 parent e52abba commit 73200c0

16 files changed

+476
-47
lines changed

.depend

+23-2
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,11 @@ utils/warnings.cmx : \
282282
utils/misc.cmx \
283283
utils/warnings.cmi
284284
utils/warnings.cmi :
285+
utils/zero_alloc_utils.cmo : \
286+
utils/zero_alloc_utils.cmi
287+
utils/zero_alloc_utils.cmx : \
288+
utils/zero_alloc_utils.cmi
289+
utils/zero_alloc_utils.cmi :
285290
parsing/ast_helper.cmo : \
286291
parsing/syntaxerr.cmi \
287292
parsing/parsetree.cmi \
@@ -3943,25 +3948,36 @@ middle_end/variable.cmi : \
39433948
utils/identifiable.cmi \
39443949
typing/ident.cmi \
39453950
utils/compilation_unit.cmi
3951+
lambda/assume_info.cmo : \
3952+
utils/zero_alloc_utils.cmi \
3953+
lambda/assume_info.cmi
3954+
lambda/assume_info.cmx : \
3955+
utils/zero_alloc_utils.cmx \
3956+
lambda/assume_info.cmi
3957+
lambda/assume_info.cmi : \
3958+
utils/zero_alloc_utils.cmi
39463959
lambda/debuginfo.cmo : \
39473960
parsing/location.cmi \
39483961
utils/int_replace_polymorphic_compare.cmi \
39493962
typing/ident.cmi \
39503963
utils/compilation_unit.cmi \
39513964
parsing/asttypes.cmi \
3965+
lambda/assume_info.cmi \
39523966
lambda/debuginfo.cmi
39533967
lambda/debuginfo.cmx : \
39543968
parsing/location.cmx \
39553969
utils/int_replace_polymorphic_compare.cmx \
39563970
typing/ident.cmx \
39573971
utils/compilation_unit.cmx \
39583972
parsing/asttypes.cmi \
3973+
lambda/assume_info.cmx \
39593974
lambda/debuginfo.cmi
39603975
lambda/debuginfo.cmi : \
39613976
parsing/location.cmi \
39623977
typing/ident.cmi \
39633978
utils/compilation_unit.cmi \
3964-
parsing/asttypes.cmi
3979+
parsing/asttypes.cmi \
3980+
lambda/assume_info.cmi
39653981
lambda/lambda.cmo : \
39663982
typing/types.cmi \
39673983
typing/typedtree.cmi \
@@ -4231,6 +4247,7 @@ lambda/translattribute.cmo : \
42314247
utils/clflags.cmi \
42324248
parsing/builtin_attributes.cmi \
42334249
parsing/asttypes.cmi \
4250+
lambda/assume_info.cmi \
42344251
lambda/translattribute.cmi
42354252
lambda/translattribute.cmx : \
42364253
utils/warnings.cmx \
@@ -4244,12 +4261,14 @@ lambda/translattribute.cmx : \
42444261
utils/clflags.cmx \
42454262
parsing/builtin_attributes.cmx \
42464263
parsing/asttypes.cmi \
4264+
lambda/assume_info.cmx \
42474265
lambda/translattribute.cmi
42484266
lambda/translattribute.cmi : \
42494267
typing/typedtree.cmi \
42504268
parsing/parsetree.cmi \
42514269
parsing/location.cmi \
4252-
lambda/lambda.cmi
4270+
lambda/lambda.cmi \
4271+
lambda/assume_info.cmi
42534272
lambda/translclass.cmo : \
42544273
typing/types.cmi \
42554274
typing/typeopt.cmi \
@@ -4325,6 +4344,7 @@ lambda/translcore.cmo : \
43254344
utils/clflags.cmi \
43264345
typing/btype.cmi \
43274346
parsing/asttypes.cmi \
4347+
lambda/assume_info.cmi \
43284348
lambda/translcore.cmi
43294349
lambda/translcore.cmx : \
43304350
typing/types.cmx \
@@ -4358,6 +4378,7 @@ lambda/translcore.cmx : \
43584378
utils/clflags.cmx \
43594379
typing/btype.cmx \
43604380
parsing/asttypes.cmi \
4381+
lambda/assume_info.cmx \
43614382
lambda/translcore.cmi
43624383
lambda/translcore.cmi : \
43634384
typing/types.cmi \

compilerlibs/Makefile.compilerlibs

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ UTILS = \
5353
utils/compilation_unit.cmo utils/linkage_name.cmo utils/symbol.cmo \
5454
utils/import_info.cmo \
5555
utils/lazy_backtrack.cmo \
56+
utils/zero_alloc_utils.cmo \
5657
utils/diffing.cmo \
5758
utils/diffing_with_keys.cmo
5859
UTILS_CMI = \
@@ -124,6 +125,7 @@ TYPING = \
124125
typing/typedecl_properties.cmo \
125126
typing/typedecl_variance.cmo \
126127
typing/typedecl_separability.cmo \
128+
lambda/assume_info.cmo \
127129
lambda/debuginfo.cmo lambda/lambda.cmo \
128130
typing/typedecl.cmo \
129131
typing/typeopt.cmo \

dune

+4-1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
local_store target_system compilation_unit import_info linkage_name symbol
7878
lazy_backtrack diffing diffing_with_keys
7979
language_extension_kernel language_extension
80+
zero_alloc_utils
8081

8182
;; PARSING
8283
location longident docstrings printast syntaxerr ast_helper
@@ -98,7 +99,7 @@
9899
annot outcometree
99100

100101
;; lambda/
101-
debuginfo lambda matching printlambda runtimedef runtimetags tmc simplif switch
102+
assume_info debuginfo lambda matching printlambda runtimedef runtimetags tmc simplif switch
102103
translmode
103104
transl_comprehension_utils
104105
transl_array_comprehension transl_list_comprehension
@@ -329,6 +330,7 @@
329330
(annot.mli as compiler-libs/annot.mli)
330331
(outcometree.mli as compiler-libs/outcometree.mli)
331332
(debuginfo.mli as compiler-libs/debuginfo.mli)
333+
(assume_info.mli as compiler-libs/assume_info.mli)
332334
(lambda.mli as compiler-libs/lambda.mli)
333335
(matching.mli as compiler-libs/matching.mli)
334336
(printlambda.mli as compiler-libs/printlambda.mli)
@@ -359,5 +361,6 @@
359361
(compilation_unit.mli as compiler-libs/compilation_unit.mli)
360362
(linkage_name.mli as compiler-libs/linkage_name.mli)
361363
(symbol.mli as compiler-libs/symbol.mli)
364+
(zero_alloc_utils.mli as compiler-libs/zero_alloc_utils.mli)
362365

363366
))

lambda/.ocamlformat-enable

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
assume_info.ml
2+
assume_info.mli

lambda/assume_info.ml

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
(*
2+
3+
The meaning of keywords [strict] and [never_returns_normally]
4+
is defined in terms of abstract values as follows:
5+
6+
relaxed (default): nor = Safe and exn = Top and div = Top
7+
strict: nor = Safe and exn = Safe and div = Safe
8+
never_returns_normally: nor = Bot and exn = Top and div = Top
9+
10+
where [nor] means normal return of the call, [exn] means return via an exception,
11+
[div] means diverging (non-terminating) executions,
12+
and the meaning and order of elements is:
13+
14+
Top may allocate
15+
Safe does not allocate on any execution paths
16+
Bot unreachable
17+
18+
Using more than one keyword means intersection (i.e., meet of the elements,
19+
pointwise lifted to tuples), so we get the following:
20+
21+
[@zero_alloc assume] nor = Safe and exn = Top and div = Top
22+
[@zero_alloc assume strict] nor = Safe and exn = Safe and div = Safe
23+
[@zero_alloc assume strict never_returns_normally] nor = Bot and exn = Safe and div = Safe
24+
[@zero_alloc assume never_returns_normally] nor = Bot and exn = Top and div = Top
25+
26+
See [Value] and [Annotation] in [backend/checkmach.ml].
27+
*)
28+
(* CR gyorsh: should we move [Value] and [Annotation] here or maybe "utils" and use them
29+
directly, instead of the weird compare function that abstracts them? Perhaps we
30+
should translate "strict" and "never_returns_normally" directly into (nor,exn,div)
31+
*)
32+
33+
module Witnesses = struct
34+
type t = unit
35+
36+
let join _ _ = ()
37+
let meet _ _ = ()
38+
let print _ _ = ()
39+
let empty = ()
40+
let compare _ _ = 0
41+
end
42+
43+
include Zero_alloc_utils.Make (Witnesses)
44+
45+
type t = No_assume | Assume of Value.t
46+
47+
let compare t1 t2 =
48+
match (t1, t2) with
49+
| No_assume, No_assume -> 0
50+
| Assume v1, Assume v2 -> Value.compare v1 v2
51+
| No_assume, Assume _ -> -1
52+
| Assume _, No_assume -> 1
53+
54+
let equal t1 t2 = compare t1 t2 = 0
55+
56+
let print ppf = function
57+
| No_assume -> ()
58+
| Assume v -> Format.fprintf ppf "%a" (Value.print ~witnesses:false) v
59+
60+
let to_string v = Format.asprintf "%a" print v
61+
62+
let join t1 t2 =
63+
match (t1, t2) with
64+
| No_assume, No_assume -> No_assume
65+
| No_assume, Assume _
66+
| Assume _, No_assume ->
67+
No_assume
68+
| Assume t1, Assume t2 -> Assume (Value.join t1 t2)
69+
70+
let meet t1 t2 =
71+
match (t1, t2) with
72+
| No_assume, No_assume -> No_assume
73+
| No_assume, (Assume _ as t)
74+
| (Assume _ as t), No_assume ->
75+
t
76+
| Assume t1, Assume t2 -> Assume (Value.meet t1 t2)
77+
78+
let none = No_assume
79+
80+
let create ~strict ~never_returns_normally =
81+
let res =
82+
if strict then
83+
Value.safe
84+
else
85+
Value.relaxed Witnesses.empty
86+
in
87+
let res =
88+
if never_returns_normally then
89+
{ res with nor = V.Bot }
90+
else
91+
res
92+
in
93+
Assume res
94+
95+
let get_value t =
96+
match t with
97+
| No_assume -> None
98+
| Assume v -> Some v
99+
100+
let is_none t =
101+
match t with
102+
| No_assume -> true
103+
| Assume _ -> false

lambda/assume_info.mli

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
type t
2+
3+
val none : t
4+
val create : strict:bool -> never_returns_normally:bool -> t
5+
val compare : t -> t -> int
6+
val equal : t -> t -> bool
7+
val join : t -> t -> t
8+
val meet : t -> t -> t
9+
val to_string : t -> string
10+
val print : Format.formatter -> t -> unit
11+
val is_none : t -> bool
12+
13+
module Witnesses : sig
14+
type t = unit
15+
16+
val join : t -> t -> t
17+
val meet : t -> t -> t
18+
val print : Format.formatter -> t -> unit
19+
val compare : t -> t -> int
20+
end
21+
22+
include module type of Zero_alloc_utils.Make (Witnesses)
23+
24+
val get_value : t -> Value.t option

0 commit comments

Comments
 (0)