diff options
author | Fabrice Le Fessant <Fabrice.Le_fessant@inria.fr> | 2012-04-18 08:50:26 +0000 |
---|---|---|
committer | Fabrice Le Fessant <Fabrice.Le_fessant@inria.fr> | 2012-04-18 08:50:26 +0000 |
commit | 905143bfa21672fef20e55ebe7a8233cd26881c5 (patch) | |
tree | 13eea7a06c6dcea2416011ad873e337380c19acf | |
parent | 3930c2fd79e43bd02e3bc79d6b047f3aeab0effe (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-- | Makefile | 31 | ||||
-rw-r--r-- | Makefile.nt | 32 | ||||
-rw-r--r-- | asmcomp/asmgen.ml | 29 | ||||
-rw-r--r-- | asmcomp/asmgen.mli | 12 | ||||
-rw-r--r-- | driver/optcompile.ml | 2 |
5 files changed, 85 insertions, 21 deletions
@@ -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; |