Skip to content

Commit

Permalink
- Added new option -dclosure to print clambda-code (lambda code after
Browse files Browse the repository at this point in the history
    closure conversion, inlining and constant propagation)
- Implementation of partial calls with known arity by eta-expansion
  • Loading branch information
lefessan committed Apr 10, 2011
1 parent aa24234 commit 1155528
Show file tree
Hide file tree
Showing 13 changed files with 297 additions and 31 deletions.
6 changes: 3 additions & 3 deletions examples/Makefile.included
Expand Up @@ -61,9 +61,9 @@ new_version:
# echo '-dlambda2' >> code_new.ml
# $(OCAMLOPT) -inline 100 $(OFLAGS) $(OPTIM) -dlambda2 -c code.ml 2> code.lambda2
# cat code.lambda2 >> code_new.ml
# echo '-dclosure' >> code_new.ml
# $(OCAMLOPT) -inline 100 $(OFLAGS) $(OPTIM) -dclosure -c code.ml 2> code.closure
# cat code.closure >> code_new.ml
echo '-dclosure' >> code_new.ml
$(OCAMLOPT) -inline 100 $(OFLAGS) $(OPTIM) -dclosure -c code.ml 2> code.closure
cat code.closure >> code_new.ml
# echo '-dclosure2' >> code_new.ml
# $(OCAMLOPT) -inline 100 $(OFLAGS) $(OPTIM) -dstats -dclosure2 -c code.ml 2> code.closure2
# cat code.closure2 >> code_new.ml
Expand Down
59 changes: 33 additions & 26 deletions inline-more/.depend
Expand Up @@ -65,8 +65,8 @@ parsing/syntaxerr.cmo: parsing/location.cmi parsing/syntaxerr.cmi
parsing/syntaxerr.cmx: parsing/location.cmx parsing/syntaxerr.cmi
typing/annot.cmi: parsing/location.cmi
typing/btype.cmi: typing/types.cmi typing/path.cmi parsing/asttypes.cmi
typing/ctype.cmi: typing/types.cmi typing/path.cmi typing/ident.cmi \
typing/env.cmi parsing/asttypes.cmi
typing/ctype.cmi: typing/types.cmi typing/path.cmi parsing/longident.cmi \
typing/ident.cmi typing/env.cmi parsing/asttypes.cmi
typing/datarepr.cmi: typing/types.cmi typing/path.cmi parsing/asttypes.cmi
typing/env.cmi: typing/types.cmi typing/path.cmi parsing/longident.cmi \
typing/ident.cmi utils/consistbl.cmi typing/annot.cmi
Expand Down Expand Up @@ -249,22 +249,22 @@ typing/typedtree.cmo: typing/types.cmi typing/primitive.cmi typing/path.cmi \
typing/typedtree.cmx: typing/types.cmx typing/primitive.cmx typing/path.cmx \
utils/misc.cmx parsing/location.cmx typing/ident.cmx typing/env.cmx \
parsing/asttypes.cmi typing/typedtree.cmi
typing/typemod.cmo: typing/typetexp.cmi typing/types.cmi typing/typedtree.cmi \
typing/typedecl.cmi typing/typecore.cmi typing/typeclass.cmi \
typing/subst.cmi typing/stypes.cmi typing/printtyp.cmi typing/path.cmi \
parsing/parsetree.cmi typing/mtype.cmi utils/misc.cmi \
parsing/longident.cmi parsing/location.cmi typing/includemod.cmi \
typing/ident.cmi typing/env.cmi typing/ctype.cmi utils/config.cmi \
utils/clflags.cmi typing/btype.cmi parsing/asttypes.cmi typing/annot.cmi \
typing/typemod.cmi
typing/typemod.cmx: typing/typetexp.cmx typing/types.cmx typing/typedtree.cmx \
typing/typedecl.cmx typing/typecore.cmx typing/typeclass.cmx \
typing/subst.cmx typing/stypes.cmx typing/printtyp.cmx typing/path.cmx \
parsing/parsetree.cmi typing/mtype.cmx utils/misc.cmx \
parsing/longident.cmx parsing/location.cmx typing/includemod.cmx \
typing/ident.cmx typing/env.cmx typing/ctype.cmx utils/config.cmx \
utils/clflags.cmx typing/btype.cmx parsing/asttypes.cmi typing/annot.cmi \
typing/typemod.cmi
typing/typemod.cmo: utils/warnings.cmi typing/typetexp.cmi typing/types.cmi \
typing/typedtree.cmi typing/typedecl.cmi typing/typecore.cmi \
typing/typeclass.cmi typing/subst.cmi typing/stypes.cmi \
typing/printtyp.cmi typing/path.cmi parsing/parsetree.cmi \
typing/mtype.cmi utils/misc.cmi parsing/longident.cmi \
parsing/location.cmi typing/includemod.cmi typing/ident.cmi \
typing/env.cmi typing/ctype.cmi utils/config.cmi utils/clflags.cmi \
typing/btype.cmi parsing/asttypes.cmi typing/annot.cmi typing/typemod.cmi
typing/typemod.cmx: utils/warnings.cmx typing/typetexp.cmx typing/types.cmx \
typing/typedtree.cmx typing/typedecl.cmx typing/typecore.cmx \
typing/typeclass.cmx typing/subst.cmx typing/stypes.cmx \
typing/printtyp.cmx typing/path.cmx parsing/parsetree.cmi \
typing/mtype.cmx utils/misc.cmx parsing/longident.cmx \
parsing/location.cmx typing/includemod.cmx typing/ident.cmx \
typing/env.cmx typing/ctype.cmx utils/config.cmx utils/clflags.cmx \
typing/btype.cmx parsing/asttypes.cmi typing/annot.cmi typing/typemod.cmi
typing/types.cmo: typing/primitive.cmi typing/path.cmi utils/misc.cmi \
typing/ident.cmi parsing/asttypes.cmi typing/types.cmi
typing/types.cmx: typing/primitive.cmx typing/path.cmx utils/misc.cmx \
Expand Down Expand Up @@ -486,8 +486,8 @@ asmcomp/cmx_format.cmi: asmcomp/clambda.cmi
asmcomp/codegen.cmi: asmcomp/cmm.cmi
asmcomp/coloring.cmi:
asmcomp/comballoc.cmi: asmcomp/mach.cmi
asmcomp/compilenv.cmi: typing/ident.cmi asmcomp/cmx_format.cmi \
asmcomp/clambda.cmi
asmcomp/compilenv.cmi: bytecomp/lambda.cmi typing/ident.cmi \
asmcomp/cmx_format.cmi asmcomp/clambda.cmi
asmcomp/debuginfo.cmi: parsing/location.cmi bytecomp/lambda.cmi
asmcomp/emit.cmi: asmcomp/linearize.cmi asmcomp/cmm.cmi
asmcomp/emitaux.cmi: asmcomp/debuginfo.cmi
Expand All @@ -496,6 +496,7 @@ asmcomp/linearize.cmi: asmcomp/reg.cmi asmcomp/mach.cmi asmcomp/debuginfo.cmi
asmcomp/liveness.cmi: asmcomp/mach.cmi
asmcomp/mach.cmi: asmcomp/reg.cmi asmcomp/debuginfo.cmi asmcomp/cmm.cmi \
asmcomp/arch.cmo
asmcomp/printclambda.cmi: asmcomp/clambda.cmi
asmcomp/printcmm.cmi: asmcomp/cmm.cmi
asmcomp/printlinear.cmi: asmcomp/linearize.cmi
asmcomp/printmach.cmi: asmcomp/reg.cmi asmcomp/mach.cmi
Expand Down Expand Up @@ -604,12 +605,12 @@ asmcomp/comballoc.cmo: asmcomp/reg.cmi asmcomp/mach.cmi utils/config.cmi \
asmcomp/comballoc.cmi
asmcomp/comballoc.cmx: asmcomp/reg.cmx asmcomp/mach.cmx utils/config.cmx \
asmcomp/comballoc.cmi
asmcomp/compilenv.cmo: utils/misc.cmi typing/ident.cmi typing/env.cmi \
utils/config.cmi asmcomp/cmx_format.cmi asmcomp/clambda.cmi \
asmcomp/compilenv.cmi
asmcomp/compilenv.cmx: utils/misc.cmx typing/ident.cmx typing/env.cmx \
utils/config.cmx asmcomp/cmx_format.cmi asmcomp/clambda.cmx \
asmcomp/compilenv.cmi
asmcomp/compilenv.cmo: utils/misc.cmi bytecomp/lambda.cmi typing/ident.cmi \
typing/env.cmi utils/config.cmi asmcomp/cmx_format.cmi \
asmcomp/clambda.cmi asmcomp/compilenv.cmi
asmcomp/compilenv.cmx: utils/misc.cmx bytecomp/lambda.cmx typing/ident.cmx \
typing/env.cmx utils/config.cmx asmcomp/cmx_format.cmi \
asmcomp/clambda.cmx asmcomp/compilenv.cmi
asmcomp/debuginfo.cmo: parsing/location.cmi bytecomp/lambda.cmi \
asmcomp/debuginfo.cmi
asmcomp/debuginfo.cmx: parsing/location.cmx bytecomp/lambda.cmx \
Expand Down Expand Up @@ -646,6 +647,12 @@ asmcomp/mach.cmo: asmcomp/reg.cmi asmcomp/debuginfo.cmi asmcomp/cmm.cmi \
asmcomp/arch.cmo asmcomp/mach.cmi
asmcomp/mach.cmx: asmcomp/reg.cmx asmcomp/debuginfo.cmx asmcomp/cmm.cmx \
asmcomp/arch.cmx asmcomp/mach.cmi
asmcomp/printclambda.cmo: bytecomp/printlambda.cmi bytecomp/lambda.cmi \
typing/ident.cmi asmcomp/clambda.cmi parsing/asttypes.cmi \
asmcomp/printclambda.cmi
asmcomp/printclambda.cmx: bytecomp/printlambda.cmx bytecomp/lambda.cmx \
typing/ident.cmx asmcomp/clambda.cmx parsing/asttypes.cmi \
asmcomp/printclambda.cmi
asmcomp/printcmm.cmo: typing/ident.cmi asmcomp/debuginfo.cmi asmcomp/cmm.cmi \
asmcomp/printcmm.cmi
asmcomp/printcmm.cmx: typing/ident.cmx asmcomp/debuginfo.cmx asmcomp/cmm.cmx \
Expand Down
3 changes: 2 additions & 1 deletion inline-more/Makefile
Expand Up @@ -71,7 +71,8 @@ BYTECOMP=bytecomp/meta.cmo bytecomp/instruct.cmo bytecomp/bytegen.cmo \
ASMCOMP=asmcomp/arch.cmo asmcomp/debuginfo.cmo \
asmcomp/cmm.cmo asmcomp/printcmm.cmo \
asmcomp/reg.cmo asmcomp/mach.cmo asmcomp/proc.cmo \
asmcomp/clambda.cmo asmcomp/compilenv.cmo \
asmcomp/clambda.cmo asmcomp/printclambda.cmo \
asmcomp/compilenv.cmo \
asmcomp/closure.cmo asmcomp/cmmgen.cmo \
asmcomp/printmach.cmo asmcomp/selectgen.cmo asmcomp/selection.cmo \
asmcomp/comballoc.cmo asmcomp/liveness.cmo \
Expand Down
5 changes: 4 additions & 1 deletion inline-more/asmcomp/asmgen.ml
Expand Up @@ -103,7 +103,10 @@ let compile_implementation ?toplevel prefixname ppf (size, lam) =
begin try
Emitaux.output_channel := oc;
Emit.begin_assembly();
Closure.intro size lam
let ulam = Closure.intro size lam in
Printclambda.print_ulambda_if ppf !dump_closure "After closure conversion"
ulam;
ulam
++ Cmmgen.compunit size
++ List.iter (compile_phrase ppf) ++ (fun () -> ());
(match toplevel with None -> () | Some f -> compile_genfuns ppf f);
Expand Down
27 changes: 27 additions & 0 deletions inline-more/asmcomp/closure.ml
Expand Up @@ -495,6 +495,9 @@ let rec close fenv cenv = function
end
| Lfunction(kind, params, body) as funct ->
close_one_function fenv cenv (Ident.create "fun") funct

(* we want to convert [f a] in [let a' = a in fun b c -> f a b c] when
fun_arity > nargs *)
| Lapply(funct, args, loc) ->
let nargs = List.length args in
begin match (close fenv cenv funct, close_list fenv cenv args) with
Expand All @@ -507,6 +510,30 @@ let rec close fenv cenv = function
when nargs = fundesc.fun_arity ->
let app = direct_apply fundesc funct ufunct uargs in
(app, strengthen_approx app approx_res)

| ((ufunct, Value_closure(fundesc, approx_res)), uargs)
when nargs < fundesc.fun_arity ->

let first_args = List.map (fun arg ->
(Ident.create "arg", arg) ) args in
let final_args = Array.to_list (Array.init (fundesc.fun_arity - nargs) (fun _ ->
Ident.create "arg")) in
let rec iter args body =
match args with
[] -> body
| (arg1, arg2) :: args ->
iter args
(Llet ( Strict, arg1, arg2, body))
in
let new_fun = iter first_args
(Lfunction(
Curried, final_args,
Lapply(funct, (List.map (fun (arg1, arg2) ->
Lvar arg1) first_args) @ (List.map (fun arg ->
Lvar arg ) final_args), loc)))
in
close fenv cenv new_fun

| ((ufunct, Value_closure(fundesc, approx_res)), uargs)
when fundesc.fun_arity > 0 && nargs > fundesc.fun_arity ->
let (first_args, rem_args) = split_list fundesc.fun_arity uargs in
Expand Down
188 changes: 188 additions & 0 deletions inline-more/asmcomp/printclambda.ml
@@ -0,0 +1,188 @@
(***********************************************************************)
(* *)
(* Objective Caml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* en Automatique. All rights reserved. This file is distributed *)
(* under the terms of the Q Public License version 1.0. *)
(* *)
(***********************************************************************)

(***********************************************************************)
(* *)
(* Contributed by OCamlPro *)
(* *)
(***********************************************************************)

(* $Id: clambda.ml 7812 2007-01-29 12:11:18Z xleroy $ *)

open Asttypes
open Lambda
open Clambda
open Format

let array_iter2 f a b =
let len_a = Array.length a in
(* let len_b = Array.length b in
if len_a <> len_b then begin
eprintf "len_a (%d) differs from len_b (%d)\n%!" len_a len_b;
assert false
end; *)
for i = 0 to len_a-1 do f i b.(a.(i)) done

let rec lam ppf l =
match l with
(* exactly the same ones as in printlambda.ml *)
| Uvar x -> fprintf ppf "%a" Ident.print x
| Uconst (cst,_) -> Printlambda.structured_constant ppf cst
| Usend (k, met, obj, largs, _) ->
let args ppf largs =
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in
let kind =
if k = Self then "self" else if k = Cached then "cache" else "" in
fprintf ppf "@[<2>(send%s@ %a@ %a%a)@]" kind lam obj lam met args largs
| Uassign(id, expr) ->
fprintf ppf "@[<2>(assign@ %a@ %a)@]" Ident.print id lam expr
| Ufor(param, lo, hi, dir, body) ->
fprintf ppf "@[<2>(for %a@ %a@ %s@ %a@ %a)@]"
Ident.print param lam lo
(match dir with Upto -> "to" | Downto -> "downto")
lam hi lam body
| Uifthenelse(lcond, lif, lelse) ->
fprintf ppf "@[<2>(if@ %a@ %a@ %a)@]" lam lcond lam lif lam lelse
| Usequence(l1, l2) ->
fprintf ppf "@[<2>(seq@ %a@ %a)@]" lam l1 sequence l2
| Uwhile(lcond, lbody) ->
fprintf ppf "@[<2>(while@ %a@ %a)@]" lam lcond lam lbody
| Uprim(prim, largs, _) ->
let lams ppf largs =
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in
fprintf ppf "@[<2>(%a%a)@]" Printlambda.primitive prim lams largs
| Utrywith(lbody, param, lhandler) ->
fprintf ppf "@[<2>(try@ %a@;<1 -1>with %a@ %a)@]"
lam lbody Ident.print param lam lhandler
| Uletrec(id_arg_list, body) ->
let bindings ppf id_arg_list =
let spc = ref false in
List.iter
(fun (id, l) ->
if !spc then fprintf ppf "@ " else spc := true;
fprintf ppf "@[<2>%a@ %a@]" Ident.print id lam l)
id_arg_list in
fprintf ppf
"@[<2>(letrec@ (@[<hv 1>%a@])@ %a)@]" bindings id_arg_list lam body

(* Lstaticraise *)
| Ustaticfail (i, ls) ->
let lams ppf largs =
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in
fprintf ppf "@[<2>(exit@ %d%a)@]" i lams ls

(* Lstaticcatch: Arguments have been reordered *)
| Ucatch(i, vars, lbody, lhandler) ->
fprintf ppf "@[<2>(catch@ %a@;<1 -1>with (%d%a)@ %a)@]"
lam lbody i
(fun ppf vars -> match vars with
| [] -> ()
| _ ->
List.iter
(fun x -> fprintf ppf " %a" Ident.print x)
vars)
vars
lam lhandler

(*
(* Strictness as disappeared *)
| Ulet(str, id, arg, body) ->
let rec letbody = function
| Ulet(str, id, arg, body) ->
fprintf ppf "@ @[<2>%a%s@ %a@]" Ident.print id (string_of_let_kind str) lam arg;
letbody body
| expr -> expr in
fprintf ppf "@[<2>(let@ @[<hv 1>(@[<2>%a%s@ %a@]" Ident.print id (string_of_let_kind str) lam arg;
let expr = letbody body in
fprintf ppf ")@]@ %a)@]" lam expr
*)
| Ulet(id, arg, body) ->
let rec letbody = function
| Ulet(id, arg, body) ->
fprintf ppf "@ @[<2>%a%s@ %a@]" Ident.print id "" (* (string_of_let_kind str) *) lam arg;
letbody body
| expr -> expr in
fprintf ppf "@[<2>(let@ @[<hv 1>(@[<2>%a%s@ %a@]" Ident.print id "" (* (string_of_let_kind str) *) lam arg;
let expr = letbody body in
fprintf ppf ")@]@ %a)@]" lam expr

(* failaction has been removed from switch *)
| Uswitch(larg, sw) ->
let switch ppf sw =
let spc = ref false in
array_iter2
(fun n l ->
if !spc then fprintf ppf "@ " else spc := true;
fprintf ppf "@[<hv 1>case int %i:@ %a@]" n lam l)
sw.us_index_consts sw.us_actions_consts;
array_iter2
(fun n l ->
if !spc then fprintf ppf "@ " else spc := true;
fprintf ppf "@[<hv 1>case tag %i:@ %a@]" n lam l)
sw.us_index_blocks sw.us_actions_blocks ;
in

fprintf ppf
"@[<1>(%s %a@ @[<v 0>%a@])@]"
"switch*"
lam larg switch sw

(* from Lapply *)
| Udirect_apply (function_label, largs, _) ->
let lams ppf largs =
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in
fprintf ppf "@[<2>(%s@ %a)@]" function_label lams largs
| Ugeneric_apply(lfun, largs, _) ->
let lams ppf largs =
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in
fprintf ppf "@[<2>(apply@ %a%a)@]" lam lfun lams largs

(* New: access to the closure *)
| Uoffset (l, pos) ->
fprintf ppf "@[<2>(offset[%d]@ %a)@]" pos lam l

| Uclosure (clos, (* env_pos, *) fvs) ->
let pr_params ppf params =
List.iter (fun param -> fprintf ppf "@ %a" Ident.print param) params
in
let closures ppf largs =
List.iter (fun (fun_label, fun_arity, fun_params, ubody) ->
fprintf ppf
"@[<2>(%s(%d%s) %a@ @[<v 0>%a@])@]"
fun_label fun_arity
"" (* (if clos.fun_closed then "" else "+c") *)
pr_params fun_params lam ubody


) largs in
let lams ppf largs =
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in
fprintf ppf
"@[<2>(closure @[<v 0>%a@] @[<v 0>{%d} %a@])@]"
closures clos 0 (* env_pos *) lams fvs


and sequence ppf = function
| Usequence(l1, l2) ->
fprintf ppf "%a@ %a" sequence l1 sequence l2
| l ->
lam ppf l

let print_ulambda ppf l =
fprintf ppf "%a@." lam l

let print_ulambda_if ppf cond msg l =
if cond then begin
fprintf ppf "*** %s:@.%a@." msg lam l;
end


26 changes: 26 additions & 0 deletions inline-more/asmcomp/printclambda.mli
@@ -0,0 +1,26 @@
(***********************************************************************)
(* *)
(* Objective Caml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* en Automatique. All rights reserved. This file is distributed *)
(* under the terms of the Q Public License version 1.0. *)
(* *)
(***********************************************************************)

(***********************************************************************)
(* *)
(* Contributed by OCamlPro *)
(* *)
(***********************************************************************)

(* $Id: clambda.mli 7812 2007-01-29 12:11:18Z xleroy $ *)

open Clambda

val print_ulambda_if : Format.formatter -> bool -> string -> ulambda -> unit
val print_ulambda : Format.formatter -> ulambda -> unit


1 change: 1 addition & 0 deletions inline-more/bytecomp/printlambda.mli
Expand Up @@ -18,3 +18,4 @@ open Format

val structured_constant: formatter -> structured_constant -> unit
val lambda: formatter -> lambda -> unit
val primitive : Format.formatter -> Lambda.primitive -> unit

0 comments on commit 1155528

Please sign in to comment.