## backend-tophalf-g.pkg
# Compiled by:
#
src/lib/compiler/core.sublib# This file defines the backend of the compiler, primarily
# the backend tophalf, which is to say the part which does
# the machine-independent code optimizations and transformations.
#
#
# At compiletime this generic gets invoked by
#
#
src/lib/compiler/back/low/main/intel32/backend-intel32-g.pkg#
src/lib/compiler/back/low/main/pwrpc32/backend-pwrpc32.pkg#
src/lib/compiler/back/low/main/sparc32/backend-sparc32.pkg#
# to produce the various platform-specific compiler backends.
#
# The "package blh' ("backend_lowhalf") generic parameter which they
# hand us takes care of all the machine-dependent optimizations,
# code-generation issues etc for us.
#
#
#
# Runtime invocation of our (sole)
#
# translate_anormcode_to_execode
#
# entrypoint is from
#
#
src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg### "When trouble is solved before it forms,
### who calls that clever?"
###
### -- Sun Tzu
stipulate
package abc = eliminate_array_bounds_checks_in_anormcode; # eliminate_array_bounds_checks_in_anormcode is from
src/lib/compiler/back/top/improve/eliminate-array-bounds-checks-in-anormcode.pkg package an = anormcode_form; # anormcode_form is from
src/lib/compiler/back/top/anormcode/anormcode-form.pkg package asc = anormcode_sequencer_controls; # anormcode_sequencer_controls is from
src/lib/compiler/back/top/main/anormcode-sequencer-controls.pkg package bac = insert_anormcode_boxing_and_coercion_code; # insert_anormcode_boxing_and_coercion_code is from
src/lib/compiler/back/top/forms/insert-anormcode-boxing-and-coercion-code.pkg package cos = compile_statistics; # compile_statistics is from
src/lib/compiler/front/basics/stats/compile-statistics.pkg package cpu = cpu_timer; # cpu_timer is from
src/lib/std/src/cpu-timer.pkg package cs = code_segment; # code_segment is from
src/lib/compiler/execution/code-segments/code-segment.pkg package ctv = anormcode_namedtypevar_vs_debruijntypevar_forms; # anormcode_namedtypevar_vs_debruijntypevar_forms is from
src/lib/compiler/back/top/anormcode/anormcode-namedtypevar-vs-debruijntypevar-forms.pkg package dai = do_crossmodule_anormcode_inlining; # do_crossmodule_anormcode_inlining is from
src/lib/compiler/back/top/improve/do-crossmodule-anormcode-inlining.pkg package drt = drop_types_from_anormcode; # drop_types_from_anormcode is from
src/lib/compiler/back/top/forms/drop-types-from-anormcode.pkg package dua = def_use_analysis_of_anormcode; # def_use_analysis_of_anormcode is from
src/lib/compiler/back/top/improve/def-use-analysis-of-anormcode.pkg package fil = file__premicrothread; # file__premicrothread is from
src/lib/std/src/posix/file--premicrothread.pkg package fvp = convert_free_variables_to_parameters_in_anormcode; # convert_free_variables_to_parameters_in_anormcode is from
src/lib/compiler/back/top/improve/convert-free-variables-to-parameters-in-anormcode.pkg package glb = make_nextcode_literals_bytecode_vector; # make_nextcode_literals_bytecode_vector is from
src/lib/compiler/back/top/main/make-nextcode-literals-bytecode-vector.pkg package hcf = highcode_form; # highcode_form is from
src/lib/compiler/back/top/highcode/highcode-form.pkg package ia = improve_anormcode; # improve_anormcode is from
src/lib/compiler/back/top/improve/improve-anormcode.pkg package iaq = improve_anormcode_quickly; # improve_anormcode_quickly is from
src/lib/compiler/back/top/improve/improve-anormcode-quickly.pkg package ihc = pick_nextcode_fns_for_heaplimit_checks; # pick_nextcode_fns_for_heaplimit_checks is from
src/lib/compiler/back/low/main/nextcode/pick-nextcode-fns-for-heaplimit-checks.pkg package la = loopify_anormcode; # loopify_anormcode is from
src/lib/compiler/back/top/improve/loopify-anormcode.pkg package lgt = specialize_anormcode_to_least_general_type; # specialize_anormcode_to_least_general_type is from
src/lib/compiler/back/top/improve/specialize-anormcode-to-least-general-type.pkg package mrf = improve_mutually_recursive_anormcode_functions; # improve_mutually_recursive_anormcode_functions is from
src/lib/compiler/back/top/improve/improve-mutually-recursive-anormcode-functions.pkg package ngf = unnest_nextcode_fns; # unnest_nextcode_fns is from
src/lib/compiler/back/top/closures/unnest-nextcode-fns.pkg package no = null_or; # null_or is from
src/lib/std/src/null-or.pkg package pa = prettyprint_anormcode; # prettyprint_anormcode is from
src/lib/compiler/back/top/anormcode/prettyprint-anormcode.pkg package pcs = per_compile_stuff; # per_compile_stuff is from
src/lib/compiler/front/typer-stuff/main/per-compile-stuff.pkg package pp = standard_prettyprinter; # standard_prettyprinter is from
src/lib/prettyprint/big/src/standard-prettyprinter.pkg package cv = compiler_verbosity; # compiler_verbosity is from
src/lib/compiler/front/basics/main/compiler-verbosity.pkg package rat = recover_anormcode_type_info; # recover_anormcode_type_info is from
src/lib/compiler/back/top/improve/recover-anormcode-type-info.pkg package tm = time; # time is from
src/lib/std/time.pkg package tr = cpu_timer; # cpu_timer is from
src/lib/std/src/cpu-timer.pkg Npp = pp::Npp;
infix my 70 +++ ; my (+++) = tm::(+) ;
infix my 70 --- ; my (---) = tm::(-) ;
tracing = logger::make_logtree_leaf { parent => fil::all_logging, name => "backend::tracing", default => FALSE };
trace = logger::log_if tracing 0; # Conditionally write string to tracing.log or whatever.
#
# To debug via tracelogging, annotate the code with lines like
#
# trace {. sprintf "foo/top: bar d=%d" bar; };
#
# and then set write_tracelog = TRUE; below.
herein
# This generic is invoked from:
#
#
src/lib/compiler/back/low/main/intel32/backend-intel32-g.pkg #
src/lib/compiler/back/low/main/pwrpc32/backend-pwrpc32.pkg #
src/lib/compiler/back/low/main/sparc32/backend-sparc32.pkg #
generic package backend_tophalf_g (
# =================
#
package blh: Backend_Lowhalf; # Backend_Lowhalf is from
src/lib/compiler/back/low/main/main/backend-lowhalf.api # backend_lowhalf_g is from
src/lib/compiler/back/low/main/main/backend-lowhalf-g.pkg # backend_lowhalf_intel32_g is from
src/lib/compiler/back/low/main/intel32/backend-lowhalf-intel32-g.pkg # backend_lowhalf_pwrpc32 is from
src/lib/compiler/back/low/main/pwrpc32/backend-lowhalf-pwrpc32.pkg # backend_lowhalf_sparc32 is from
src/lib/compiler/back/low/main/sparc32/backend-lowhalf-sparc32.pkg # "blh" == "backend_lowhalf".
harvest_code_segment # harvest_code_segment def in
src/lib/compiler/back/low/main/pwrpc32/backend-pwrpc32.pkg : # harvest_code_segment def in
src/lib/compiler/back/low/main/sparc32/backend-sparc32.pkg (Npp, cv::Compiler_Verbosity) # harvest_code_segment def in
src/lib/compiler/back/low/main/intel32/backend-intel32-g.pkg ->
(Void -> Int)
->
cs::Code_Segment;
)
: (weak) Backend # Backend is from
src/lib/compiler/toplevel/main/backend.api {
stipulate
#
package mp = blh::mp; # "mp" == "machine_properties".
package a2f = translate_anormcode_to_nextcode_g( mp ); # translate_anormcode_to_nextcode_g is from
src/lib/compiler/back/top/nextcode/translate-anormcode-to-nextcode-g.pkg package fpt = nextcode_preimprover_transform_g( mp ); # nextcode_preimprover_transform_g is from
src/lib/compiler/back/top/nextcode/nextcode-preimprover-transform-g.pkg
package run = run_optional_nextcode_improvers_g( mp ); # run_optional_nextcode_improvers_g is from
src/lib/compiler/back/top/improve-nextcode/run-optional-nextcode-improvers-g.pkg package mfc = make_nextcode_closures_g( mp ); # make_nextcode_closures_g is from
src/lib/compiler/back/top/closures/make-nextcode-closures-g.pkg package sfr = spill_nextcode_registers_g( mp ); # spill_nextcode_registers_g if from
src/lib/compiler/back/low/main/nextcode/spill-nextcode-registers-g.pkg package fin = nextcode_inlining_g( mp ); # nextcode_inlining_g is from
src/lib/compiler/back/top/closures/dummy-nextcode-inlining-g.pkg herein # Implements cross-module inlining -- or would, if its contents weren't commented out.
# Export to client packages:
#
package blh = blh;
target_architecture = blh::mp::machine_architecture; # PWRPC32/SPARC32/INTEL32.
abi_variant = blh::abi_variant;
#
fun bug s
=
error_message::impossible ("backend_tophalf_g:" + s);
say = control_print::say;
package k {
Highcodekind # This is a simple ad-hoc mechanism to ensure sane ordering of highcode passes.
= WRAP
| DROP_TYPES
| DEBRUIJN
| NAMED
;
};
#
fun phase x
=
cos::do_compiler_phase (cos::make_compiler_phase x);
# Which of these gets used, and in what order, is controlled by 'anormcode_passes' in:
#
#
src/lib/compiler/back/top/main/anormcode-sequencer-controls.pkg #
convert_debruijn_typevars_to_named_typevars_in_anormcode = phase "highcode 056 convert_debruijn_typevars_to_named_typevars_in_anormcode" ctv::convert_debruijn_typevars_to_named_typevars_in_anormcode;
convert_named_typevars_to_debruijn_typevars_in_anormcode = phase "highcode 057 convert_named_typevars_to_debruijn_typevars_in_anormcode" ctv::convert_named_typevars_to_debruijn_typevars_in_anormcode;
/*Used*/ improve_anormcode_quickly = phase "highcode 052 improve_anormcode_quickly" iaq::improve_anormcode_quickly;
/*used*/ collect_anormcode_def_use_info = phase "highcode 052a collect_anormcode_def_use_info" dua::collect_anormcode_def_use_info;
/*Used*/ improve_anormcode = phase "highcode 052b improve_anormcode" (\\ (opts, expression) = ia::improve_anormcode opts expression);
/*Used*/ loopify_anormcode = phase "highcode 057 loopify_anormcode" la::loopify_anormcode;
/*Used*/ improve_mutually_recursive_anormcode_functions = phase "highcode 056 improve_mutually_recursive_anormcode_functions" mrf::improve_mutually_recursive_anormcode_functions;
/*Used*/ do_crossmodule_anormcode_inlining = phase "highcode 058 do_crossmodule_anormcode_inlining" dai::do_crossmodule_anormcode_inlining;
eliminate_array_bounds_checks_in_anormcode = phase "highcode 059 eliminate_array_bounds_checks_in_anormcode" abc::eliminate_array_bounds_checks_in_anormcode;
convert_free_variables_to_parameters_in_anormcode = phase "highcode 0535 convert_free_variables_to_parameters_in_anormcode" fvp::convert_free_variables_to_parameters_in_anormcode;
anormcode_is_well_formed = phase "highcode 0536 anormcode_is_well_formed" fvp::anormcode_is_well_formed;
/*Used*/ specialize_anormcode_to_least_general_type = phase "highcode 053 specialize_anormcode_to_least_general_type" lgt::specialize_anormcode_to_least_general_type;
/*Used*/ insert_anormcode_boxing_and_coercion_code = phase "highcode 054 insert_anormcode_boxing_and_coercion_code" bac::insert_anormcode_boxing_and_coercion_code;
/*Used*/ drop_types_from_anormcode = phase "highcode 055 drop_types_from_anormcode" drt::drop_types_from_anormcode;
recover_anormcode_type_info = phase "highcode 05a recover_anormcode_type_info" rat::recover_anormcode_type_info;
translate_anormcode_to_nextcode = phase "nextcode 060 translate_anormcode_to_nextcode" a2f::translate_anormcode_to_nextcode;
nextcode_preimprover_transform = phase "nextcode 065 nextcode_preimprover_transform" fpt::nextcode_preimprover_transform;
run_optional_nextcode_improvers = phase "nextcode 070 run_optional_nextcode_improvers" run::run_optional_nextcode_improvers;
split_off_nextcode_literals = phase "nextcode 075 split_off_nextcode_literals" glb::split_off_nextcode_literals;
make_nextcode_literals_bytecode_vector = phase "nextcode 076 make_nextcode_literals_bytecode_vector" glb::make_nextcode_literals_bytecode_vector;
make_nextcode_closures = phase "nextcode 080 make_nextcode_closures" mfc::make_nextcode_closures;
unnest_nextcode_fns = phase "nextcode 090 unnest_nextcode_fns" ngf::unnest_nextcode_fns;
spill_nextcode_registers = phase "nextcode 100 spill_nextcode_registers" sfr::spill_nextcode_registers;
pick_nextcode_fns_for_heaplimit_checks = phase "nextcode 110 pick_nextcode_fns_for_heaplimit_checks" ihc::pick_nextcode_fns_for_heaplimit_checks;
translate_nextcode_to_execode = phase "nextcode 120 nextcode_to_execode" blh::translate_nextcode_to_execode;
improve_anormcode
=
\\ opts =
\\ lambda_expression
=
improve_anormcode (opts, collect_anormcode_def_use_info lambda_expression);
# Pretty printing for the "A-Normal" and
# "Nextcode" (== continuation passing style)
# intermediate code formats.
#
my ( pprint_anormcode_program,
pprint_nextcode_expression
)
=
{ fun make_prettyprinter (flag, print_e) s e
=
if *flag
#
say ("\n[After " + s + " ...]\n\n");
print_e e;
say "\n";
e;
else
e;
fi;
( make_prettyprinter (asc::print, prettyprint_anormcode::print_prog),
make_prettyprinter (global_controls::compiler::printit, prettyprint_nextcode::print_nextcode_function)
);
};
# Writing out a term into
# a error output file
#
fun dump_term (print_e, s, le)
=
{ out_s = fil::open_for_append s;
#
save_out = *global_controls::print::out;
#
fun done ()
=
{ fil::close_output out_s;
#
global_controls::print::out := save_out;
};
global_controls::print::out
:=
{ say => \\ s = fil::write (out_s, s),
flush => \\ () = fil::flush out_s
};
print_e le
except
x = { done ()
except
_ = ();
raise exception x;
};
done ();
};
# XXX BUGGO FIXME This looks like more thread-hostile buried global mutable state :(
# my fcs: Ref( List( anormcode::Program -> anormcode::Program ) )
# = REF [];
# Compile anormcode ("A-Normal" intermediate code)
# to nextcode ("continuation passing style" intermediate code)
# and thence on down to binary machine code.
# This function is invoked (only) from
# fun translate_anormcode_to_execode in
#
#
src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg #
fun translate_anormcode_to_execode (
#
highcode,
per_compile_stuff as { error_fn, source_name, prettyprinter_or_null, cpu_timer, compiler_verbosity, ... }
:
pcs::Per_Compile_Stuff( deep_syntax::Declaration ),
crossmodule_inlining_aggressiveness # This gets used in
src/lib/compiler/back/top/improve/do-crossmodule-anormcode-inlining.pkg )
=
{ time_to_string = tm::format 5;
# Write 'string' to our compile.log file, if any:
#
fun to_compile_log string
=
case prettyprinter_or_null
#
NULL => ();
#
THE pp => if compiler_verbosity.pprint_elapsed_times
#
elapsed_cpu
=
time::from_float_seconds
#
(cpu::get_added_cpu_seconds cpu_timer);
#
pp.lit (sprintf "(%s cpu secs) " (time_to_string elapsed_cpu));
pp.lit string;
pp.newline();
fi;
esac;
to_compile_log "translate_anormcode_to_execode/TOP";
#
fun err severity s
=
error_fn (0, 0) severity (cat ["Float constant out of range: ", s, "\n"]);
#
fun check (check_e, print_e, check_id) (level, log_id) e
=
if (check_e (e, level))
dump_term (print_e, source_name + "." + check_id + log_id, e);
bug (check_id + " typing errors " + log_id);
fi;
#
fun maybe_prettyprint_nextcode function
=
{ per_compile_stuff -> { prettyprinter_or_null, compiler_verbosity, ... };
#
case prettyprinter_or_null
#
THE pp
=>
{ pp.txt' 0 1 "\n\n\n(Following printed by src/lib/compiler/back/top/main/backend-tophalf-g.pkg.)\n";
pp.txt' 0 1 "\n\nnextcode form:\n";
prettyprint_nextcode::prettyprint_nextcode_function pp function;
pp.txt' 0 1 "\n";
pp.flush ();
};
NULL => ();
esac;
};
#
fun wff (f, s) # "wff" == "well formed formula"
=
if (not (anormcode_is_well_formed f))
print ("\nAfter " + s + " CODE NOT WELL FORMED\n");
fi;
# f: program highcode code
# fifi: program opt inlinable approximation of f
# fk: highcodekind what kind of highcode variant this is
# l: String last phase through which it went
#
# Our phase sequence here is controlled by 'anormcode_passes' in:
#
#
src/lib/compiler/back/top/main/anormcode-sequencer-controls.pkg #
fun runphase (p, (f, fifi, fk, l))
=
case (p, fk)
#
(("improve_anormcode"
| "improve_anormcode_quickly"), k::DEBRUIJN)
=>
{ say("\n!! " + p + " cannot be applied to the DeBruijn form !!\n");
(f, fifi, fk, l);
};
("improve_anormcode", _)
=>
(improve_anormcode { eta_split=>FALSE, tfn_inline=>FALSE } f, fifi, fk, p);
("improve_anormcode+eta", _)
=>
(improve_anormcode { eta_split=>TRUE, tfn_inline=>FALSE } f, fifi, fk, p);
("improve_anormcode_quickly", _)
=>
(improve_anormcode_quickly f, fifi, fk, p);
("improve_mutually_recursive_anormcode_functions", _)
=>
(improve_mutually_recursive_anormcode_functions f, fifi, fk, p);
("loopify_anormcode", _) => (loopify_anormcode f, fifi, fk, p);
("eliminate_array_bounds_checks_in_anormcode", _) => (eliminate_array_bounds_checks_in_anormcode f, fifi, fk, p);
("specialize_anormcode_to_least_general_type", k::NAMED) => (specialize_anormcode_to_least_general_type f, fifi, fk, p);
("insert_anormcode_boxing_and_coercion_code", k::NAMED) => (insert_anormcode_boxing_and_coercion_code f, fifi, k::WRAP, p);
("drop_types_from_anormcode", k::WRAP) => (drop_types_from_anormcode f, fifi, k::DROP_TYPES, p);
("deb2names", k::DEBRUIJN) => (convert_debruijn_typevars_to_named_typevars_in_anormcode f, fifi, k::NAMED, p);
("names2deb", k::NAMED) => (convert_named_typevars_to_debruijn_typevars_in_anormcode f, fifi, k::DEBRUIJN, p);
("convert_free_variables_to_parameters_in_anormcode", _)
=>
{ f = convert_free_variables_to_parameters_in_anormcode f;
if *asc::check wff (f, p); fi;
(f, fifi, fk, p);
};
("do_crossmodule_anormcode_inlining", k::NAMED)
=>
{ (do_crossmodule_anormcode_inlining
( f,
crossmodule_inlining_aggressiveness
) )
->
(f, fifi);
#
(f, fifi, fk, p);
};
# pseudo highcode phases
("pickle", _)
=>
( the (unpickler_junk::unpickle_highcode ((pickler_junk::pickle_highcode_program (THE f)).pickle)),
(unpickler_junk::unpickle_highcode ((pickler_junk::pickle_highcode_program fifi ).pickle)),
fk,
p
);
("collect_anormcode_def_use_info", _)
=>
(collect_anormcode_def_use_info f, fifi, fk, p);
_ =>
{ case (p, fk)
#
("id", _) => ();
("wellformed", _) => wff (f, l);
#
("recover_anormcode_type_info", _)
=>
{ (recover_anormcode_type_info (f, fk == k::DROP_TYPES))
->
{ get_uniqtypoid_for_anormcode_value => gettype, ... };
asc::recover := (say o hcf::uniqtypoid_to_string o gettype o an::VAR);
};
("print", _)
=>
{ say ("\n[After " + l + "...]\n\n");
pa::print_fundec f; say "\n";
};
("printsplit", _)
=>
{ say "[ splitted ]\n\n";
no::map pa::print_fundec fifi;
say "\n";
};
("check", _)
=>
(check (type_anormcode::check_top, prettyprint_anormcode::print_fundec, "highcode")
(fk == k::DROP_TYPES, l) f);
_ =>
say("\n!! Unknown or badly scheduled anormcode pass '" + p + "' !!\n");
esac;
(f, fifi, fk, l);
};
esac;
#
fun print (f, fifi, fk, l)
=
{ pprint_anormcode_program l f;
(f, fifi, fk, l);
};
#
fun check' (f, fifi, fk, l)
=
{ fun c n reified f
=
check (type_anormcode::check_top, prettyprint_anormcode::print_fundec, n)
(reified, l) (convert_named_typevars_to_debruijn_typevars_in_anormcode f);
if (*asc::check)
#
c "HIGHCODE" (fk == k::DROP_TYPES) f;
no::map (c "iHIGHCODE" FALSE) fifi;
();
fi;
(f, fifi, fk, l);
};
#
fun show_history [s] => say (cat [" raised at:\t", s, "\n"]);
show_history (s ! r) => { show_history r; say (cat ["\t\t", s, "\n"]);};
show_history [] => ();
end;
#
fun runphase' (arg as (phase_name, { 1=>f, ... } ))
=
{ if *asc::print_phases say( "Phase " + phase_name + "..."); fi;
( (check' o print o runphase) arg)
then
{ if *asc::print_phases say("..." + phase_name + " Done.\n"); fi;
#
to_compile_log ("translate_anormcode_to_execode phase " + phase_name + " done.");
};
}
except x
=
{ say ("\nwhile in " + phase_name + " phase\n");
dump_term (prettyprint_anormcode::print_fundec, "highcode.core", f);
show_history (lib7::exception_history x);
raise exception x;
};
to_compile_log ("translate_anormcode_to_execode: *asc::phases == '" + (string::join " " *asc::anormcode_passes));
my (highcode, fifi, fk, _)
=
fold_forward runphase'
(highcode, NULL, k::DEBRUIJN, "highcodenm")
(/* "id" ! */ "deb2names" ! *asc::anormcode_passes);
# Run any missing passes:
#
my (highcode, fk)
=
if (fk == k::DEBRUIJN)
#
say "\n!!Forgot deb2names!!\n";
(convert_debruijn_typevars_to_named_typevars_in_anormcode highcode, k::NAMED);
else
(highcode, fk);
fi;
my (highcode, fk)
=
if (fk == k::NAMED)
#
say "\n!!Forgot wrap!!\n";
#
(insert_anormcode_boxing_and_coercion_code highcode, k::WRAP);
else
(highcode, fk);
fi;
my (highcode, fk)
=
if (fk == k::WRAP)
#
say "\n!!Forgot drop_types_from_anormcode!!\n";
(drop_types_from_anormcode highcode, k::DROP_TYPES);
else
(highcode, fk);
fi;
# Finish up with nextcode
#
my (new_code_segment, bytecodes_to_regenerate_literals_vector)
=
{ function = translate_anormcode_to_nextcode highcode;
pprint_nextcode_expression "translate_anormcode_to_nextcode" function;
# Running this on mythryl.lex.pkg takes MINUTES -- must be
# an O(N**2) performance bug or such -- so I've commented
# out the call for now. -- 2010-09-08 CrT
#
# maybe_prettyprint_nextcode function;
function = ( pprint_nextcode_expression "nextcode_preimprover_transform"
o
nextcode_preimprover_transform
)
function;
function = run_optional_nextcode_improvers (function, NULL, FALSE); # Despite the name, before returning this pass always runs rup::replace_unlimited_precision_int_ops_in_nextcode
pprint_nextcode_expression
"optional_nextcode_improvers"
function;
(split_off_nextcode_literals function)
->
(function, literals);
bytecodes_to_regenerate_literals_vector # Generate the literals bytecode program which will eventually be interpreted by
= #
make_nextcode_literals_bytecode_vector literals; # src/c/heapcleaner/make-package-literals-via-bytecode-interpreter.c
pprint_nextcode_expression
"optional_nextcode_improvers-code"
function;
#
case (fin::nextcode_inlining function)
#
[ code_segment ]
=>
( gen code_segment,
bytecodes_to_regenerate_literals_vector
);
_ => bug "unexpected case on gen in translate_anormcode_to_execode";
esac
where
fun gen fx
=
{ fx = ( pprint_nextcode_expression "make_nextcode_closures"
o
make_nextcode_closures
)
fx;
carg = unnest_nextcode_fns fx;
carg = spill_nextcode_registers carg;
(pick_nextcode_fns_for_heaplimit_checks carg)
->
(carg, fun_id__to__max_resource_consumption);
# Here is where runtime flow of control passes from
# our machine-independent FLINT-derived backend tophalf
# to our machine-dependent MLRISC-derived backend lowhalf:
entrypoint_thunk # Evaluates to entrypoint offset in machinecode bytevector. (In practice this is currently always zero.)
=
translate_nextcode_to_execode # translate_nextcode_to_execode def in
src/lib/compiler/back/low/main/main/translate-nextcode-to-treecode-g.pkg {
nextcode_functions => carg,
fun_id__to__max_resource_consumption,
err,
source_name,
per_compile_stuff
};
harvest_code_segment (prettyprinter_or_null, compiler_verbosity) entrypoint_thunk;
# harvest_code_segment def in
src/lib/compiler/back/low/main/pwrpc32/backend-pwrpc32.pkg # harvest_code_segment def in
src/lib/compiler/back/low/main/sparc32/backend-sparc32.pkg # harvest_code_segment def in
src/lib/compiler/back/low/main/intel32/backend-intel32-g.pkg };
end;
};
mapped_fifi
=
no::map convert_named_typevars_to_debruijn_typevars_in_anormcode fifi;
( { code_segment=>new_code_segment, bytecodes_to_regenerate_literals_vector },
mapped_fifi
);
}; # function translate_anormcode_to_execode
translate_anormcode_to_execode
=
phase
"highcode 050 translate_anormcode_to_execode"
translate_anormcode_to_execode;
end; # stipulate
}; # package backend_tophalf_g
end;