Skip to content

Save cfg to file #257

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 9 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions backend/asmgen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,41 @@ let start_from_emit = ref true
let should_save_before_emit () =
should_save_ir_after Compiler_pass.Scheduling && (not !start_from_emit)

let should_save_cfg_before_emit () =
should_save_ir_after Compiler_pass.Simplify_cfg && (not !start_from_emit)

let linear_unit_info =
{ Linear_format.unit_name = "";
items = [];
for_pack = None;
}

let cfg_unit_info =
{ Cfg_format.unit_name = "";
items = [];
for_pack = None;
}

let reset () =
start_from_emit := false;
if should_save_before_emit () then begin
linear_unit_info.unit_name <- Compilenv.current_unit_name ();
linear_unit_info.items <- [];
linear_unit_info.for_pack <- !Clflags.for_package;
end;
if should_save_cfg_before_emit () then begin
cfg_unit_info.unit_name <- Compilenv.current_unit_name ();
cfg_unit_info.items <- [];
cfg_unit_info.for_pack <- !Clflags.for_package;
end

let save_data dl =
if should_save_before_emit () then begin
linear_unit_info.items <- Linear_format.(Data dl) :: linear_unit_info.items
end;
if should_save_cfg_before_emit () then begin
cfg_unit_info.items <- Cfg_format.(Data dl) :: cfg_unit_info.items
end;
dl

let save_linear f =
Expand All @@ -77,11 +94,22 @@ let save_linear f =
end;
f

let write_linear prefix =
let save_cfg f =
if should_save_cfg_before_emit () then begin
cfg_unit_info.items <- Cfg_format.(Cfg f) :: cfg_unit_info.items
end;
f

let write_ir prefix =
if should_save_before_emit () then begin
let filename = Compiler_pass.(to_output_filename Scheduling ~prefix) in
linear_unit_info.items <- List.rev linear_unit_info.items;
Linear_format.save filename linear_unit_info
end;
if should_save_cfg_before_emit () then begin
let filename = Compiler_pass.(to_output_filename Simplify_cfg ~prefix) in
cfg_unit_info.items <- List.rev cfg_unit_info.items;
Cfg_format.save filename cfg_unit_info
end

let should_emit () =
Expand Down Expand Up @@ -184,6 +212,7 @@ let compile_fundecl ~ppf_dump fd_cmm =
++ Profile.record ~accumulate:true "linear_to_cfg"
(Linear_to_cfg.run ~preserve_orig_labels:true)
++ pass_dump_cfg_if ppf_dump dump_cfg "After linear_to_cfg"
++ save_cfg
++ Profile.record ~accumulate:true "cfg_to_linear" Cfg_to_linear.run
++ pass_dump_linear_if ppf_dump dump_linear "After cfg_to_linear"
end else
Expand Down Expand Up @@ -227,7 +256,7 @@ let compile_unit ~output_prefix ~asm_filename ~keep_asm ~obj_filename gen =
Misc.try_finally
(fun () ->
gen ();
write_linear output_prefix)
write_ir output_prefix)
~always:(fun () ->
if create_asm then close_out !Emitaux.output_channel)
~exceptionally:(fun () ->
Expand Down
3 changes: 2 additions & 1 deletion driver/optmaindriver.ml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ let main argv ppf ~flambda2_backend ~flambda2_to_cmm =
| None ->
Compenv.fatal "Please specify at most one of -pack, -a, -shared, -c, \
-output-obj";
| Some ((P.Parsing | P.Typing | P.Scheduling | P.Emit) as p) ->
| Some ((P.Parsing | P.Typing | P.Scheduling
| P.Simplify_cfg | P.Emit) as p) ->
assert (P.is_compilation_pass p);
Printf.ksprintf Compenv.fatal
"Options -i and -stop-after (%s) \
Expand Down
17 changes: 13 additions & 4 deletions dune
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

(copy_files# file_formats/linear_format.ml{,i})

(copy_files# file_formats/cfg_format.ml{,i})

(copy_files# middle_end/*.ml{,i})

(copy_files# middle_end/closure/*.ml{,i})
Expand Down Expand Up @@ -219,6 +221,7 @@
cfg_equivalence
;; file_formats/
linear_format
cfg_format
;; asmcomp/debug/
reg_availability_set
compute_ranges_intf
Expand Down Expand Up @@ -475,6 +478,7 @@
(x86_masm.mli as compiler-libs/x86_masm.mli)
(x86_proc.mli as compiler-libs/x86_proc.mli)
(linear_format.mli as compiler-libs/linear_format.mli)
(cfg_format.mli as compiler-libs/cfg_format.mli)
(reg_availability_set.mli as compiler-libs/reg_availability_set.mli)
(available_regs.mli as compiler-libs/available_regs.mli)
(reg_with_debug_info.mli as compiler-libs/reg_with_debug_info.mli)
Expand Down Expand Up @@ -513,9 +517,10 @@
(.ocamloptcomp.objs/byte/linear_format.cmti
as
compiler-libs/linear_format.cmti)
(.ocamloptcomp.objs/native/linear_format.cmx
as
compiler-libs/linear_format.cmx)
(.ocamloptcomp.objs/byte/cfg_format.cmi as compiler-libs/cfg_format.cmi)
(.ocamloptcomp.objs/byte/cfg_format.cmo as compiler-libs/cfg_format.cmo)
(.ocamloptcomp.objs/byte/cfg_format.cmt as compiler-libs/cfg_format.cmt)
(.ocamloptcomp.objs/byte/cfg_format.cmti as compiler-libs/cfg_format.cmti)
(.ocamloptcomp.objs/byte/afl_instrument.cmi
as
compiler-libs/afl_instrument.cmi)
Expand Down Expand Up @@ -2099,4 +2104,8 @@
(.ocamloptcomp.objs/native/var_within_closure.cmx
as
compiler-libs/var_within_closure.cmx)
(.ocamloptcomp.objs/native/variable.cmx as compiler-libs/variable.cmx)))
(.ocamloptcomp.objs/native/variable.cmx as compiler-libs/variable.cmx)
(.ocamloptcomp.objs/native/linear_format.cmx
as
compiler-libs/linear_format.cmx)
(.ocamloptcomp.objs/native/cfg_format.cmx as compiler-libs/cfg_format.cmx)))
101 changes: 101 additions & 0 deletions file_formats/cfg_format.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
(**************************************************************************)
(* *)
(* OCaml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* Greta Yorsh, Jane Street Europe *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* en Automatique. *)
(* Copyright 2019 Jane Street Group LLC *)
(* *)
(* All rights reserved. This file is distributed under the terms of *)
(* the GNU Lesser General Public License version 2.1, with the *)
(* special exception on linking described in the file LICENSE. *)
(* *)
(**************************************************************************)

(* Marshal and unmarshal a compilation unit in Cfg format *)
type cfg_item_info =
| Cfg of Cfg_with_layout.t
| Data of Cmm.data_item list

type cfg_unit_info =
{
mutable unit_name : string;
mutable items : cfg_item_info list;
mutable for_pack : string option
}

type error =
| Wrong_format of string
| Wrong_version of string
| Corrupted of string
| Marshal_failed of string

exception Error of error

let save filename cfg_unit_info =
let ch = open_out_bin filename in
Misc.try_finally (fun () ->
output_string ch Config.cfg_magic_number;
output_value ch cfg_unit_info;
(* Saved because Emit depends on Cmm.label. *)
output_value ch (Cmm.cur_label ());
(* Compute digest of the contents and append it to the file. *)
flush ch;
let crc = Digest.file filename in
Digest.output ch crc
)
~always:(fun () -> close_out ch)
~exceptionally:(fun () -> raise (Error (Marshal_failed filename)))

let restore filename =
let ic = open_in_bin filename in
Misc.try_finally
(fun () ->
let magic = Config.cfg_magic_number in
let buffer = really_input_string ic (String.length magic) in
if String.equal buffer magic then begin
try
let cfg_unit_info = (input_value ic : cfg_unit_info) in
let last_label = (input_value ic : Cmm.label) in
Cmm.reset ();
Cmm.set_label last_label;
let crc = Digest.input ic in
cfg_unit_info, crc
with End_of_file | Failure _ -> raise (Error (Corrupted filename))
| Error e -> raise (Error e)
end
else if String.sub buffer 0 9 = String.sub magic 0 9 then
raise (Error (Wrong_version filename))
else
raise (Error (Wrong_format filename))
)
~always:(fun () -> close_in ic)

(* Error report *)

open Format

let report_error ppf = function
| Wrong_format filename ->
fprintf ppf "Expected Cfg format. Incompatible file %a"
Location.print_filename filename
| Wrong_version filename ->
fprintf ppf
"%a@ is not compatible with this version of OCaml"
Location.print_filename filename
| Corrupted filename ->
fprintf ppf "Corrupted format@ %a"
Location.print_filename filename
| Marshal_failed filename ->
fprintf ppf "Failed to marshal Cfg to file@ %a"
Location.print_filename filename

let () =
Location.register_error_of_exn
(function
| Error err -> Some (Location.error_of_printer_file report_error err)
| _ -> None
)
38 changes: 38 additions & 0 deletions file_formats/cfg_format.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
(**************************************************************************)
(* *)
(* OCaml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* Greta Yorsh, Jane Street Europe *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* en Automatique. *)
(* Copyright 2019 Jane Street Group LLC *)
(* *)
(* All rights reserved. This file is distributed under the terms of *)
(* the GNU Lesser General Public License version 2.1, with the *)
(* special exception on linking described in the file LICENSE. *)
(* *)
(**************************************************************************)

(* Format of .cmir-cfg files *)

(* Compiler can optionally save Cfg representation of a compilation unit,
along with other information required to emit assembly. *)
type cfg_item_info =
| Cfg of Cfg_with_layout.t
| Data of Cmm.data_item list

type cfg_unit_info =
{
mutable unit_name : string;
mutable items : cfg_item_info list;
mutable for_pack : string option
}

(* Marshal and unmarshal a compilation unit in Cfg format.
It includes saving and restoring global state required for Emit,
that currently consists of Cmm.label_counter.
*)
val save : string -> cfg_unit_info -> unit
val restore : string -> cfg_unit_info * Digest.t
4 changes: 2 additions & 2 deletions file_formats/linear_format.ml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ let save filename linear_unit_info =
(* Compute digest of the contents and append it to the file. *)
flush ch;
let crc = Digest.file filename in
output_value ch crc
Digest.output ch crc
)
~always:(fun () -> close_out ch)
~exceptionally:(fun () -> raise (Error (Marshal_failed filename)))
Expand All @@ -62,7 +62,7 @@ let restore filename =
let last_label = (input_value ic : Cmm.label) in
Cmm.reset ();
Cmm.set_label last_label;
let crc = (input_value ic : Digest.t) in
let crc = Digest.input ic in
linear_unit_info, crc
with End_of_file | Failure _ -> raise (Error (Corrupted filename))
| Error e -> raise (Error e)
Expand Down
2 changes: 1 addition & 1 deletion ocaml/driver/maindriver.ml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ let main argv ppf =
are incompatible with -pack, -a, -output-obj"
(String.concat "|"
(P.available_pass_names ~filter:(fun _ -> true) ~native:false))
| Some (P.Scheduling | P.Emit) -> assert false (* native only *)
| Some (P.Scheduling | P.Simplify_cfg | P.Emit) -> assert false (* native only *)
end;
if !make_archive then begin
Compmisc.init_path ();
Expand Down
3 changes: 2 additions & 1 deletion ocaml/driver/optmaindriver.ml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ let main argv ppf =
| None ->
Compenv.fatal "Please specify at most one of -pack, -a, -shared, -c, \
-output-obj";
| Some ((P.Parsing | P.Typing | P.Scheduling | P.Emit) as p) ->
| Some ((P.Parsing | P.Typing | P.Scheduling
| P.Simplify_cfg | P.Emit) as p) ->
assert (P.is_compilation_pass p);
Printf.ksprintf Compenv.fatal
"Options -i and -stop-after (%s) \
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
wrong argument 'typing'; option '-save-ir-after' expects one of: scheduling.
wrong argument 'typing'; option '-save-ir-after' expects one of: scheduling simplify_cfg.
Loading