Initial import of linear-scan-register-allocator
The code in this commit was written by Marcell Fischbach & Benedikt Meurer. See [Mantis#5324](http://caml.inria.fr/mantis/view.php?id=5324) for some context. The code (which was originally written against 3.12) was ported to trunk by doing ```bash git clone https://github.com/bmeurer/ocaml-experimental/ cd ocaml-experimental git diff master...linear-scan-register-allocator > t.diff ``` and then applying the diff by hand.master
parent
4f46291fa3
commit
e75c87dc48
169
.depend
169
.depend
|
@ -233,13 +233,13 @@ typing/includemod.cmo : typing/types.cmi typing/typedtree.cmi utils/tbl.cmi \
|
|||
typing/mtype.cmi utils/misc.cmi parsing/location.cmi \
|
||||
typing/includecore.cmi typing/includeclass.cmi typing/ident.cmi \
|
||||
typing/env.cmi typing/ctype.cmi typing/cmt_format.cmi utils/clflags.cmi \
|
||||
typing/includemod.cmi
|
||||
typing/btype.cmi typing/includemod.cmi
|
||||
typing/includemod.cmx : typing/types.cmx typing/typedtree.cmx utils/tbl.cmx \
|
||||
typing/subst.cmx typing/printtyp.cmx typing/primitive.cmx typing/path.cmx \
|
||||
typing/mtype.cmx utils/misc.cmx parsing/location.cmx \
|
||||
typing/includecore.cmx typing/includeclass.cmx typing/ident.cmx \
|
||||
typing/env.cmx typing/ctype.cmx typing/cmt_format.cmx utils/clflags.cmx \
|
||||
typing/includemod.cmi
|
||||
typing/btype.cmx typing/includemod.cmi
|
||||
typing/includemod.cmi : typing/types.cmi typing/typedtree.cmi \
|
||||
typing/path.cmi parsing/location.cmi typing/includecore.cmi \
|
||||
typing/ident.cmi typing/env.cmi typing/ctype.cmi
|
||||
|
@ -600,6 +600,11 @@ bytecomp/printlambda.cmi : bytecomp/lambda.cmi
|
|||
bytecomp/runtimedef.cmo : bytecomp/runtimedef.cmi
|
||||
bytecomp/runtimedef.cmx : bytecomp/runtimedef.cmi
|
||||
bytecomp/runtimedef.cmi :
|
||||
bytecomp/semantics_of_primitives.cmo : bytecomp/lambda.cmi \
|
||||
bytecomp/semantics_of_primitives.cmi
|
||||
bytecomp/semantics_of_primitives.cmx : bytecomp/lambda.cmx \
|
||||
bytecomp/semantics_of_primitives.cmi
|
||||
bytecomp/semantics_of_primitives.cmi : bytecomp/lambda.cmi
|
||||
bytecomp/simplif.cmo : utils/warnings.cmi utils/tbl.cmi typing/stypes.cmi \
|
||||
utils/misc.cmi parsing/location.cmi bytecomp/lambda.cmi typing/ident.cmi \
|
||||
utils/clflags.cmi parsing/asttypes.cmi typing/annot.cmi \
|
||||
|
@ -706,21 +711,22 @@ asmcomp/CSEgen.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/mach.cmx \
|
|||
asmcomp/CSEgen.cmi : asmcomp/mach.cmi
|
||||
asmcomp/afl_instrument.cmo : bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/debuginfo.cmi asmcomp/cmm.cmi utils/clflags.cmi \
|
||||
asmcomp/afl_instrument.cmi
|
||||
parsing/asttypes.cmi asmcomp/afl_instrument.cmi
|
||||
asmcomp/afl_instrument.cmx : bytecomp/lambda.cmx typing/ident.cmx \
|
||||
middle_end/debuginfo.cmx asmcomp/cmm.cmx utils/clflags.cmx \
|
||||
asmcomp/afl_instrument.cmi
|
||||
parsing/asttypes.cmi asmcomp/afl_instrument.cmi
|
||||
asmcomp/afl_instrument.cmi : asmcomp/cmm.cmi
|
||||
asmcomp/arch.cmo : utils/clflags.cmi
|
||||
asmcomp/arch.cmx : utils/clflags.cmx
|
||||
asmcomp/arch.cmo : utils/config.cmi utils/clflags.cmi
|
||||
asmcomp/arch.cmx : utils/config.cmx utils/clflags.cmx
|
||||
asmcomp/asmgen.cmo : asmcomp/un_anf.cmi bytecomp/translmod.cmi \
|
||||
utils/timings.cmi middle_end/base_types/symbol.cmi asmcomp/split.cmi \
|
||||
asmcomp/spill.cmi asmcomp/selection.cmi asmcomp/scheduling.cmi \
|
||||
asmcomp/reload.cmi asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/printmach.cmi \
|
||||
asmcomp/printlinear.cmi asmcomp/printcmm.cmi asmcomp/printclambda.cmi \
|
||||
typing/primitive.cmi utils/misc.cmi asmcomp/mach.cmi parsing/location.cmi \
|
||||
asmcomp/liveness.cmi middle_end/base_types/linkage_name.cmi \
|
||||
asmcomp/linearize.cmi bytecomp/lambda.cmi asmcomp/interf.cmi \
|
||||
asmcomp/liveness.cmi asmcomp/linscan.cmi \
|
||||
middle_end/base_types/linkage_name.cmi asmcomp/linearize.cmi \
|
||||
bytecomp/lambda.cmi asmcomp/interval.cmi asmcomp/interf.cmi \
|
||||
typing/ident.cmi asmcomp/flambda_to_clambda.cmi middle_end/flambda.cmi \
|
||||
asmcomp/emitaux.cmi asmcomp/emit.cmi asmcomp/deadcode.cmi \
|
||||
utils/config.cmi asmcomp/compilenv.cmi asmcomp/comballoc.cmi \
|
||||
|
@ -733,8 +739,9 @@ asmcomp/asmgen.cmx : asmcomp/un_anf.cmx bytecomp/translmod.cmx \
|
|||
asmcomp/reload.cmx asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/printmach.cmx \
|
||||
asmcomp/printlinear.cmx asmcomp/printcmm.cmx asmcomp/printclambda.cmx \
|
||||
typing/primitive.cmx utils/misc.cmx asmcomp/mach.cmx parsing/location.cmx \
|
||||
asmcomp/liveness.cmx middle_end/base_types/linkage_name.cmx \
|
||||
asmcomp/linearize.cmx bytecomp/lambda.cmx asmcomp/interf.cmx \
|
||||
asmcomp/liveness.cmx asmcomp/linscan.cmx \
|
||||
middle_end/base_types/linkage_name.cmx asmcomp/linearize.cmx \
|
||||
bytecomp/lambda.cmx asmcomp/interval.cmx asmcomp/interf.cmx \
|
||||
typing/ident.cmx asmcomp/flambda_to_clambda.cmx middle_end/flambda.cmx \
|
||||
asmcomp/emitaux.cmx asmcomp/emit.cmx asmcomp/deadcode.cmx \
|
||||
utils/config.cmx asmcomp/compilenv.cmx asmcomp/comballoc.cmx \
|
||||
|
@ -821,14 +828,16 @@ asmcomp/clambda.cmx : bytecomp/lambda.cmx typing/ident.cmx \
|
|||
asmcomp/clambda.cmi : bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/debuginfo.cmi parsing/asttypes.cmi
|
||||
asmcomp/closure.cmo : utils/warnings.cmi utils/tbl.cmi bytecomp/switch.cmi \
|
||||
bytecomp/simplif.cmi typing/primitive.cmi utils/misc.cmi \
|
||||
parsing/location.cmi bytecomp/lambda.cmi typing/ident.cmi typing/env.cmi \
|
||||
bytecomp/simplif.cmi bytecomp/semantics_of_primitives.cmi \
|
||||
typing/primitive.cmi utils/misc.cmi parsing/location.cmi \
|
||||
bytecomp/lambda.cmi typing/ident.cmi typing/env.cmi \
|
||||
middle_end/debuginfo.cmi utils/config.cmi asmcomp/compilenv.cmi \
|
||||
utils/clflags.cmi asmcomp/clambda.cmi parsing/asttypes.cmi \
|
||||
asmcomp/arch.cmo asmcomp/closure.cmi
|
||||
asmcomp/closure.cmx : utils/warnings.cmx utils/tbl.cmx bytecomp/switch.cmx \
|
||||
bytecomp/simplif.cmx typing/primitive.cmx utils/misc.cmx \
|
||||
parsing/location.cmx bytecomp/lambda.cmx typing/ident.cmx typing/env.cmx \
|
||||
bytecomp/simplif.cmx bytecomp/semantics_of_primitives.cmx \
|
||||
typing/primitive.cmx utils/misc.cmx parsing/location.cmx \
|
||||
bytecomp/lambda.cmx typing/ident.cmx typing/env.cmx \
|
||||
middle_end/debuginfo.cmx utils/config.cmx asmcomp/compilenv.cmx \
|
||||
utils/clflags.cmx asmcomp/clambda.cmx parsing/asttypes.cmi \
|
||||
asmcomp/arch.cmx asmcomp/closure.cmi
|
||||
|
@ -846,11 +855,13 @@ asmcomp/closure_offsets.cmx : middle_end/base_types/variable.cmx \
|
|||
asmcomp/closure_offsets.cmi : middle_end/base_types/var_within_closure.cmi \
|
||||
middle_end/flambda.cmi middle_end/base_types/closure_id.cmi
|
||||
asmcomp/cmm.cmo : bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/debuginfo.cmi asmcomp/arch.cmo asmcomp/cmm.cmi
|
||||
middle_end/debuginfo.cmi parsing/asttypes.cmi asmcomp/arch.cmo \
|
||||
asmcomp/cmm.cmi
|
||||
asmcomp/cmm.cmx : bytecomp/lambda.cmx typing/ident.cmx \
|
||||
middle_end/debuginfo.cmx asmcomp/arch.cmx asmcomp/cmm.cmi
|
||||
middle_end/debuginfo.cmx parsing/asttypes.cmi asmcomp/arch.cmx \
|
||||
asmcomp/cmm.cmi
|
||||
asmcomp/cmm.cmi : bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/debuginfo.cmi
|
||||
middle_end/debuginfo.cmi parsing/asttypes.cmi
|
||||
asmcomp/cmmgen.cmo : asmcomp/un_anf.cmi typing/types.cmi bytecomp/switch.cmi \
|
||||
asmcomp/strmatch.cmi asmcomp/proc.cmi bytecomp/printlambda.cmi \
|
||||
typing/primitive.cmi utils/misc.cmi bytecomp/lambda.cmi typing/ident.cmi \
|
||||
|
@ -882,16 +893,16 @@ asmcomp/compilenv.cmo : utils/warnings.cmi middle_end/base_types/symbol.cmi \
|
|||
typing/ident.cmi middle_end/flambda.cmi asmcomp/export_info.cmi \
|
||||
typing/env.cmi utils/config.cmi \
|
||||
middle_end/base_types/compilation_unit.cmi asmcomp/cmx_format.cmi \
|
||||
middle_end/base_types/closure_id.cmi asmcomp/clambda.cmi \
|
||||
asmcomp/compilenv.cmi
|
||||
middle_end/base_types/closure_id.cmi utils/clflags.cmi \
|
||||
asmcomp/clambda.cmi asmcomp/compilenv.cmi
|
||||
asmcomp/compilenv.cmx : utils/warnings.cmx middle_end/base_types/symbol.cmx \
|
||||
middle_end/base_types/set_of_closures_id.cmx utils/misc.cmx \
|
||||
parsing/location.cmx middle_end/base_types/linkage_name.cmx \
|
||||
typing/ident.cmx middle_end/flambda.cmx asmcomp/export_info.cmx \
|
||||
typing/env.cmx utils/config.cmx \
|
||||
middle_end/base_types/compilation_unit.cmx asmcomp/cmx_format.cmi \
|
||||
middle_end/base_types/closure_id.cmx asmcomp/clambda.cmx \
|
||||
asmcomp/compilenv.cmi
|
||||
middle_end/base_types/closure_id.cmx utils/clflags.cmx \
|
||||
asmcomp/clambda.cmx asmcomp/compilenv.cmi
|
||||
asmcomp/compilenv.cmi : utils/timings.cmi middle_end/base_types/symbol.cmi \
|
||||
middle_end/base_types/set_of_closures_id.cmi \
|
||||
middle_end/base_types/linkage_name.cmi typing/ident.cmi \
|
||||
|
@ -948,6 +959,7 @@ asmcomp/export_info.cmi : middle_end/base_types/variable.cmi \
|
|||
asmcomp/export_info_for_pack.cmo : middle_end/base_types/variable.cmi \
|
||||
middle_end/base_types/var_within_closure.cmi \
|
||||
middle_end/base_types/symbol.cmi \
|
||||
middle_end/base_types/set_of_closures_origin.cmi \
|
||||
middle_end/base_types/set_of_closures_id.cmi utils/misc.cmi \
|
||||
middle_end/flambda_utils.cmi middle_end/flambda_iterators.cmi \
|
||||
middle_end/flambda.cmi asmcomp/export_info.cmi \
|
||||
|
@ -957,6 +969,7 @@ asmcomp/export_info_for_pack.cmo : middle_end/base_types/variable.cmi \
|
|||
asmcomp/export_info_for_pack.cmx : middle_end/base_types/variable.cmx \
|
||||
middle_end/base_types/var_within_closure.cmx \
|
||||
middle_end/base_types/symbol.cmx \
|
||||
middle_end/base_types/set_of_closures_origin.cmx \
|
||||
middle_end/base_types/set_of_closures_id.cmx utils/misc.cmx \
|
||||
middle_end/flambda_utils.cmx middle_end/flambda_iterators.cmx \
|
||||
middle_end/flambda.cmx asmcomp/export_info.cmx \
|
||||
|
@ -1014,6 +1027,11 @@ asmcomp/interf.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/mach.cmi \
|
|||
asmcomp/interf.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/mach.cmx \
|
||||
asmcomp/cmm.cmx asmcomp/interf.cmi
|
||||
asmcomp/interf.cmi : asmcomp/mach.cmi
|
||||
asmcomp/interval.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/mach.cmi \
|
||||
asmcomp/interval.cmi
|
||||
asmcomp/interval.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/mach.cmx \
|
||||
asmcomp/interval.cmi
|
||||
asmcomp/interval.cmi : asmcomp/reg.cmi asmcomp/mach.cmi
|
||||
asmcomp/linearize.cmo : asmcomp/reg.cmi asmcomp/proc.cmi utils/misc.cmi \
|
||||
asmcomp/mach.cmi middle_end/debuginfo.cmi utils/config.cmi \
|
||||
asmcomp/cmm.cmi asmcomp/linearize.cmi
|
||||
|
@ -1022,6 +1040,11 @@ asmcomp/linearize.cmx : asmcomp/reg.cmx asmcomp/proc.cmx utils/misc.cmx \
|
|||
asmcomp/cmm.cmx asmcomp/linearize.cmi
|
||||
asmcomp/linearize.cmi : asmcomp/reg.cmi asmcomp/mach.cmi \
|
||||
middle_end/debuginfo.cmi asmcomp/cmm.cmi
|
||||
asmcomp/linscan.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/interval.cmi \
|
||||
asmcomp/linscan.cmi
|
||||
asmcomp/linscan.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/interval.cmx \
|
||||
asmcomp/linscan.cmi
|
||||
asmcomp/linscan.cmi :
|
||||
asmcomp/liveness.cmo : asmcomp/reg.cmi asmcomp/proc.cmi \
|
||||
asmcomp/printmach.cmi utils/misc.cmi asmcomp/mach.cmi utils/config.cmi \
|
||||
asmcomp/cmm.cmi asmcomp/liveness.cmi
|
||||
|
@ -1043,9 +1066,11 @@ asmcomp/printclambda.cmx : bytecomp/printlambda.cmx bytecomp/lambda.cmx \
|
|||
asmcomp/printclambda.cmi
|
||||
asmcomp/printclambda.cmi : asmcomp/clambda.cmi
|
||||
asmcomp/printcmm.cmo : bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/debuginfo.cmi asmcomp/cmm.cmi asmcomp/printcmm.cmi
|
||||
middle_end/debuginfo.cmi asmcomp/cmm.cmi parsing/asttypes.cmi \
|
||||
asmcomp/printcmm.cmi
|
||||
asmcomp/printcmm.cmx : bytecomp/lambda.cmx typing/ident.cmx \
|
||||
middle_end/debuginfo.cmx asmcomp/cmm.cmx asmcomp/printcmm.cmi
|
||||
middle_end/debuginfo.cmx asmcomp/cmm.cmx parsing/asttypes.cmi \
|
||||
asmcomp/printcmm.cmi
|
||||
asmcomp/printcmm.cmi : middle_end/debuginfo.cmi asmcomp/cmm.cmi
|
||||
asmcomp/printlinear.cmo : asmcomp/printmach.cmi asmcomp/printcmm.cmi \
|
||||
asmcomp/mach.cmi asmcomp/linearize.cmi middle_end/debuginfo.cmi \
|
||||
|
@ -1055,11 +1080,13 @@ asmcomp/printlinear.cmx : asmcomp/printmach.cmx asmcomp/printcmm.cmx \
|
|||
asmcomp/printlinear.cmi
|
||||
asmcomp/printlinear.cmi : asmcomp/linearize.cmi
|
||||
asmcomp/printmach.cmo : asmcomp/reg.cmi asmcomp/proc.cmi \
|
||||
asmcomp/printcmm.cmi asmcomp/mach.cmi middle_end/debuginfo.cmi \
|
||||
utils/config.cmi asmcomp/cmm.cmi asmcomp/arch.cmo asmcomp/printmach.cmi
|
||||
asmcomp/printcmm.cmi asmcomp/mach.cmi asmcomp/interval.cmi \
|
||||
middle_end/debuginfo.cmi utils/config.cmi asmcomp/cmm.cmi \
|
||||
asmcomp/arch.cmo asmcomp/printmach.cmi
|
||||
asmcomp/printmach.cmx : asmcomp/reg.cmx asmcomp/proc.cmx \
|
||||
asmcomp/printcmm.cmx asmcomp/mach.cmx middle_end/debuginfo.cmx \
|
||||
utils/config.cmx asmcomp/cmm.cmx asmcomp/arch.cmx asmcomp/printmach.cmi
|
||||
asmcomp/printcmm.cmx asmcomp/mach.cmx asmcomp/interval.cmx \
|
||||
middle_end/debuginfo.cmx utils/config.cmx asmcomp/cmm.cmx \
|
||||
asmcomp/arch.cmx asmcomp/printmach.cmi
|
||||
asmcomp/printmach.cmi : asmcomp/reg.cmi asmcomp/mach.cmi
|
||||
asmcomp/proc.cmo : asmcomp/x86_proc.cmi asmcomp/reg.cmi utils/misc.cmi \
|
||||
asmcomp/mach.cmi utils/config.cmi asmcomp/cmm.cmi asmcomp/arch.cmo \
|
||||
|
@ -1072,9 +1099,9 @@ asmcomp/reg.cmo : typing/ident.cmi asmcomp/cmm.cmi asmcomp/reg.cmi
|
|||
asmcomp/reg.cmx : typing/ident.cmx asmcomp/cmm.cmx asmcomp/reg.cmi
|
||||
asmcomp/reg.cmi : typing/ident.cmi asmcomp/cmm.cmi
|
||||
asmcomp/reload.cmo : asmcomp/reloadgen.cmi asmcomp/reg.cmi asmcomp/mach.cmi \
|
||||
asmcomp/cmm.cmi utils/clflags.cmi asmcomp/reload.cmi
|
||||
asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo asmcomp/reload.cmi
|
||||
asmcomp/reload.cmx : asmcomp/reloadgen.cmx asmcomp/reg.cmx asmcomp/mach.cmx \
|
||||
asmcomp/cmm.cmx utils/clflags.cmx asmcomp/reload.cmi
|
||||
asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx asmcomp/reload.cmi
|
||||
asmcomp/reload.cmi : asmcomp/mach.cmi
|
||||
asmcomp/reloadgen.cmo : asmcomp/reg.cmi utils/misc.cmi asmcomp/mach.cmi \
|
||||
asmcomp/reloadgen.cmi
|
||||
|
@ -1094,33 +1121,35 @@ asmcomp/scheduling.cmi : asmcomp/linearize.cmi
|
|||
asmcomp/selectgen.cmo : utils/tbl.cmi bytecomp/simplif.cmi asmcomp/reg.cmi \
|
||||
asmcomp/proc.cmi utils/misc.cmi asmcomp/mach.cmi bytecomp/lambda.cmi \
|
||||
typing/ident.cmi middle_end/debuginfo.cmi utils/config.cmi \
|
||||
asmcomp/cmm.cmi asmcomp/arch.cmo asmcomp/selectgen.cmi
|
||||
asmcomp/cmm.cmi parsing/asttypes.cmi asmcomp/arch.cmo \
|
||||
asmcomp/selectgen.cmi
|
||||
asmcomp/selectgen.cmx : utils/tbl.cmx bytecomp/simplif.cmx asmcomp/reg.cmx \
|
||||
asmcomp/proc.cmx utils/misc.cmx asmcomp/mach.cmx bytecomp/lambda.cmx \
|
||||
typing/ident.cmx middle_end/debuginfo.cmx utils/config.cmx \
|
||||
asmcomp/cmm.cmx asmcomp/arch.cmx asmcomp/selectgen.cmi
|
||||
asmcomp/cmm.cmx parsing/asttypes.cmi asmcomp/arch.cmx \
|
||||
asmcomp/selectgen.cmi
|
||||
asmcomp/selectgen.cmi : asmcomp/reg.cmi asmcomp/mach.cmi typing/ident.cmi \
|
||||
middle_end/debuginfo.cmi asmcomp/cmm.cmi asmcomp/arch.cmo
|
||||
asmcomp/selection.cmo : asmcomp/spacetime_profiling.cmi asmcomp/proc.cmi \
|
||||
asmcomp/mach.cmi utils/config.cmi asmcomp/cmm.cmi utils/clflags.cmi \
|
||||
asmcomp/arch.cmo asmcomp/selection.cmi
|
||||
asmcomp/selection.cmx : asmcomp/spacetime_profiling.cmx asmcomp/proc.cmx \
|
||||
asmcomp/mach.cmx utils/config.cmx asmcomp/cmm.cmx utils/clflags.cmx \
|
||||
asmcomp/arch.cmx asmcomp/selection.cmi
|
||||
asmcomp/selection.cmo : asmcomp/spacetime_profiling.cmi \
|
||||
asmcomp/selectgen.cmi asmcomp/proc.cmi asmcomp/mach.cmi utils/config.cmi \
|
||||
asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo asmcomp/selection.cmi
|
||||
asmcomp/selection.cmx : asmcomp/spacetime_profiling.cmx \
|
||||
asmcomp/selectgen.cmx asmcomp/proc.cmx asmcomp/mach.cmx utils/config.cmx \
|
||||
asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx asmcomp/selection.cmi
|
||||
asmcomp/selection.cmi : asmcomp/mach.cmi asmcomp/cmm.cmi
|
||||
asmcomp/spacetime_profiling.cmo : asmcomp/selectgen.cmi asmcomp/proc.cmi \
|
||||
utils/misc.cmi asmcomp/mach.cmi bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/debuginfo.cmi utils/config.cmi asmcomp/cmm.cmi \
|
||||
asmcomp/arch.cmo asmcomp/spacetime_profiling.cmi
|
||||
parsing/asttypes.cmi asmcomp/arch.cmo asmcomp/spacetime_profiling.cmi
|
||||
asmcomp/spacetime_profiling.cmx : asmcomp/selectgen.cmx asmcomp/proc.cmx \
|
||||
utils/misc.cmx asmcomp/mach.cmx bytecomp/lambda.cmx typing/ident.cmx \
|
||||
middle_end/debuginfo.cmx utils/config.cmx asmcomp/cmm.cmx \
|
||||
asmcomp/arch.cmx asmcomp/spacetime_profiling.cmi
|
||||
parsing/asttypes.cmi asmcomp/arch.cmx asmcomp/spacetime_profiling.cmi
|
||||
asmcomp/spacetime_profiling.cmi : asmcomp/selectgen.cmi
|
||||
asmcomp/spill.cmo : asmcomp/reg.cmi asmcomp/proc.cmi utils/misc.cmi \
|
||||
asmcomp/mach.cmi asmcomp/cmm.cmi asmcomp/spill.cmi
|
||||
asmcomp/mach.cmi asmcomp/cmm.cmi utils/clflags.cmi asmcomp/spill.cmi
|
||||
asmcomp/spill.cmx : asmcomp/reg.cmx asmcomp/proc.cmx utils/misc.cmx \
|
||||
asmcomp/mach.cmx asmcomp/cmm.cmx asmcomp/spill.cmi
|
||||
asmcomp/mach.cmx asmcomp/cmm.cmx utils/clflags.cmx asmcomp/spill.cmi
|
||||
asmcomp/spill.cmi : asmcomp/mach.cmi
|
||||
asmcomp/split.cmo : asmcomp/reg.cmi utils/misc.cmi asmcomp/mach.cmi \
|
||||
asmcomp/split.cmi
|
||||
|
@ -1128,11 +1157,11 @@ asmcomp/split.cmx : asmcomp/reg.cmx utils/misc.cmx asmcomp/mach.cmx \
|
|||
asmcomp/split.cmi
|
||||
asmcomp/split.cmi : asmcomp/mach.cmi
|
||||
asmcomp/strmatch.cmo : bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/debuginfo.cmi asmcomp/cmm.cmi asmcomp/arch.cmo \
|
||||
asmcomp/strmatch.cmi
|
||||
middle_end/debuginfo.cmi asmcomp/cmm.cmi parsing/asttypes.cmi \
|
||||
asmcomp/arch.cmo asmcomp/strmatch.cmi
|
||||
asmcomp/strmatch.cmx : bytecomp/lambda.cmx typing/ident.cmx \
|
||||
middle_end/debuginfo.cmx asmcomp/cmm.cmx asmcomp/arch.cmx \
|
||||
asmcomp/strmatch.cmi
|
||||
middle_end/debuginfo.cmx asmcomp/cmm.cmx parsing/asttypes.cmi \
|
||||
asmcomp/arch.cmx asmcomp/strmatch.cmi
|
||||
asmcomp/strmatch.cmi : middle_end/debuginfo.cmi asmcomp/cmm.cmi
|
||||
asmcomp/un_anf.cmo : bytecomp/semantics_of_primitives.cmi \
|
||||
asmcomp/printclambda.cmi utils/misc.cmi bytecomp/lambda.cmi \
|
||||
|
@ -1206,12 +1235,12 @@ middle_end/backend_intf.cmi : middle_end/base_types/symbol.cmi \
|
|||
middle_end/closure_conversion.cmo : middle_end/base_types/variable.cmi \
|
||||
middle_end/base_types/tag.cmi middle_end/base_types/symbol.cmi \
|
||||
middle_end/base_types/static_exception.cmi bytecomp/simplif.cmi \
|
||||
bytecomp/printlambda.cmi typing/primitive.cmi typing/predef.cmi \
|
||||
utils/numbers.cmi middle_end/base_types/mutable_variable.cmi \
|
||||
utils/misc.cmi parsing/location.cmi \
|
||||
middle_end/base_types/linkage_name.cmi middle_end/lift_code.cmi \
|
||||
bytecomp/lambda.cmi typing/ident.cmi middle_end/flambda_utils.cmi \
|
||||
middle_end/flambda.cmi middle_end/debuginfo.cmi utils/config.cmi \
|
||||
bytecomp/printlambda.cmi typing/predef.cmi utils/numbers.cmi \
|
||||
middle_end/base_types/mutable_variable.cmi utils/misc.cmi \
|
||||
parsing/location.cmi middle_end/base_types/linkage_name.cmi \
|
||||
middle_end/lift_code.cmi bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/flambda_utils.cmi middle_end/flambda.cmi \
|
||||
middle_end/debuginfo.cmi utils/config.cmi \
|
||||
middle_end/base_types/compilation_unit.cmi \
|
||||
middle_end/base_types/closure_id.cmi \
|
||||
middle_end/closure_conversion_aux.cmi utils/clflags.cmi \
|
||||
|
@ -1219,12 +1248,12 @@ middle_end/closure_conversion.cmo : middle_end/base_types/variable.cmi \
|
|||
middle_end/closure_conversion.cmx : middle_end/base_types/variable.cmx \
|
||||
middle_end/base_types/tag.cmx middle_end/base_types/symbol.cmx \
|
||||
middle_end/base_types/static_exception.cmx bytecomp/simplif.cmx \
|
||||
bytecomp/printlambda.cmx typing/primitive.cmx typing/predef.cmx \
|
||||
utils/numbers.cmx middle_end/base_types/mutable_variable.cmx \
|
||||
utils/misc.cmx parsing/location.cmx \
|
||||
middle_end/base_types/linkage_name.cmx middle_end/lift_code.cmx \
|
||||
bytecomp/lambda.cmx typing/ident.cmx middle_end/flambda_utils.cmx \
|
||||
middle_end/flambda.cmx middle_end/debuginfo.cmx utils/config.cmx \
|
||||
bytecomp/printlambda.cmx typing/predef.cmx utils/numbers.cmx \
|
||||
middle_end/base_types/mutable_variable.cmx utils/misc.cmx \
|
||||
parsing/location.cmx middle_end/base_types/linkage_name.cmx \
|
||||
middle_end/lift_code.cmx bytecomp/lambda.cmx typing/ident.cmx \
|
||||
middle_end/flambda_utils.cmx middle_end/flambda.cmx \
|
||||
middle_end/debuginfo.cmx utils/config.cmx \
|
||||
middle_end/base_types/compilation_unit.cmx \
|
||||
middle_end/base_types/closure_id.cmx \
|
||||
middle_end/closure_conversion_aux.cmx utils/clflags.cmx \
|
||||
|
@ -1233,15 +1262,15 @@ middle_end/closure_conversion.cmi : bytecomp/lambda.cmi typing/ident.cmi \
|
|||
middle_end/flambda.cmi middle_end/backend_intf.cmi
|
||||
middle_end/closure_conversion_aux.cmo : middle_end/base_types/variable.cmi \
|
||||
middle_end/base_types/symbol.cmi \
|
||||
middle_end/base_types/static_exception.cmi typing/primitive.cmi \
|
||||
utils/numbers.cmi middle_end/base_types/mutable_variable.cmi \
|
||||
utils/misc.cmi parsing/location.cmi bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/base_types/static_exception.cmi utils/numbers.cmi \
|
||||
middle_end/base_types/mutable_variable.cmi utils/misc.cmi \
|
||||
parsing/location.cmi bytecomp/lambda.cmi typing/ident.cmi \
|
||||
middle_end/closure_conversion_aux.cmi
|
||||
middle_end/closure_conversion_aux.cmx : middle_end/base_types/variable.cmx \
|
||||
middle_end/base_types/symbol.cmx \
|
||||
middle_end/base_types/static_exception.cmx typing/primitive.cmx \
|
||||
utils/numbers.cmx middle_end/base_types/mutable_variable.cmx \
|
||||
utils/misc.cmx parsing/location.cmx bytecomp/lambda.cmx typing/ident.cmx \
|
||||
middle_end/base_types/static_exception.cmx utils/numbers.cmx \
|
||||
middle_end/base_types/mutable_variable.cmx utils/misc.cmx \
|
||||
parsing/location.cmx bytecomp/lambda.cmx typing/ident.cmx \
|
||||
middle_end/closure_conversion_aux.cmi
|
||||
middle_end/closure_conversion_aux.cmi : middle_end/base_types/variable.cmi \
|
||||
middle_end/base_types/symbol.cmi \
|
||||
|
@ -1733,11 +1762,6 @@ middle_end/remove_unused_program_constructs.cmx : \
|
|||
middle_end/effect_analysis.cmx \
|
||||
middle_end/remove_unused_program_constructs.cmi
|
||||
middle_end/remove_unused_program_constructs.cmi : middle_end/flambda.cmi
|
||||
bytecomp/semantics_of_primitives.cmo : bytecomp/printlambda.cmi \
|
||||
utils/misc.cmi bytecomp/lambda.cmi bytecomp/semantics_of_primitives.cmi
|
||||
bytecomp/semantics_of_primitives.cmx : bytecomp/printlambda.cmx \
|
||||
utils/misc.cmx bytecomp/lambda.cmx bytecomp/semantics_of_primitives.cmi
|
||||
bytecomp/semantics_of_primitives.cmi : bytecomp/lambda.cmi
|
||||
middle_end/share_constants.cmo : middle_end/base_types/symbol.cmi \
|
||||
middle_end/flambda_iterators.cmi middle_end/flambda.cmi \
|
||||
middle_end/share_constants.cmi
|
||||
|
@ -1748,7 +1772,8 @@ middle_end/share_constants.cmi : middle_end/flambda.cmi
|
|||
middle_end/simple_value_approx.cmo : middle_end/base_types/variable.cmi \
|
||||
middle_end/base_types/var_within_closure.cmi \
|
||||
middle_end/base_types/tag.cmi middle_end/base_types/symbol.cmi \
|
||||
utils/misc.cmi bytecomp/lambda.cmi middle_end/inlining_cost.cmi \
|
||||
middle_end/base_types/set_of_closures_id.cmi utils/misc.cmi \
|
||||
bytecomp/lambda.cmi middle_end/inlining_cost.cmi \
|
||||
middle_end/freshening.cmi middle_end/flambda_utils.cmi \
|
||||
middle_end/flambda.cmi middle_end/base_types/export_id.cmi \
|
||||
middle_end/effect_analysis.cmi middle_end/base_types/closure_id.cmi \
|
||||
|
@ -1756,7 +1781,8 @@ middle_end/simple_value_approx.cmo : middle_end/base_types/variable.cmi \
|
|||
middle_end/simple_value_approx.cmx : middle_end/base_types/variable.cmx \
|
||||
middle_end/base_types/var_within_closure.cmx \
|
||||
middle_end/base_types/tag.cmx middle_end/base_types/symbol.cmx \
|
||||
utils/misc.cmx bytecomp/lambda.cmx middle_end/inlining_cost.cmx \
|
||||
middle_end/base_types/set_of_closures_id.cmx utils/misc.cmx \
|
||||
bytecomp/lambda.cmx middle_end/inlining_cost.cmx \
|
||||
middle_end/freshening.cmx middle_end/flambda_utils.cmx \
|
||||
middle_end/flambda.cmx middle_end/base_types/export_id.cmx \
|
||||
middle_end/effect_analysis.cmx middle_end/base_types/closure_id.cmx \
|
||||
|
@ -1764,7 +1790,8 @@ middle_end/simple_value_approx.cmx : middle_end/base_types/variable.cmx \
|
|||
middle_end/simple_value_approx.cmi : middle_end/base_types/variable.cmi \
|
||||
middle_end/base_types/var_within_closure.cmi \
|
||||
middle_end/base_types/tag.cmi middle_end/base_types/symbol.cmi \
|
||||
bytecomp/lambda.cmi middle_end/freshening.cmi middle_end/flambda.cmi \
|
||||
middle_end/base_types/set_of_closures_id.cmi bytecomp/lambda.cmi \
|
||||
middle_end/freshening.cmi middle_end/flambda.cmi \
|
||||
middle_end/base_types/export_id.cmi middle_end/base_types/closure_id.cmi
|
||||
middle_end/simplify_boxed_integer_ops.cmo : middle_end/simplify_common.cmi \
|
||||
middle_end/simplify_boxed_integer_ops_intf.cmi \
|
||||
|
|
8
Changes
8
Changes
|
@ -33,6 +33,14 @@ Next version (4.05.0):
|
|||
and "0 mod <expr>" in the case when <expr> was a non-constant
|
||||
evaluating to zero (Mark Shinwell)
|
||||
|
||||
- GPR#375: An alternative Linear Scan register allocator for ocamlopt,
|
||||
activated with the -linscan command-line flag. This allocator represents
|
||||
a trade-off between worse generated code performance for higher
|
||||
compilation speed (especially interesting in some cases graph coloring
|
||||
is necessarily quadratic).
|
||||
(Marcell Fischbach and Benedikt Meurer, adapted by Nicolas Ojeda Bar,
|
||||
review by Nicolas Ojeda Bar and Alain Frisch)
|
||||
|
||||
### Runtime system:
|
||||
|
||||
- PR#7423, GPR#946: expose new exception-raising functions
|
||||
|
|
2
Makefile
2
Makefile
|
@ -168,6 +168,7 @@ ASMCOMP=\
|
|||
asmcomp/un_anf.cmo \
|
||||
asmcomp/afl_instrument.cmo \
|
||||
asmcomp/strmatch.cmo asmcomp/cmmgen.cmo \
|
||||
asmcomp/interval.cmo \
|
||||
asmcomp/printmach.cmo asmcomp/selectgen.cmo \
|
||||
asmcomp/spacetime_profiling.cmo asmcomp/selection.cmo \
|
||||
asmcomp/comballoc.cmo \
|
||||
|
@ -175,6 +176,7 @@ ASMCOMP=\
|
|||
asmcomp/liveness.cmo \
|
||||
asmcomp/spill.cmo asmcomp/split.cmo \
|
||||
asmcomp/interf.cmo asmcomp/coloring.cmo \
|
||||
asmcomp/linscan.cmo \
|
||||
asmcomp/reloadgen.cmo asmcomp/reload.cmo \
|
||||
asmcomp/deadcode.cmo \
|
||||
asmcomp/printlinear.cmo asmcomp/linearize.cmo \
|
||||
|
|
|
@ -80,10 +80,18 @@ let rec regalloc ppf round fd =
|
|||
fatal_error(fd.Mach.fun_name ^
|
||||
": function too complex, cannot complete register allocation");
|
||||
dump_if ppf dump_live "Liveness analysis" fd;
|
||||
if !use_linscan then begin
|
||||
(* Linear Scan *)
|
||||
Interval.build_intervals fd;
|
||||
if !dump_interval then Printmach.intervals ppf ();
|
||||
Linscan.allocate_registers()
|
||||
end else begin
|
||||
(* Graph Coloring *)
|
||||
Interf.build_graph fd;
|
||||
if !dump_interf then Printmach.interferences ppf ();
|
||||
if !dump_prefer then Printmach.preferences ppf ();
|
||||
Coloring.allocate_registers();
|
||||
Coloring.allocate_registers()
|
||||
end;
|
||||
dump_if ppf dump_regalloc "After register allocation" fd;
|
||||
let (newfd, redo_regalloc) = Reload.fundecl fd in
|
||||
dump_if ppf dump_reload "After insertion of reloading code" newfd;
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
(***********************************************************************)
|
||||
(* *)
|
||||
(* Objective Caml *)
|
||||
(* *)
|
||||
(* Marcell Fischbach, University of Siegen *)
|
||||
(* Benedikt Meurer, University of Siegen *)
|
||||
(* *)
|
||||
(* Copyright 2011 Lehrstuhl für Compilerbau und Softwareanalyse, *)
|
||||
(* Universität Siegen. All rights reserved. This file is distri- *)
|
||||
(* buted under the terms of the Q Public License version 1.0. *)
|
||||
(* *)
|
||||
(***********************************************************************)
|
||||
|
||||
(* $Id$ *)
|
||||
|
||||
(* Live intervals for the linear scan register allocator. *)
|
||||
|
||||
open Mach
|
||||
open Reg
|
||||
|
||||
type range =
|
||||
{
|
||||
mutable rbegin: int;
|
||||
mutable rend: int;
|
||||
}
|
||||
|
||||
type t =
|
||||
{
|
||||
mutable reg: Reg.t;
|
||||
mutable ibegin: int;
|
||||
mutable iend: int;
|
||||
mutable ranges: range list;
|
||||
}
|
||||
|
||||
type kind =
|
||||
Result
|
||||
| Argument
|
||||
| Live
|
||||
|
||||
let interval_list = ref ([] : t list)
|
||||
let fixed_interval_list = ref ([] : t list)
|
||||
let all_intervals() = !interval_list
|
||||
let all_fixed_intervals() = !fixed_interval_list
|
||||
|
||||
(* Check if two intervals overlap *)
|
||||
|
||||
let overlap i0 i1 =
|
||||
let rec overlap_ranges rl0 rl1 =
|
||||
match rl0, rl1 with
|
||||
r0 :: rl0', r1 :: rl1' ->
|
||||
if r0.rend >= r1.rbegin && r1.rend >= r0.rbegin then true
|
||||
else if r0.rend < r1.rend then overlap_ranges rl0' rl1
|
||||
else if r0.rend > r1.rend then overlap_ranges rl0 rl1'
|
||||
else overlap_ranges rl0' rl1'
|
||||
| _ -> false in
|
||||
overlap_ranges i0.ranges i1.ranges
|
||||
|
||||
let is_live i pos =
|
||||
let rec is_live_in_ranges = function
|
||||
[] -> false
|
||||
| r :: rl -> if pos < r.rbegin then false
|
||||
else if pos <= r.rend then true
|
||||
else is_live_in_ranges rl in
|
||||
is_live_in_ranges i.ranges
|
||||
|
||||
let remove_expired_ranges i pos =
|
||||
let rec filter = function
|
||||
[] -> []
|
||||
| r :: rl' as rl -> if pos < r.rend then rl
|
||||
else filter rl' in
|
||||
i.ranges <- filter i.ranges
|
||||
|
||||
let update_interval_position intervals pos kind reg =
|
||||
let i = intervals.(reg.stamp) in
|
||||
let on = pos lsl 1 in
|
||||
let off = on + 1 in
|
||||
let rbegin = (match kind with Result -> off | _ -> on) in
|
||||
let rend = (match kind with Argument -> on | _ -> off) in
|
||||
if i.iend = 0 then begin
|
||||
i.ibegin <- rbegin;
|
||||
i.reg <- reg;
|
||||
i.ranges <- [{rbegin = rbegin; rend = rend}]
|
||||
end else begin
|
||||
let r = List.hd i.ranges in
|
||||
let ridx = r.rend asr 1 in
|
||||
if pos - ridx <= 1 then
|
||||
r.rend <- rend
|
||||
else
|
||||
i.ranges <- {rbegin = rbegin; rend = rend} :: i.ranges
|
||||
end;
|
||||
i.iend <- rend
|
||||
|
||||
let update_interval_position_by_array intervals regs pos kind =
|
||||
Array.iter (update_interval_position intervals pos kind) regs
|
||||
|
||||
let update_interval_position_by_set intervals regs pos kind =
|
||||
Set.iter (update_interval_position intervals pos kind) regs
|
||||
|
||||
let update_interval_position_by_instr intervals instr pos =
|
||||
update_interval_position_by_array intervals instr.arg pos Argument;
|
||||
update_interval_position_by_array intervals instr.res pos Result;
|
||||
update_interval_position_by_set intervals instr.live pos Live
|
||||
|
||||
let insert_destroyed_at_oper intervals instr pos =
|
||||
let destroyed = Proc.destroyed_at_oper instr.desc in
|
||||
if Array.length destroyed > 0 then
|
||||
update_interval_position_by_array intervals destroyed pos Result
|
||||
|
||||
let insert_destroyed_at_raise intervals pos =
|
||||
let destroyed = Proc.destroyed_at_raise in
|
||||
if Array.length destroyed > 0 then
|
||||
update_interval_position_by_array intervals destroyed pos Result
|
||||
|
||||
(* Build all intervals.
|
||||
The intervals will be expanded by one step at the start and end
|
||||
of a basic block. *)
|
||||
|
||||
let build_intervals fd =
|
||||
let intervals = Array.init
|
||||
(Reg.num_registers())
|
||||
(fun _ -> {
|
||||
reg = Reg.dummy;
|
||||
ibegin = 0;
|
||||
iend = 0;
|
||||
ranges = []; }) in
|
||||
let pos = ref 0 in
|
||||
let rec walk_instruction i =
|
||||
incr pos;
|
||||
update_interval_position_by_instr intervals i !pos;
|
||||
begin match i.desc with
|
||||
Iend -> ()
|
||||
| Iop(Icall_ind _ | Icall_imm _ | Iextcall{alloc = true; _}
|
||||
| Itailcall_ind _ | Itailcall_imm _) ->
|
||||
walk_instruction i.next
|
||||
| Iop _ ->
|
||||
insert_destroyed_at_oper intervals i !pos;
|
||||
walk_instruction i.next
|
||||
| Ireturn ->
|
||||
insert_destroyed_at_oper intervals i !pos;
|
||||
walk_instruction i.next
|
||||
| Iifthenelse(_, ifso, ifnot) ->
|
||||
insert_destroyed_at_oper intervals i !pos;
|
||||
walk_instruction ifso;
|
||||
walk_instruction ifnot;
|
||||
walk_instruction i.next
|
||||
| Iswitch(_, cases) ->
|
||||
insert_destroyed_at_oper intervals i !pos;
|
||||
Array.iter walk_instruction cases;
|
||||
walk_instruction i.next
|
||||
| Iloop body ->
|
||||
insert_destroyed_at_oper intervals i !pos;
|
||||
walk_instruction body;
|
||||
walk_instruction i.next
|
||||
| Icatch(_, body, handler) ->
|
||||
insert_destroyed_at_oper intervals i !pos;
|
||||
List.iter (fun (_, i) -> walk_instruction i) body;
|
||||
walk_instruction handler;
|
||||
walk_instruction i.next
|
||||
| Iexit _ ->
|
||||
insert_destroyed_at_oper intervals i !pos;
|
||||
walk_instruction i.next
|
||||
| Itrywith(body, handler) ->
|
||||
insert_destroyed_at_oper intervals i !pos;
|
||||
walk_instruction body;
|
||||
insert_destroyed_at_raise intervals !pos;
|
||||
walk_instruction handler;
|
||||
walk_instruction i.next
|
||||
| Iraise _ ->
|
||||
walk_instruction i.next
|
||||
end in
|
||||
walk_instruction fd.fun_body;
|
||||
(* Generate the interval and fixed interval lists *)
|
||||
interval_list := [];
|
||||
fixed_interval_list := [];
|
||||
Array.iter
|
||||
(fun i ->
|
||||
if i.iend != 0 then begin
|
||||
i.ranges <- List.rev i.ranges;
|
||||
begin match i.reg.loc with
|
||||
Reg _ ->
|
||||
fixed_interval_list := i :: !fixed_interval_list
|
||||
| _ ->
|
||||
interval_list := i :: !interval_list
|
||||
end
|
||||
end)
|
||||
intervals;
|
||||
(* Sort the intervals according to their start position *)
|
||||
interval_list := List.sort (fun i0 i1 -> i0.ibegin - i1.ibegin) !interval_list
|
|
@ -0,0 +1,37 @@
|
|||
(***********************************************************************)
|
||||
(* *)
|
||||
(* Objective Caml *)
|
||||
(* *)
|
||||
(* Marcell Fischbach, University of Siegen *)
|
||||
(* Benedikt Meurer, University of Siegen *)
|
||||
(* *)
|
||||
(* Copyright 2011 Lehrstuhl für Compilerbau und Softwareanalyse, *)
|
||||
(* Universität Siegen. All rights reserved. This file is distri- *)
|
||||
(* buted under the terms of the Q Public License version 1.0. *)
|
||||
(* *)
|
||||
(***********************************************************************)
|
||||
|
||||
(* $Id$ *)
|
||||
|
||||
(* Live intervals for the linear scan register allocator. *)
|
||||
|
||||
type range =
|
||||
{
|
||||
mutable rbegin: int;
|
||||
mutable rend: int;
|
||||
}
|
||||
|
||||
type t =
|
||||
{
|
||||
mutable reg: Reg.t;
|
||||
mutable ibegin: int;
|
||||
mutable iend: int;
|
||||
mutable ranges: range list;
|
||||
}
|
||||
|
||||
val all_intervals: unit -> t list
|
||||
val all_fixed_intervals: unit -> t list
|
||||
val overlap: t -> t -> bool
|
||||
val is_live: t -> int -> bool
|
||||
val remove_expired_ranges: t -> int -> unit
|
||||
val build_intervals: Mach.fundecl -> unit
|
|
@ -0,0 +1,190 @@
|
|||
(***********************************************************************)
|
||||
(* *)
|
||||
(* Objective Caml *)
|
||||
(* *)
|
||||
(* Marcell Fischbach, University of Siegen *)
|
||||
(* Benedikt Meurer, University of Siegen *)
|
||||
(* *)
|
||||
(* Copyright 2011 Lehrstuhl für Compilerbau und Softwareanalyse, *)
|
||||
(* Universität Siegen. All rights reserved. This file is distri- *)
|
||||
(* buted under the terms of the Q Public License version 1.0. *)
|
||||
(* *)
|
||||
(***********************************************************************)
|
||||
|
||||
(* $Id$ *)
|
||||
|
||||
(* Linear scan register allocation. *)
|
||||
|
||||
open Interval
|
||||
open Reg
|
||||
|
||||
(* Live intervals per register class *)
|
||||
|
||||
type class_intervals =
|
||||
{
|
||||
mutable ci_fixed: Interval.t list;
|
||||
mutable ci_active: Interval.t list;
|
||||
mutable ci_inactive: Interval.t list;
|
||||
}
|
||||
|
||||
let active = Array.init Proc.num_register_classes (fun _ -> {
|
||||
ci_fixed = [];
|
||||
ci_active = [];
|
||||
ci_inactive = []
|
||||
})
|
||||
|
||||
(* Insert interval into list sorted by end position *)
|
||||
|
||||
let rec insert_interval_sorted i = function
|
||||
[] -> [i]
|
||||
| j :: _ as il when j.iend <= i.iend -> i :: il
|
||||
| j :: il -> j :: insert_interval_sorted i il
|
||||
|
||||
let rec release_expired_fixed pos = function
|
||||
i :: il when i.iend >= pos ->
|
||||
Interval.remove_expired_ranges i pos;
|
||||
i :: release_expired_fixed pos il
|
||||
| _ -> []
|
||||
|
||||
let rec release_expired_active ci pos = function
|
||||
i :: il when i.iend >= pos ->
|
||||
Interval.remove_expired_ranges i pos;
|
||||
if Interval.is_live i pos then
|
||||
i :: release_expired_active ci pos il
|
||||
else begin
|
||||
ci.ci_inactive <- insert_interval_sorted i ci.ci_inactive;
|
||||
release_expired_active ci pos il
|
||||
end
|
||||
| _ -> []
|
||||
|
||||
let rec release_expired_inactive ci pos = function
|
||||
i :: il when i.iend >= pos ->
|
||||
Interval.remove_expired_ranges i pos;
|
||||
if not (Interval.is_live i pos) then
|
||||
i :: release_expired_inactive ci pos il
|
||||
else begin
|
||||
ci.ci_active <- insert_interval_sorted i ci.ci_active;
|
||||
release_expired_inactive ci pos il
|
||||
end
|
||||
| _ -> []
|
||||
|
||||
(* Allocate a new stack slot to the interval. *)
|
||||
|
||||
let allocate_stack_slot i =
|
||||
let cl = Proc.register_class i.reg in
|
||||
let ss = Proc.num_stack_slots.(cl) in
|
||||
Proc.num_stack_slots.(cl) <- succ ss;
|
||||
i.reg.loc <- Stack(Local ss);
|
||||
i.reg.spill <- true
|
||||
|
||||
(* Find a register for the given interval and assigns this register.
|
||||
The interval is added to active. Raises Not_found if no free registers
|
||||
left. *)
|
||||
|
||||
let allocate_free_register i =
|
||||
begin match i.reg.loc, i.reg.spill with
|
||||
Unknown, true ->
|
||||
(* Allocate a stack slot for the already spilled interval *)
|
||||
allocate_stack_slot i
|
||||
| Unknown, _ ->
|
||||
(* We need to allocate a register to this interval somehow *)
|
||||
let cl = Proc.register_class i.reg in
|
||||
begin match Proc.num_available_registers.(cl) with
|
||||
0 ->
|
||||
(* There are no registers available for this class *)
|
||||
raise Not_found
|
||||
| rn ->
|
||||
let ci = active.(cl) in
|
||||
let r0 = Proc.first_available_register.(cl) in
|
||||
(* Create register mask for this class *)
|
||||
let regmask = Array.make rn true in
|
||||
(* Remove all assigned registers from the register mask *)
|
||||
List.iter
|
||||
(function
|
||||
{reg = {loc = Reg r}} -> regmask.(r - r0) <- false
|
||||
| _ -> ())
|
||||
ci.ci_active;
|
||||
(* Remove all overlapping registers from the register mask *)
|
||||
let remove_bound_overlapping = function
|
||||
{reg = {loc = Reg r}} as j ->
|
||||
if regmask.(r - r0) && Interval.overlap j i then
|
||||
regmask.(r - r0) <- false
|
||||
| _ -> () in
|
||||
List.iter remove_bound_overlapping ci.ci_inactive;
|
||||
List.iter remove_bound_overlapping ci.ci_fixed;
|
||||
(* Assign the first free register (if any) *)
|
||||
let rec assign r =
|
||||
if r = rn then
|
||||
raise Not_found
|
||||
else if regmask.(r) then begin
|
||||
(* Assign the free register and insert the
|
||||
current interval into the active list *)
|
||||
i.reg.loc <- Reg (r0 + r);
|
||||
i.reg.spill <- false;
|
||||
ci.ci_active <- insert_interval_sorted i ci.ci_active
|
||||
end else
|
||||
assign (succ r) in
|
||||
assign 0
|
||||
end
|
||||
| _ -> ()
|
||||
end
|
||||
|
||||
let allocate_blocked_register i =
|
||||
let cl = Proc.register_class i.reg in
|
||||
let ci = active.(cl) in
|
||||
begin match ci.ci_active with
|
||||
ilast :: il when ilast.iend > i.iend ->
|
||||
(* Last interval in active is the last interval, so spill it. *)
|
||||
begin match ilast.reg.loc with
|
||||
Reg _ as loc ->
|
||||
(* Use register from last interval for current interval *)
|
||||
i.reg.loc <- loc
|
||||
| _ -> ()
|
||||
end;
|
||||
(* Remove the last interval from active and insert the current *)
|
||||
ci.ci_active <- insert_interval_sorted i il;
|
||||
(* Now get a new stack slot for the spilled register *)
|
||||
allocate_stack_slot ilast
|
||||
| _ ->
|
||||
(* Either the current interval is last and we have to spill it,
|
||||
or there are no registers at all in the register class (i.e.
|
||||
floating point class on i386). *)
|
||||
allocate_stack_slot i
|
||||
end
|
||||
|
||||
let walk_interval i =
|
||||
let pos = i.ibegin land (lnot 0x01) in
|
||||
(* Release all intervals that have been expired at the current position *)
|
||||
Array.iter
|
||||
(fun ci ->
|
||||
ci.ci_fixed <- release_expired_fixed pos ci.ci_fixed;
|
||||
ci.ci_active <- release_expired_active ci pos ci.ci_active;
|
||||
ci.ci_inactive <- release_expired_inactive ci pos ci.ci_inactive)
|
||||
active;
|
||||
try
|
||||
(* Allocate free register (if any) *)
|
||||
allocate_free_register i
|
||||
with
|
||||
Not_found ->
|
||||
(* No free register, need to decide which interval to spill *)
|
||||
allocate_blocked_register i
|
||||
|
||||
let allocate_registers() =
|
||||
(* Initialize the stack slots and interval lists *)
|
||||
for cl = 0 to Proc.num_register_classes - 1 do
|
||||
(* Start with empty interval lists *)
|
||||
active.(cl) <- {
|
||||
ci_fixed = [];
|
||||
ci_active = [];
|
||||
ci_inactive = []
|
||||
};
|
||||
Proc.num_stack_slots.(cl) <- 0
|
||||
done;
|
||||
(* Add all fixed intervals (sorted by end position) *)
|
||||
List.iter
|
||||
(fun i ->
|
||||
let ci = active.(Proc.register_class i.reg) in
|
||||
ci.ci_fixed <- insert_interval_sorted i ci.ci_fixed)
|
||||
(Interval.all_fixed_intervals());
|
||||
(* Walk all the intervals within the list *)
|
||||
List.iter walk_interval (Interval.all_intervals())
|
|
@ -0,0 +1,18 @@
|
|||
(***********************************************************************)
|
||||
(* *)
|
||||
(* Objective Caml *)
|
||||
(* *)
|
||||
(* Marcell Fischbach, University of Siegen *)
|
||||
(* Benedikt Meurer, University of Siegen *)
|
||||
(* *)
|
||||
(* Copyright 2011 Lehrstuhl für Compilerbau und Softwareanalyse, *)
|
||||
(* Universität Siegen. All rights reserved. This file is distri- *)
|
||||
(* buted under the terms of the Q Public License version 1.0. *)
|
||||
(* *)
|
||||
(***********************************************************************)
|
||||
|
||||
(* $Id$ *)
|
||||
|
||||
(* Linear scan register allocation. *)
|
||||
|
||||
val allocate_registers: unit -> unit
|
|
@ -19,6 +19,7 @@ open Format
|
|||
open Cmm
|
||||
open Reg
|
||||
open Mach
|
||||
open Interval
|
||||
|
||||
let reg ppf r =
|
||||
if not (Reg.anonymous r) then
|
||||
|
@ -242,6 +243,18 @@ let interferences ppf () =
|
|||
fprintf ppf "*** Interferences@.";
|
||||
List.iter (interference ppf) (Reg.all_registers())
|
||||
|
||||
let interval ppf i =
|
||||
let interv ppf =
|
||||
List.iter
|
||||
(fun r -> fprintf ppf "@ [%d;%d]" r.rbegin r.rend)
|
||||
i.ranges in
|
||||
fprintf ppf "@[<2>%a:%t@]@." reg i.reg interv
|
||||
|
||||
let intervals ppf () =
|
||||
fprintf ppf "*** Intervals@.";
|
||||
List.iter (interval ppf) (Interval.all_fixed_intervals());
|
||||
List.iter (interval ppf) (Interval.all_intervals())
|
||||
|
||||
let preference ppf r =
|
||||
let prefs ppf =
|
||||
List.iter
|
||||
|
|
|
@ -27,6 +27,7 @@ val instr: formatter -> Mach.instruction -> unit
|
|||
val fundecl: formatter -> Mach.fundecl -> unit
|
||||
val phase: string -> formatter -> Mach.fundecl -> unit
|
||||
val interferences: formatter -> unit -> unit
|
||||
val intervals: formatter -> unit -> unit
|
||||
val preferences: formatter -> unit -> unit
|
||||
|
||||
val print_live: bool ref
|
||||
|
|
|
@ -151,8 +151,9 @@ let rec reload i before =
|
|||
| Iop op ->
|
||||
let new_before =
|
||||
(* Quick check to see if the register pressure is below the maximum *)
|
||||
if Reg.Set.cardinal i.live + Array.length i.res <=
|
||||
Proc.safe_register_pressure op
|
||||
if !Clflags.use_linscan ||
|
||||
(Reg.Set.cardinal i.live + Array.length i.res <=
|
||||
Proc.safe_register_pressure op)
|
||||
then before
|
||||
else add_superpressure_regs op i.live i.res before in
|
||||
let after =
|
||||
|
|
|
@ -248,6 +248,10 @@ let mk_linkall f =
|
|||
"-linkall", Arg.Unit f, " Link all modules, even unused ones"
|
||||
;;
|
||||
|
||||
let mk_linscan f =
|
||||
"-linscan", Arg.Unit f, " Use the linear scan register allocator"
|
||||
;;
|
||||
|
||||
let mk_make_runtime f =
|
||||
"-make-runtime", Arg.Unit f,
|
||||
" Build a runtime system with given C objects and libraries"
|
||||
|
@ -697,6 +701,10 @@ let mk_dlinear f =
|
|||
"-dlinear", Arg.Unit f, " (undocumented)"
|
||||
;;
|
||||
|
||||
let mk_dinterval f =
|
||||
"-dinterval", Arg.Unit f, " (undocumented)"
|
||||
;;
|
||||
|
||||
let mk_dstartup f =
|
||||
"-dstartup", Arg.Unit f, " (undocumented)"
|
||||
;;
|
||||
|
@ -931,6 +939,7 @@ module type Optcomp_options = sig
|
|||
include Common_options
|
||||
include Compiler_options
|
||||
include Optcommon_options
|
||||
val _linscan : unit -> unit
|
||||
val _no_float_const_prop : unit -> unit
|
||||
val _nodynlink : unit -> unit
|
||||
val _p : unit -> unit
|
||||
|
@ -939,6 +948,7 @@ module type Optcomp_options = sig
|
|||
val _shared : unit -> unit
|
||||
val _afl_instrument : unit -> unit
|
||||
val _afl_inst_ratio : int -> unit
|
||||
val _dinterval : unit -> unit
|
||||
end;;
|
||||
|
||||
module type Opttop_options = sig
|
||||
|
@ -1167,6 +1177,7 @@ struct
|
|||
mk_inline_max_depth F._inline_max_depth;
|
||||
mk_alias_deps F._alias_deps;
|
||||
mk_no_alias_deps F._no_alias_deps;
|
||||
mk_linscan F._linscan;
|
||||
mk_app_funct F._app_funct;
|
||||
mk_no_app_funct F._no_app_funct;
|
||||
mk_no_float_const_prop F._no_float_const_prop;
|
||||
|
@ -1249,6 +1260,7 @@ struct
|
|||
mk_dreload F._dreload;
|
||||
mk_dscheduling F._dscheduling;
|
||||
mk_dlinear F._dlinear;
|
||||
mk_dinterval F._dinterval;
|
||||
mk_dstartup F._dstartup;
|
||||
mk_dtimings F._dtimings;
|
||||
mk_dump_pass F._dump_pass;
|
||||
|
|
|
@ -196,6 +196,7 @@ module type Optcomp_options = sig
|
|||
include Common_options
|
||||
include Compiler_options
|
||||
include Optcommon_options
|
||||
val _linscan : unit -> unit
|
||||
val _no_float_const_prop : unit -> unit
|
||||
val _nodynlink : unit -> unit
|
||||
val _p : unit -> unit
|
||||
|
@ -204,6 +205,7 @@ module type Optcomp_options = sig
|
|||
val _shared : unit -> unit
|
||||
val _afl_instrument : unit -> unit
|
||||
val _afl_inst_ratio : int -> unit
|
||||
val _dinterval : unit -> unit
|
||||
end;;
|
||||
|
||||
module type Opttop_options = sig
|
||||
|
|
|
@ -120,6 +120,7 @@ module Options = Main_args.Make_optcomp_options (struct
|
|||
inline_max_depth
|
||||
let _alias_deps = clear transparent_modules
|
||||
let _no_alias_deps = set transparent_modules
|
||||
let _linscan = set use_linscan
|
||||
let _app_funct = set applicative_functors
|
||||
let _no_app_funct = clear applicative_functors
|
||||
let _no_float_const_prop = clear float_const_prop
|
||||
|
@ -221,6 +222,7 @@ module Options = Main_args.Make_optcomp_options (struct
|
|||
let _dreload = set dump_reload
|
||||
let _dscheduling = set dump_scheduling
|
||||
let _dlinear = set dump_linear
|
||||
let _dinterval = set dump_interval
|
||||
let _dstartup = set keep_startup_file
|
||||
let _dtimings = set print_timings
|
||||
let _opaque = set opaque
|
||||
|
|
|
@ -78,6 +78,6 @@ clean:: partialclean
|
|||
$(CAMLOPT) -c $(COMPFLAGS) $<
|
||||
|
||||
depend:
|
||||
$(CAMLRUN) $(ROOTDIR)/tools/ocamldep *.mli *.ml >> .depend
|
||||
$(CAMLRUN) $(ROOTDIR)/tools/ocamldep *.mli *.ml > .depend
|
||||
|
||||
include .depend
|
||||
|
|
|
@ -144,6 +144,7 @@ module Options = Main_args.Make_optcomp_options (struct
|
|||
let _color s = option_with_arg "-color" s
|
||||
let _where = option "-where"
|
||||
|
||||
let _linscan = option "-linscan"
|
||||
let _nopervasives = option "-nopervasives"
|
||||
let _dsource = option "-dsource"
|
||||
let _dparsetree = option "-dparsetree"
|
||||
|
@ -171,6 +172,7 @@ module Options = Main_args.Make_optcomp_options (struct
|
|||
let _dscheduling = option "-dscheduling"
|
||||
let _dlinear = option "-dlinear"
|
||||
let _dstartup = option "-dstartup"
|
||||
let _dinterval = option "-dinterval"
|
||||
let _dtimings = option "-dtimings"
|
||||
let _opaque = option "-opaque"
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ module Options = Main_args.Make_opttop_options (struct
|
|||
let _labels = clear classic
|
||||
let _alias_deps = clear transparent_modules
|
||||
let _no_alias_deps = set transparent_modules
|
||||
let _dlinscan = set use_linscan
|
||||
let _app_funct = set applicative_functors
|
||||
let _no_app_funct = clear applicative_functors
|
||||
let _noassert = set noassert
|
||||
|
@ -229,6 +230,7 @@ module Options = Main_args.Make_opttop_options (struct
|
|||
let _dreload = set dump_reload
|
||||
let _dscheduling = set dump_scheduling
|
||||
let _dlinear = set dump_linear
|
||||
let _dinterval = set dump_interval
|
||||
let _dstartup = set keep_startup_file
|
||||
let _safe_string = clear unsafe_string
|
||||
let _unsafe_string = set unsafe_string
|
||||
|
|
|
@ -50,6 +50,7 @@ and print_types = ref false (* -i *)
|
|||
and make_archive = ref false (* -a *)
|
||||
and debug = ref false (* -g *)
|
||||
and fast = ref false (* -unsafe *)
|
||||
and use_linscan = ref false (* -linscan *)
|
||||
and link_everything = ref false (* -linkall *)
|
||||
and custom_runtime = ref false (* -custom *)
|
||||
and no_check_prims = ref false (* -no-check-prims *)
|
||||
|
@ -120,6 +121,7 @@ let dump_regalloc = ref false (* -dalloc *)
|
|||
let dump_reload = ref false (* -dreload *)
|
||||
let dump_scheduling = ref false (* -dscheduling *)
|
||||
let dump_linear = ref false (* -dlinear *)
|
||||
let dump_interval = ref false (* -dinterval *)
|
||||
let keep_startup_file = ref false (* -dstartup *)
|
||||
let dump_combine = ref false (* -dcombine *)
|
||||
let print_timings = ref false (* -dtimings *)
|
||||
|
|
|
@ -75,6 +75,7 @@ val print_types : bool ref
|
|||
val make_archive : bool ref
|
||||
val debug : bool ref
|
||||
val fast : bool ref
|
||||
val use_linscan : bool ref
|
||||
val link_everything : bool ref
|
||||
val custom_runtime : bool ref
|
||||
val no_check_prims : bool ref
|
||||
|
@ -141,6 +142,7 @@ val dump_regalloc : bool ref
|
|||
val dump_reload : bool ref
|
||||
val dump_scheduling : bool ref
|
||||
val dump_linear : bool ref
|
||||
val dump_interval : bool ref
|
||||
val keep_startup_file : bool ref
|
||||
val dump_combine : bool ref
|
||||
val native_code : bool ref
|
||||
|
|
Loading…
Reference in New Issue