Skip to content

Commit aafeeda

Browse files
authored
flambda-backend: Zero alloc: add payload "opt" and "-zero-alloc-check {default|all|none|opt}" flag (#1936)
1 parent e65faae commit aafeeda

File tree

7 files changed

+65
-10
lines changed

7 files changed

+65
-10
lines changed

lambda/lambda.ml

+10
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

lambda/lambda.mli

+2
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

lambda/printlambda.ml

+3-3
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 =

lambda/translattribute.ml

+6-4
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]. *)

parsing/builtin_attributes.ml

+1-1
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
| _ ->

utils/clflags.ml

+33-1
Original file line numberDiff line numberDiff line change
@@ -635,5 +635,37 @@ let create_usage_msg program =
635635
let print_arguments program =
636636
Arg.usage !arg_spec (create_usage_msg program)
637637

638-
let zero_alloc_check = ref false (* -zero-alloc-check *)
638+
module Annotations = struct
639+
type t = Check_default | Check_all | Check_opt_only | No_check
640+
641+
let all = [ Check_default; Check_all; Check_opt_only; No_check ]
642+
643+
let to_string = function
644+
| Check_default -> "default"
645+
| Check_all -> "all"
646+
| Check_opt_only -> "opt"
647+
| No_check -> "none"
648+
649+
let equal t1 t2 =
650+
match t1, t2 with
651+
| Check_default, Check_default -> true
652+
| Check_all, Check_all -> true
653+
| No_check, No_check -> true
654+
| Check_opt_only, Check_opt_only -> true
655+
| (Check_default | Check_all | Check_opt_only | No_check), _ -> false
656+
657+
let of_string v =
658+
let f t =
659+
if String.equal (to_string t) v then Some t else None
660+
in
661+
List.find_map f all
662+
663+
let doc =
664+
"\n\ The argument specifies which annotations to check: \n\
665+
\ \"opt\" means attributes with \"opt\" payload and is intended for debugging;\n\
666+
\ \"default\" means attributes without \"opt\" payload; \n\
667+
\ \"all\" covers both \"opt\" and \"default\" and is intended for optimized builds."
668+
end
669+
670+
let zero_alloc_check = ref Annotations.No_check (* -zero-alloc-check *)
639671
let zero_alloc_check_assert_all = ref false (* -zero-alloc-check-assert-all *)

utils/clflags.mli

+10-1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,15 @@ val print_arguments : string -> unit
286286
(* [reset_arguments ()] clear all declared arguments *)
287287
val reset_arguments : unit -> unit
288288

289-
val zero_alloc_check : bool ref
289+
(* [Annotations] specifies which zero_alloc attributes to check. *)
290+
module Annotations : sig
291+
type t = Check_default | Check_all | Check_opt_only | No_check
292+
val all : t list
293+
val to_string : t -> string
294+
val of_string : string -> t option
295+
val equal : t -> t -> bool
296+
val doc : string
297+
end
298+
val zero_alloc_check : Annotations.t ref
290299
val zero_alloc_check_assert_all : bool ref
291300

0 commit comments

Comments
 (0)