Skip to content

Commit 7caac4b

Browse files
committed
Zero alloc: add payload "opt" and "-zero-alloc-check {default|all|none|opt}" flag (#1936)
1 parent 880dc4e commit 7caac4b

22 files changed

+233
-66
lines changed

backend/checkmach.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1162,7 +1162,13 @@ end
11621162
module Spec_zero_alloc : Spec = struct
11631163
let property = Cmm.Zero_alloc
11641164

1165-
let enabled () = !Clflags.zero_alloc_check
1165+
let enabled () =
1166+
(* Checkmach no longer distinguishes between opt and default checks. *)
1167+
match !Clflags.zero_alloc_check with
1168+
| No_check -> false
1169+
| Check_default -> true
1170+
| Check_all -> true
1171+
| Check_opt_only -> true
11661172

11671173
(* Compact the mapping from function name to Value.t to reduce size of Checks
11681174
in cmx and memory consumption Compilenv. Different components have

backend/cmm_helpers.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4563,8 +4563,10 @@ let transl_attrib : Lambda.check_attribute -> Cmm.codegen_option list = function
45634563
never_returns_normally;
45644564
loc
45654565
} ]
4566-
| Check { property; strict; loc } ->
4567-
[Check { property = transl_property property; strict; loc }]
4566+
| Check { property; strict; loc; opt } ->
4567+
if Lambda.is_check_enabled ~opt property
4568+
then [Check { property = transl_property property; strict; loc }]
4569+
else []
45684570

45694571
let kind_of_layout (layout : Lambda.layout) =
45704572
match layout with

driver/flambda_backend_args.ml

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@ let mk_heap_reduction_threshold f =
9090
;;
9191

9292
let mk_zero_alloc_check f =
93-
"-zero-alloc-check", Arg.Unit f, " Check that annoted functions do not allocate \
94-
and do not have indirect calls"
93+
let annotations = Clflags.Annotations.(List.map to_string all) in
94+
"-zero-alloc-check", Arg.Symbol (annotations, f),
95+
" Check that annotated functions do not allocate \
96+
and do not have indirect calls. "^Clflags.Annotations.doc
9597

9698
let mk_dcheckmach f =
9799
"-dcheckmach", Arg.Unit f, " (undocumented)"
@@ -586,7 +588,7 @@ module type Flambda_backend_options = sig
586588
val dno_asm_comments : unit -> unit
587589

588590
val heap_reduction_threshold : int -> unit
589-
val zero_alloc_check : unit -> unit
591+
val zero_alloc_check : string -> unit
590592
val dcheckmach : unit -> unit
591593
val checkmach_details_cutoff : int -> unit
592594

@@ -837,7 +839,12 @@ module Flambda_backend_options_impl = struct
837839
let heap_reduction_threshold x =
838840
Flambda_backend_flags.heap_reduction_threshold := x
839841

840-
let zero_alloc_check = set' Clflags.zero_alloc_check
842+
let zero_alloc_check s =
843+
match Clflags.Annotations.of_string s with
844+
| None -> () (* this should not occur as we use Arg.Symbol *)
845+
| Some a ->
846+
Clflags.zero_alloc_check := a
847+
841848
let dcheckmach = set' Flambda_backend_flags.dump_checkmach
842849
let checkmach_details_cutoff n =
843850
let c : Flambda_backend_flags.checkmach_details_cutoff =
@@ -1096,7 +1103,13 @@ module Extra_params = struct
10961103
set_int_option' Flambda_backend_flags.reorder_blocks_random
10971104
| "basic-block-sections" -> set' Flambda_backend_flags.basic_block_sections
10981105
| "heap-reduction-threshold" -> set_int' Flambda_backend_flags.heap_reduction_threshold
1099-
| "zero-alloc-check" -> set' Clflags.zero_alloc_check
1106+
| "zero-alloc-check" ->
1107+
(match Clflags.Annotations.of_string v with
1108+
| Some a -> Clflags.zero_alloc_check := a; true
1109+
| None ->
1110+
raise
1111+
(Arg.Bad
1112+
(Printf.sprintf "Unexpected value %s for %s" v name)))
11001113
| "dump-checkmach" -> set' Flambda_backend_flags.dump_checkmach
11011114
| "checkmach-details-cutoff" ->
11021115
begin match Compenv.check_int ppf name v with

driver/flambda_backend_args.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ module type Flambda_backend_options = sig
4444
val dno_asm_comments : unit -> unit
4545

4646
val heap_reduction_threshold : int -> unit
47-
val zero_alloc_check : unit -> unit
47+
val zero_alloc_check : string -> unit
4848
val dcheckmach : unit -> unit
4949
val checkmach_details_cutoff : int -> unit
5050

middle_end/flambda2/terms/check_attribute.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ let from_lambda : Lambda.check_attribute -> t = function
5858
never_returns_normally;
5959
loc
6060
}
61-
| Check { property; strict; loc } ->
62-
Check { property = Property.from_lambda property; strict; loc }
61+
| Check { property; strict; opt; loc } ->
62+
if Lambda.is_check_enabled ~opt property
63+
then Check { property = Property.from_lambda property; strict; loc }
64+
else Default_check
6365

6466
let equal x y =
6567
match x, y with

ocaml/lambda/lambda.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ type check_attribute =
509509
| Ignore_assert_all of property
510510
| Check of { property: property;
511511
strict: bool;
512+
opt: bool;
512513
loc: Location.t;
513514
}
514515
| Assume of { property: property;
@@ -1662,3 +1663,12 @@ let array_set_kind mode = function
16621663
| Paddrarray -> Paddrarray_set mode
16631664
| Pintarray -> Pintarray_set
16641665
| Pfloatarray -> Pfloatarray_set
1666+
1667+
let is_check_enabled ~opt property =
1668+
match property with
1669+
| Zero_alloc ->
1670+
match !Clflags.zero_alloc_check with
1671+
| No_check -> false
1672+
| Check_all -> true
1673+
| Check_default -> not opt
1674+
| Check_opt_only -> opt

ocaml/lambda/lambda.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ type check_attribute =
401401
then the property holds (but property violations on
402402
exceptional returns or divering loops are ignored).
403403
This definition may not be applicable to new properties. *)
404+
opt: bool;
404405
loc: Location.t;
405406
}
406407
| Assume of { property: property;
@@ -770,3 +771,4 @@ val array_ref_kind : alloc_mode -> array_kind -> array_ref_kind
770771

771772
(** The mode will be discarded if unnecessary for the given [array_kind] *)
772773
val array_set_kind : modify_mode -> array_kind -> array_set_kind
774+
val is_check_enabled : opt:bool -> property -> bool

ocaml/lambda/printlambda.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -687,9 +687,9 @@ let check_attribute ppf check =
687687
(check_property p)
688688
(if strict then "_strict" else "")
689689
(if never_returns_normally then "_never_returns_normally" else "")
690-
| Check {property=p; strict; loc = _} ->
691-
fprintf ppf "assert_%s%s@ "
692-
(check_property p)
690+
| Check {property=p; strict; loc = _; opt} ->
691+
fprintf ppf "assert_%s%s%s@ "
692+
(check_property p) (if opt then "_opt" else "")
693693
(if strict then "_strict" else "")
694694

695695
let function_attribute ppf t =

ocaml/lambda/translattribute.ml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,13 @@ let parse_property_attribute attr property =
251251
| Some {Parsetree.attr_name = {txt; loc}; attr_payload = payload}->
252252
parse_ids_payload txt loc
253253
~default:Default_check
254-
~empty:(Check { property; strict = false; loc; } )
254+
~empty:(Check { property; strict = false; opt = false; loc; } )
255255
[
256256
["assume"],
257257
Assume { property; strict = false; never_returns_normally = false; loc; };
258-
["strict"], Check { property; strict = true; loc; };
258+
["strict"], Check { property; strict = true; opt = false; loc; };
259+
["opt"], Check { property; strict = false; opt = true; loc; };
260+
["opt"; "strict"; ], Check { property; strict = true; opt = true; loc; };
259261
["assume"; "strict"],
260262
Assume { property; strict = true; never_returns_normally = false; loc; };
261263
["assume"; "never_returns_normally"],
@@ -312,8 +314,8 @@ let get_property_attribute l p =
312314
| None, (Check _ | Assume _ | Ignore_assert_all _) -> assert false
313315
| Some _, Ignore_assert_all _ -> ()
314316
| Some _, Assume _ -> ()
315-
| Some attr, Check _ ->
316-
if !Clflags.zero_alloc_check && !Clflags.native_code then
317+
| Some attr, Check { opt; _ } ->
318+
if Lambda.is_check_enabled ~opt p && !Clflags.native_code then
317319
(* The warning for unchecked functions will not trigger if the check is requested
318320
through the [@@@zero_alloc all] top-level annotation rather than through the
319321
function annotation [@zero_alloc]. *)

ocaml/parsing/builtin_attributes.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ let parse_attribute_with_ident_payload attr ~name ~f =
586586
let zero_alloc_attribute (attr : Parsetree.attribute) =
587587
parse_attribute_with_ident_payload attr
588588
~name:"zero_alloc" ~f:(function
589-
| "check" -> Clflags.zero_alloc_check := true
589+
| "check" -> Clflags.zero_alloc_check := Clflags.Annotations.Check_default
590590
| "all" ->
591591
Clflags.zero_alloc_check_assert_all := true
592592
| _ ->

0 commit comments

Comments
 (0)