Extend this optimization to handle temporaries being both defined in

Estimated hours taken: 12
Branches: main

compiler/use_local_vars.m:
	Extend this optimization to handle temporaries being both defined in
	and used by foreign_proc_code instructions. This should eliminate
	unnecessary accesses to the MR_fake_reg array, and thus speed up
	programs that use foreign code a lot, including typeclass- and
	tabling-intensive programs, since those features are implemented using
	inline foreign code. I/O intensive should also benefit, but not much,
	since the cost of the I/O itself overwhelms the cost of the
	MR_fake_reg accesses.

	Group together the LLDS instructions that are handled similarly.
	Factor out some common code.

compiler/opt_util.m:
	Allow for the fact that foreign_proc_codes can now refer to
	temporaries.

compiler/opt_debug.m:
	Print more useful information about foreign_proc_code components.

compiler/prog_data.m:
	Rename the types and function symbols of the recently added
	foreign_proc attributes to avoid clashing with the keywords
	representing them in source code.

	Add a new foreign_proc attribute, proc_may_duplicate that governs
	whether the body of foreign code is allowed to be duplicated.

compiler/table_gen.m:
	Include does_not_affect_liveness among the annotations for the
	foreign_proc calls generated by this module. Some of these procedures
	affect memory beyond their arguments, but that memory is in tables,
	not in unlisted registers.

	Allow some of the smaller code fragments generated by this module
	to be duplicated.

compiler/inlining.m:
	Respect the may_not_duplicate foreign_proc attribute.

compiler/pragma_c_gen.m:
	Transmit any annotations about liveness from the HLDS to the LLDS,
	since without does_not_affect_liveness annotations use_local_vars.m
	cannot optimize foreign_proc_codes.

	Transmit any annotations about may_duplicate from the HLDS to the LLDS,
	since with them jumpopt can do a better job.

compiler/llds.m:
	Use the new foreign_proc attribute instead of a boolean to represent
	whether a foreign code fragment may be duplicated.

compiler/simplify.m:
	Generate an error message if a may_duplicate or may_not_duplicate
	attribute on a foreign_proc conflicts with a no_inline or inline pragma
	(respectively) on the predicate it belongs to.

compiler/hlds_pred.m:
	Fix some comment rot.

compiler/jumpopt.m:
compiler/livemap.m:
compiler/proc_gen.m:
compiler/trace_gen.m:
	Conform to the changes above.

doc/reference_manual.texi:
	Document the new foreign_proc attribute.

library/array.m:
library/builtin.m:
library/char.m:
library/dir.m:
library/float.m:
library/int.m:
library/io.m:
library/lexer.m:
library/math.m:
library/private_builtin.m:
library/string.m:
library/version_array.m:
	Add does_not_affect_liveness annotations to the C foreign_procs that
	deserve them.

configure.in:
	Require the installed compiler to support does_not_affect_liveness.

tests/invalid/test_may_duplicate.{m,err_exp}:
	Add a new test case to test the error checking code in simplify.m.

tests/invalid/Mmakefile:
	Enable the new test case.
This commit is contained in:
Zoltan Somogyi
2007-01-15 02:24:04 +00:00
parent 7651d83206
commit 7b7dabb89a
34 changed files with 1522 additions and 851 deletions

View File

@@ -605,14 +605,14 @@ dump_proclabel(ProcLabel) = Str :-
PredModuleName = sym_name_mangle(PredModule),
ExtraModule = PredModuleName ++ "_"
),
Str = ExtraModule ++ sym_name_mangle(Module) ++ "_" ++ PredName ++ "_"
++ int_to_string(Arity) ++ "_" ++ int_to_string(Mode)
Str = ExtraModule ++ sym_name_mangle(Module) ++ "__" ++ PredName
++ "_" ++ int_to_string(Arity) ++ "_" ++ int_to_string(Mode)
;
ProcLabel = special_proc_label(Module, SpecialPredId, TypeModule,
TypeName, TypeArity, Mode),
TypeCtor = type_ctor(qualified(TypeModule, TypeName), TypeArity),
Str = sym_name_mangle(Module) ++ "_"
Str = sym_name_mangle(Module) ++ "__"
++ special_pred_name(SpecialPredId, TypeCtor) ++ "_"
++ qualify_name(sym_name_mangle(TypeModule), TypeName) ++ "_"
++ int_to_string(TypeArity) ++ "_" ++ int_to_string(Mode)
@@ -802,7 +802,7 @@ dump_instr(ProcLabel, PrintComments, Instr) = Str :-
++ dump_maybe_label("fix onlylayout:", MaybeProcLabel, MFOL)
++ dump_maybe_label("nofix:", MaybeProcLabel, MNF)
++ dump_bool_msg("stack slot ref:", SSR)
++ dump_bool_msg("may duplicate:", MD)
++ dump_may_duplicate(MD) ++ "\n"
++ ")"
).
@@ -822,6 +822,11 @@ dump_maybe_label(Msg, MaybeProcLabel, yes(Label)) =
dump_bool_msg(Msg, no) = Msg ++ " no\n".
dump_bool_msg(Msg, yes) = Msg ++ " yes\n".
:- func dump_may_duplicate(proc_may_duplicate) = string.
dump_may_duplicate(proc_may_duplicate) = "may_duplicate".
dump_may_duplicate(proc_may_not_duplicate) = "may_not_duplicate".
:- func dump_may_use_atomic(may_use_atomic_alloc) = string.
dump_may_use_atomic(may_use_atomic_alloc) = "may_use_atomic_alloc".
@@ -855,18 +860,28 @@ dump_component(MaybeProcLabel, foreign_proc_inputs(Inputs)) =
dump_component(MaybeProcLabel, foreign_proc_outputs(Outputs)) =
dump_output_components(MaybeProcLabel, Outputs).
dump_component(_, foreign_proc_user_code(_, AL, Code)) =
dump_affects_liveness(AL) ++ "\n" ++ Code ++ "\n".
( Code = "" ->
"empty user_code: " ++ dump_affects_liveness(AL) ++ "\n"
;
"user_code: " ++ dump_affects_liveness(AL) ++ "\n" ++ Code ++ "\n"
).
dump_component(_, foreign_proc_raw_code(_, AL, _, Code)) =
dump_affects_liveness(AL) ++ "\n" ++ Code ++ "\n".
( Code = "" ->
"empty raw_code: " ++ dump_affects_liveness(AL) ++ "\n"
;
"raw_code:\n" ++ dump_affects_liveness(AL) ++ "\n" ++ Code ++ "\n"
).
dump_component(MaybeProcLabel, foreign_proc_fail_to(Label)) =
"fail to " ++ dump_label(MaybeProcLabel, Label) ++ "\n".
dump_component(_, foreign_proc_noop) = "".
:- func dump_affects_liveness(affects_liveness) = string.
:- func dump_affects_liveness(proc_affects_liveness) = string.
dump_affects_liveness(affects_liveness) = "affects_liveness".
dump_affects_liveness(does_not_affect_liveness) = "does_not_affect_liveness".
dump_affects_liveness(default_affects_liveness) = "default_affects_liveness".
dump_affects_liveness(proc_affects_liveness) = "affects_liveness".
dump_affects_liveness(proc_does_not_affect_liveness) =
"does_not_affect_liveness".
dump_affects_liveness(proc_default_affects_liveness) =
"default_affects_liveness".
:- func dump_input_components(maybe(proc_label), list(foreign_proc_input))
= string.