summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabrice Le Fessant <Fabrice.Le_fessant@inria.fr>2012-04-18 08:50:26 +0000
committerFabrice Le Fessant <Fabrice.Le_fessant@inria.fr>2012-04-18 08:50:26 +0000
commit905143bfa21672fef20e55ebe7a8233cd26881c5 (patch)
tree13eea7a06c6dcea2416011ad873e337380c19acf
parent3930c2fd79e43bd02e3bc79d6b047f3aeab0effe (diff)
Add hooks in Asmgen
Add hooks in Asmgen to allow external developers to add new passes on the typedtree, lambda, clambda and cmm trees. A library 'ocamlopt.cm{a/xa}' is installed, with optmain.cm{x/o}, so that developers can create new ocamlopt executables containing these new passes. git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@12370 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--Makefile31
-rw-r--r--Makefile.nt32
-rw-r--r--asmcomp/asmgen.ml29
-rw-r--r--asmcomp/asmgen.mli12
-rw-r--r--driver/optcompile.ml2
5 files changed, 85 insertions, 21 deletions
diff --git a/Makefile b/Makefile
index d7ec3b76c..01e2bb67e 100644
--- a/Makefile
+++ b/Makefile
@@ -89,8 +89,10 @@ ASMCOMP=asmcomp/arch.cmo asmcomp/debuginfo.cmo \
DRIVER=driver/pparse.cmo driver/errors.cmo driver/compile.cmo \
driver/main_args.cmo driver/main.cmo
-OPTDRIVER= driver/pparse.cmo driver/opterrors.cmo driver/optcompile.cmo \
- driver/main_args.cmo driver/optmain.cmo
+OPTEND= driver/pparse.cmo driver/opterrors.cmo driver/optcompile.cmo \
+ driver/main_args.cmo
+OPTMAIN= driver/optmain.cmo
+OPTDRIVER= $(OPTEND) $(OPTMAIN)
TOPLEVEL=driver/pparse.cmo driver/errors.cmo driver/compile.cmo \
driver/main_args.cmo toplevel/genprintval.cmo toplevel/toploop.cmo \
@@ -105,9 +107,8 @@ TOPLIB=$(UTILS) $(PARSING) $(TYPING) $(COMP) $(BYTECOMP) $(TOPLEVEL)
TOPOBJS=$(TOPLEVELLIB) $(TOPLEVELSTART)
-NATTOPOBJS=$(OPTUTILS) $(PARSING) $(TYPING) $(COMP) $(ASMCOMP) \
- driver/pparse.cmo driver/opterrors.cmo driver/optcompile.cmo \
- driver/main_args.cmo \
+OPTFILES=$(OPTUTILS) $(PARSING) $(TYPING) $(COMP) $(ASMCOMP) $(OPTEND)
+NATTOPOBJS= $(OPTFILES) \
toplevel/genprintval.cmo toplevel/opttoploop.cmo toplevel/opttopdirs.cmo \
toplevel/opttopmain.cmo toplevel/opttopstart.cmo
@@ -315,6 +316,7 @@ install:
installopt:
cd asmrun; $(MAKE) install
cp ocamlopt $(BINDIR)/ocamlopt$(EXE)
+ cp driver/ocamlopt.cma driver/optmain.cmo $(LIBDIR)/
cd stdlib; $(MAKE) installopt
cd ocamldoc; $(MAKE) installopt
for i in $(OTHERLIBRARIES); \
@@ -322,7 +324,11 @@ installopt:
if test -f ocamlc.opt; \
then cp ocamlc.opt $(BINDIR)/ocamlc.opt$(EXE); else :; fi
if test -f ocamlopt.opt; \
- then cp ocamlopt.opt $(BINDIR)/ocamlopt.opt$(EXE); else :; fi
+ then \
+ cp ocamlopt.opt $(BINDIR)/ocamlopt.opt$(EXE); \
+ cp driver/ocamlopt.$(A) driver/ocamlopt.cmxa \
+ driver/optmain.cmx driver/optmain.$(O) $(LIBDIR)/; \
+ else :; fi
if test -f lex/ocamllex.opt; \
then cp lex/ocamllex.opt $(BINDIR)/ocamllex.opt$(EXE); else :; fi
@@ -340,15 +346,17 @@ partialclean::
rm -f ocamlc ocamlcomp.sh
# The native-code compiler
+driver/ocamlopt.cma: $(OPTOBJS)
+ $(CAMLC) $(LINKFLAGS) -a -o driver/ocamlopt.cma $(OPTFILES)
-ocamlopt: $(OPTOBJS)
+ocamlopt: $(OPTOBJS) driver/ocamlopt.cma
$(CAMLC) $(LINKFLAGS) -o ocamlopt $(OPTOBJS)
@sed -e 's|@compiler@|$$topdir/boot/ocamlrun $$topdir/ocamlopt|' \
driver/ocamlcomp.sh.in > ocamlcompopt.sh
@chmod +x ocamlcompopt.sh
partialclean::
- rm -f ocamlopt ocamlcompopt.sh
+ rm -f ocamlopt ocamlcompopt.sh driver/ocamlopt.cma
# The toplevel
@@ -446,14 +454,17 @@ partialclean::
# The native-code compiler compiled with itself
-ocamlopt.opt: $(OPTOBJS:.cmo=.cmx)
+driver/ocamlopt.cmxa: $(OPTOBJS:.cmo=.cmx)
+ $(CAMLOPT) $(LINKFLAGS) -a -o driver/ocamlopt.cmxa $(OPTFILES:.cmo=.cmx)
+
+ocamlopt.opt: driver/ocamlopt.cmxa $(OPTOBJS:.cmo=.cmx)
$(CAMLOPT) $(LINKFLAGS) -o ocamlopt.opt $(OPTOBJS:.cmo=.cmx)
@sed -e 's|@compiler@|$$topdir/ocamlopt.opt|' \
driver/ocamlcomp.sh.in > ocamlcompopt.sh
@chmod +x ocamlcompopt.sh
partialclean::
- rm -f ocamlopt.opt
+ rm -f ocamlopt.opt driver/ocamlopt.cmxa driver/ocamlopt.$(A)
$(OPTOBJS:.cmo=.cmx): ocamlopt
diff --git a/Makefile.nt b/Makefile.nt
index 0b9e4e7c2..018956124 100644
--- a/Makefile.nt
+++ b/Makefile.nt
@@ -86,8 +86,10 @@ ASMCOMP=asmcomp/arch.cmo asmcomp/debuginfo.cmo \
DRIVER=driver/pparse.cmo driver/errors.cmo driver/compile.cmo \
driver/main_args.cmo driver/main.cmo
-OPTDRIVER=driver/pparse.cmo driver/opterrors.cmo driver/optcompile.cmo \
- driver/main_args.cmo driver/optmain.cmo
+OPTEND= driver/pparse.cmo driver/opterrors.cmo driver/optcompile.cmo \
+ driver/main_args.cmo
+OPTMAIN= driver/optmain.cmo
+OPTDRIVER= $(OPTEND) $(OPTMAIN)
TOPLEVEL=driver/pparse.cmo driver/errors.cmo driver/compile.cmo \
driver/main_args.cmo toplevel/genprintval.cmo toplevel/toploop.cmo \
@@ -102,9 +104,8 @@ TOPLIB=$(UTILS) $(PARSING) $(TYPING) $(COMP) $(BYTECOMP) $(TOPLEVEL)
TOPOBJS=$(TOPLEVELLIB) $(TOPLEVELSTART)
-NATTOPOBJS=$(OPTUTILS) $(PARSING) $(TYPING) $(COMP) $(ASMCOMP) \
- driver/pparse.cmo driver/opterrors.cmo driver/optcompile.cmo \
- driver/main_args.cmo \
+OPTFILES=$(OPTUTILS) $(PARSING) $(TYPING) $(COMP) $(ASMCOMP) $(OPTEND)
+NATTOPOBJS= $(OPTFILES) \
toplevel/genprintval.cmo toplevel/opttoploop.cmo toplevel/opttopdirs.cmo \
toplevel/opttopmain.cmo toplevel/opttopstart.cmo
@@ -125,7 +126,7 @@ defaultentry:
# Recompile the system using the bootstrap compiler
all: runtime ocamlc ocamllex ocamlyacc ocamltools library ocaml \
- otherlibraries ocamldoc.byte ocamlbuild.byte $(CAMLP4OUT) $(DEBUGGER)
+ otherlibraries ocamldoc.byte ocamlbuild.byte $(CAMLP4OUT) $(DEBUGGER)
# The compilation of ocaml will fail if the runtime has changed.
# Never mind, just do make bootstrap to reach fixpoint again.
@@ -254,13 +255,18 @@ installbyt:
installopt:
cd asmrun ; $(MAKEREC) install
cp ocamlopt $(BINDIR)/ocamlopt.exe
+ cp driver/ocamlopt.cma driver/optmain.cmo $(LIBDIR)/
cd stdlib ; $(MAKEREC) installopt
cd ocamldoc ; $(MAKEREC) installopt
for i in $(OTHERLIBRARIES); do $(MAKEREC) -C otherlibs/$$i installopt; done
if test -f ocamlc.opt; \
then cp ocamlc.opt $(BINDIR)/ocamlc.opt.exe; else :; fi
if test -f ocamlopt.opt; \
- then cp ocamlopt.opt $(BINDIR)/ocamlopt.opt.exe; else :; fi
+ then \
+ cp ocamlopt.opt $(BINDIR)/ocamlopt.opt.exe; \
+ cp driver/ocamlopt.$(A) driver/ocamlopt.cmxa \
+ driver/optmain.cmx driver/optmain.$(O) $(LIBDIR)/; \
+ else :; fi
if test -f lex/ocamllex.opt; \
then cp lex/ocamllex.opt $(BINDIR)/ocamllex.opt.exe; else :; fi
@@ -278,15 +284,17 @@ partialclean::
rm -f ocamlc
# The native-code compiler
+driver/ocamlopt.cma: $(OPTOBJS)
+ $(CAMLC) $(LINKFLAGS) -a -o driver/ocamlopt.cma $(OPTFILES)
-ocamlopt: $(OPTOBJS)
+ocamlopt: $(OPTOBJS) driver/ocamlopt.cma
$(CAMLC) $(LINKFLAGS) -o ocamlopt $(OPTOBJS)
@sed -e 's|@compiler@|$$topdir/boot/ocamlrun $$topdir/ocamlopt|' \
driver/ocamlcomp.sh.in > ocamlcompopt.sh
@chmod +x ocamlcompopt.sh
partialclean::
- rm -f ocamlopt
+ rm -f ocamlopt driver/ocamlopt.cma
# The toplevel
@@ -384,15 +392,17 @@ partialclean::
rm -f ocamlc.opt
# The native-code compiler compiled with itself
+driver/ocamlopt.cmxa: $(OPTOBJS:.cmo=.cmx)
+ $(CAMLOPT) $(LINKFLAGS) -a -o driver/ocamlopt.cmxa $(OPTFILES:.cmo=.cmx)
-ocamlopt.opt: $(OPTOBJS:.cmo=.cmx)
+ocamlopt.opt: driver/ocamlopt.cmxa $(OPTOBJS:.cmo=.cmx)
$(CAMLOPT) $(LINKFLAGS) -o ocamlopt.opt $(OPTOBJS:.cmo=.cmx)
@sed -e 's|@compiler@|$$topdir/ocamlopt.opt|' \
driver/ocamlcomp.sh.in > ocamlcompopt.sh
@chmod +x ocamlcompopt.sh
partialclean::
- rm -f ocamlopt.opt
+ rm -f ocamlopt.opt driver/ocamlopt.cmxa driver/ocamlopt.$(A)
$(OPTOBJS:.cmo=.cmx): ocamlopt
diff --git a/asmcomp/asmgen.ml b/asmcomp/asmgen.ml
index 5f513db1b..fbe97f1d3 100644
--- a/asmcomp/asmgen.ml
+++ b/asmcomp/asmgen.ml
@@ -20,6 +20,32 @@ open Clflags
open Misc
open Cmm
+(* hooks *)
+
+let eval_hooks hooks x =
+ List.fold_left (fun x hook -> hook x) x hooks
+let add_hook ref hook = ref := hook :: !ref
+
+type 'a hook = ('a -> 'a)
+
+let typedtree_hooks = ref []
+let lambda_hooks = ref []
+let clambda_hooks = ref []
+let cmm_hooks = ref []
+
+let add_typedtree_hook = add_hook typedtree_hooks
+let add_lambda_hook = add_hook lambda_hooks
+let add_clambda_hook = add_hook clambda_hooks
+let add_cmm_hook = add_hook cmm_hooks
+
+let eval_typedtree_hooks = eval_hooks !typedtree_hooks
+let eval_lambda_hooks = eval_hooks !lambda_hooks
+let eval_clambda_hooks = eval_hooks !clambda_hooks
+let eval_cmm_hooks = eval_hooks !cmm_hooks
+
+(* asm generation *)
+
+
type error = Assembler_error of string
exception Error of error
@@ -58,6 +84,7 @@ let (++) x f = f x
let compile_fundecl (ppf : formatter) fd_cmm =
Reg.reset();
fd_cmm
+ ++ eval_hooks !cmm_hooks
++ Selection.fundecl
++ pass_dump_if ppf dump_selection "After instruction selection"
++ Comballoc.fundecl
@@ -104,6 +131,7 @@ let compile_implementation ?toplevel prefixname ppf (size, lam) =
Emitaux.output_channel := oc;
Emit.begin_assembly();
Closure.intro size lam
+ ++ eval_hooks !clambda_hooks
++ Cmmgen.compunit size
++ List.iter (compile_phrase ppf) ++ (fun () -> ());
(match toplevel with None -> () | Some f -> compile_genfuns ppf f);
@@ -137,3 +165,4 @@ let report_error ppf = function
| Assembler_error file ->
fprintf ppf "Assembler error, input left in file %a"
Location.print_filename file
+
diff --git a/asmcomp/asmgen.mli b/asmcomp/asmgen.mli
index f71cba8f7..cc249a9e9 100644
--- a/asmcomp/asmgen.mli
+++ b/asmcomp/asmgen.mli
@@ -23,3 +23,15 @@ val compile_phrase :
type error = Assembler_error of string
exception Error of error
val report_error: Format.formatter -> error -> unit
+
+type 'a hook = ('a -> 'a)
+
+val add_typedtree_hook :
+ (Typedtree.structure * Typedtree.module_coercion) hook -> unit
+val add_lambda_hook : (int * Lambda.lambda) hook -> unit
+val add_clambda_hook : Clambda.ulambda hook -> unit
+val add_cmm_hook : Cmm.fundecl hook -> unit
+
+val eval_typedtree_hooks :
+ (Typedtree.structure * Typedtree.module_coercion) hook
+val eval_lambda_hooks : (int * Lambda.lambda) hook
diff --git a/driver/optcompile.ml b/driver/optcompile.ml
index 1e6ab0ce3..f330f0779 100644
--- a/driver/optcompile.ml
+++ b/driver/optcompile.ml
@@ -124,10 +124,12 @@ let implementation ppf sourcefile outputprefix =
Pparse.file ppf inputfile Parse.implementation ast_impl_magic_number
++ print_if ppf Clflags.dump_parsetree Printast.implementation
++ Typemod.type_implementation sourcefile outputprefix modulename env
+ ++ Asmgen.eval_typedtree_hooks
++ Translmod.transl_store_implementation modulename
+++ print_if ppf Clflags.dump_rawlambda Printlambda.lambda
+++ Simplif.simplify_lambda
+++ print_if ppf Clflags.dump_lambda Printlambda.lambda
+ ++ Asmgen.eval_lambda_hooks
++ Asmgen.compile_implementation outputprefix ppf;
Compilenv.save_unit_info cmxfile;
end;