diff --git a/compiler/continuation_info.m b/compiler/continuation_info.m index 3f72c123b..58ac6a137 100644 --- a/compiler/continuation_info.m +++ b/compiler/continuation_info.m @@ -62,6 +62,7 @@ :- import_module hlds.instmap. :- import_module hlds.pred_proc_id. :- import_module hlds.proc_info_types. +:- import_module hlds.proc_table_struct. :- import_module libs. :- import_module libs.globals. :- import_module libs.trace_params. diff --git a/compiler/hlds.m b/compiler/hlds.m index 30940f4c1..e1988df21 100644 --- a/compiler/hlds.m +++ b/compiler/hlds.m @@ -39,6 +39,7 @@ :- include_module pred_proc_id. :- include_module pred_table. :- include_module proc_info_types. +:- include_module proc_table_struct. :- include_module special_pred. :- include_module status. diff --git a/compiler/hlds_module.m b/compiler/hlds_module.m index c859935b5..ec65e4873 100644 --- a/compiler/hlds_module.m +++ b/compiler/hlds_module.m @@ -35,6 +35,7 @@ :- import_module hlds.pred_proc_id. :- import_module hlds.pred_table. :- import_module hlds.proc_info_types. +:- import_module hlds.proc_table_struct. :- import_module hlds.special_pred. :- import_module hlds.status. :- import_module libs. diff --git a/compiler/hlds_out_module.m b/compiler/hlds_out_module.m index 6f05ae124..7cf50856c 100644 --- a/compiler/hlds_out_module.m +++ b/compiler/hlds_out_module.m @@ -121,6 +121,7 @@ :- import_module hlds.pred_name. :- import_module hlds.pred_proc_id. :- import_module hlds.proc_info_types. +:- import_module hlds.proc_table_struct. :- import_module libs. :- import_module libs.dependency_graph. :- import_module libs.globals. diff --git a/compiler/hlds_proc.m b/compiler/hlds_proc.m index b8454212d..f7477942c 100644 --- a/compiler/hlds_proc.m +++ b/compiler/hlds_proc.m @@ -204,8 +204,6 @@ maybe(mode_constraint)::out) is det. :- pred proc_info_get_cse_nopull_contexts(proc_info::in, list(prog_context)::out) is det. -:- pred proc_info_get_maybe_untuple_info(proc_info::in, - maybe(untuple_proc_info)::out) is det. :- pred proc_info_get_var_name_remap(proc_info::in, map(prog_var, string)::out) is det. :- pred proc_info_get_statevar_warnings(proc_info::in, @@ -222,12 +220,16 @@ has_parallel_conj::out) is det. :- pred proc_info_get_has_user_event(proc_info::in, has_user_event::out) is det. +:- pred proc_info_get_needs_maxfr_slot(proc_info::in, + needs_maxfr_slot::out) is det. :- pred proc_info_get_has_tail_rec_call(proc_info::in, has_tail_rec_call::out) is det. :- pred proc_info_get_oisu_kind_fors(proc_info::in, list(oisu_pred_kind_for)::out) is det. :- pred proc_info_get_maybe_require_tailrec_info(proc_info::in, maybe(require_tail_recursion)::out) is det. +:- pred proc_info_get_obsolete_in_favour_of(proc_info::in, + maybe(list(sym_name_arity))::out) is det. :- pred proc_info_get_reg_r_headvars(proc_info::in, set_of_progvar::out) is det. :- pred proc_info_get_maybe_arg_info(proc_info::in, @@ -237,18 +239,16 @@ :- pred proc_info_get_initial_liveness(proc_info::in, codegen_liveness::out) is det. :- pred proc_info_get_stack_slots(proc_info::in, stack_slots::out) is det. -:- pred proc_info_get_needs_maxfr_slot(proc_info::in, - needs_maxfr_slot::out) is det. :- pred proc_info_get_call_table_tip(proc_info::in, maybe(prog_var)::out) is det. :- pred proc_info_get_maybe_proc_table_io_info(proc_info::in, maybe(proc_table_io_info)::out) is det. :- pred proc_info_get_table_attributes(proc_info::in, maybe(table_attributes)::out) is det. -:- pred proc_info_get_obsolete_in_favour_of(proc_info::in, - maybe(list(sym_name_arity))::out) is det. :- pred proc_info_get_maybe_deep_profile_info(proc_info::in, maybe(deep_profile_proc_info)::out) is det. +:- pred proc_info_get_maybe_untuple_info(proc_info::in, + maybe(untuple_proc_info)::out) is det. :- pred proc_info_get_maybe_arg_size_info(proc_info::in, maybe(arg_size_info)::out) is det. :- pred proc_info_get_maybe_termination_info(proc_info::in, @@ -287,8 +287,6 @@ proc_info::in, proc_info::out) is det. :- pred proc_info_set_cse_nopull_contexts(list(prog_context)::in, proc_info::in, proc_info::out) is det. -:- pred proc_info_set_maybe_untuple_info(maybe(untuple_proc_info)::in, - proc_info::in, proc_info::out) is det. :- pred proc_info_set_var_name_remap(map(prog_var, string)::in, proc_info::in, proc_info::out) is det. :- pred proc_info_set_statevar_warnings(list(warn_spec)::in, @@ -307,12 +305,16 @@ proc_info::in, proc_info::out) is det. :- pred proc_info_set_has_user_event(has_user_event::in, proc_info::in, proc_info::out) is det. +:- pred proc_info_set_needs_maxfr_slot(needs_maxfr_slot::in, + proc_info::in, proc_info::out) is det. :- pred proc_info_set_has_tail_rec_call(has_tail_rec_call::in, proc_info::in, proc_info::out) is det. :- pred proc_info_set_oisu_kind_fors(list(oisu_pred_kind_for)::in, proc_info::in, proc_info::out) is det. :- pred proc_info_set_require_tailrec_info(require_tail_recursion::in, proc_info::in, proc_info::out) is det. +:- pred proc_info_set_obsolete_in_favour_of(maybe(list(sym_name_arity))::in, + proc_info::in, proc_info::out) is det. :- pred proc_info_set_reg_r_headvars(set_of_progvar::in, proc_info::in, proc_info::out) is det. :- pred proc_info_set_arg_info(list(arg_info)::in, @@ -323,20 +325,17 @@ proc_info::in, proc_info::out) is det. :- pred proc_info_set_stack_slots(stack_slots::in, proc_info::in, proc_info::out) is det. -:- pred proc_info_set_needs_maxfr_slot(needs_maxfr_slot::in, - proc_info::in, proc_info::out) is det. :- pred proc_info_set_call_table_tip(maybe(prog_var)::in, proc_info::in, proc_info::out) is det. :- pred proc_info_set_maybe_proc_table_io_info(maybe(proc_table_io_info)::in, proc_info::in, proc_info::out) is det. :- pred proc_info_set_table_attributes(maybe(table_attributes)::in, proc_info::in, proc_info::out) is det. -:- pred proc_info_set_obsolete_in_favour_of( - maybe(list(sym_name_arity))::in, - proc_info::in, proc_info::out) is det. :- pred proc_info_set_maybe_deep_profile_info( maybe(deep_profile_proc_info)::in, proc_info::in, proc_info::out) is det. +:- pred proc_info_set_maybe_untuple_info(maybe(untuple_proc_info)::in, + proc_info::in, proc_info::out) is det. :- pred proc_info_set_maybe_arg_size_info(maybe(arg_size_info)::in, proc_info::in, proc_info::out) is det. :- pred proc_info_set_maybe_termination_info(maybe(termination_info)::in, @@ -393,7 +392,6 @@ proc_info_create_with_declared_detism(MainContext, ItemNumber, CanProcess = can_process_now, % argument DetismDecl CseNopullContexts = [], - MaybeUntupleInfo = no `with_type` maybe(untuple_proc_info), % argument VarNameRemap StateVarWarnings = [], set.init(DeletedCallees), @@ -405,6 +403,7 @@ proc_info_create_with_declared_detism(MainContext, ItemNumber, has_no_mutual_tail_rec_call), OisuKinds = [], MaybeRequireTailRecursion = no, + MaybeObsoleteInFavourOf = no `with_type` maybe(list(sym_name_arity)), set_of_var.init(RegR_HeadVars), MaybeArgPassInfo = no `with_type` maybe(list(arg_info)), MaybeSpecialReturn = no `with_type` maybe(special_proc_return), @@ -414,8 +413,8 @@ proc_info_create_with_declared_detism(MainContext, ItemNumber, MaybeCallTableTip = no `with_type` maybe(prog_var), MaybeTableIOInfo = no `with_type` maybe(proc_table_io_info), MaybeTableAttrs = no `with_type` maybe(table_attributes), - MaybeObsoleteInFavourOf = no `with_type` maybe(list(sym_name_arity)), MaybeDeepProfProcInfo = no `with_type` maybe(deep_profile_proc_info), + MaybeUntupleInfo = no `with_type` maybe(untuple_proc_info), MaybeArgSizes = no `with_type` maybe(arg_size_info), MaybeTermInfo = no `with_type` maybe(termination_info), Term2Info = term_constr_main_types.term2_info_init, @@ -430,7 +429,6 @@ proc_info_create_with_declared_detism(MainContext, ItemNumber, ItemNumber, MaybeHeadModesConstr, CseNopullContexts, - MaybeUntupleInfo, VarNameRemap, StateVarWarnings, DeletedCallees, @@ -440,20 +438,21 @@ proc_info_create_with_declared_detism(MainContext, ItemNumber, HasForeignProcExports, HasParallelConj, HasUserEvent, + NeedsMaxfrSlot, HasTailCallEvent, OisuKinds, MaybeRequireTailRecursion, + MaybeObsoleteInFavourOf, RegR_HeadVars, MaybeArgPassInfo, MaybeSpecialReturn, InitialLiveness, StackSlots, - NeedsMaxfrSlot, MaybeCallTableTip, MaybeTableIOInfo, MaybeTableAttrs, - MaybeObsoleteInFavourOf, MaybeDeepProfProcInfo, + MaybeUntupleInfo, MaybeArgSizes, MaybeTermInfo, Term2Info, @@ -555,7 +554,6 @@ proc_info_init(ModuleInfo, MainContext, ItemNumber, Types, InstVarSet, ItemNumber, MaybeHeadModesConstr, CseNopullContexts, - MaybeUntupleInfo, VarNameRemap, StateVarWarnings, DeletedCallees, @@ -565,20 +563,21 @@ proc_info_init(ModuleInfo, MainContext, ItemNumber, Types, InstVarSet, HasForeignProcExports, HasParallelConj, HasUserEvent, + NeedsMaxfrSlot, HasTailCallEvent, OisuKinds, MaybeRequireTailRecursion, + MaybeObsoleteInFavourOf, RegR_HeadVars, MaybeArgPassInfo, MaybeSpecialReturn, InitialLiveness, StackSlots, - NeedsMaxfrSlot, MaybeCallTableTip, MaybeTableIOInfo, MaybeTableAttrs, - MaybeObsoleteInFavourOf, MaybeDeepProfProcInfo, + MaybeUntupleInfo, MaybeArgSizes, MaybeTermInfo, Term2Info, @@ -678,7 +677,6 @@ proc_prepare_to_clone(ProcInfo, HeadVars, Goal, VarTable, RttiVarMaps, ItemNumber, MaybeHeadModesConstr, CseNopullContexts, - MaybeUntupleInfo, VarNameRemap, StateVarWarnings, DeletedCallees, @@ -688,20 +686,21 @@ proc_prepare_to_clone(ProcInfo, HeadVars, Goal, VarTable, RttiVarMaps, HasForeignProcExports, HasParallelConj, HasUserEvent, + NeedsMaxfrSlot, HasTailCallEvent, OisuKinds, MaybeRequireTailRecursion, + MaybeObsoleteInFavourOf, RegR_HeadVars, MaybeArgPassInfo, MaybeSpecialReturn, InitialLiveness, StackSlots, - NeedsMaxfrSlot, MaybeCallTableTip, MaybeTableIOInfo, MaybeTableAttrs, - MaybeObsoleteInFavourOf, MaybeDeepProfProcInfo, + MaybeUntupleInfo, MaybeArgSizes, MaybeTermInfo, Term2Info, @@ -729,7 +728,6 @@ proc_create(HeadVars, Goal, VarTable, RttiVarMaps, ItemNumber, MaybeHeadModesConstr, CseNopullContexts, - MaybeUntupleInfo, VarNameRemap, StateVarWarnings, DeletedCallees, @@ -739,20 +737,21 @@ proc_create(HeadVars, Goal, VarTable, RttiVarMaps, HasForeignProcExports, HasParallelConj, HasUserEvent, + NeedsMaxfrSlot, HasTailCallEvent, OisuKinds, MaybeRequireTailRecursion, + MaybeObsoleteInFavourOf, RegR_HeadVars, MaybeArgPassInfo, MaybeSpecialReturn, InitialLiveness, StackSlots, - NeedsMaxfrSlot, MaybeCallTableTip, MaybeTableIOInfo, MaybeTableAttrs, - MaybeObsoleteInFavourOf, MaybeDeepProfProcInfo, + MaybeUntupleInfo, MaybeArgSizes, MaybeTermInfo, Term2Info, @@ -911,15 +910,6 @@ proc_info_reset_imported_structure_reuse(!ProcInfo) :- % See Mantis bug #496. psi_cse_nopull_contexts :: list(prog_context), - % If set, it means this procedure was created from another - % procedure by the untupling transformation. This slot records - % which of the procedure's arguments were derived from which - % arguments in the original procedure. - % - % This is effectively a record of the *procedure*'s origin. - % (The pred_origin field records the *predicate*'s origin.) - psi_maybe_untuple_info :: maybe(untuple_proc_info), - % Remaps the compiler-created variables named HeadVar__N % to the user-given variable names that actually occupied the % corresponding argument slots in the procedure's clauses. @@ -996,8 +986,21 @@ proc_info_reset_imported_structure_reuse(!ProcInfo) :- % This slot is set by the simplification pass. psi_proc_has_user_event :: has_user_event, + % True iff tracing is enabled, this is a procedure that lives + % on the det stack, and the code of this procedure may create + % a frame on the det stack. (Only in these circumstances do we + % need to reserve a stack slot to hold the value of maxfr + % at the call, for use in implementing retry.) This slot + % is used only with the LLDS backend XXX. Its value is set + % during the live_vars pass; it is invalid before then. + psi_needs_maxfr_slot :: needs_maxfr_slot, + psi_proc_has_tail_rec_call :: has_tail_rec_call, + %-----------------------------------------------------------% + % Information about pragmas. + %-----------------------------------------------------------% + % Is the procedure mentioned in any order-independent-state- % update pragmas? If yes, list the role of this procedure % for the each of the types in those pragmas. @@ -1008,6 +1011,14 @@ proc_info_reset_imported_structure_reuse(!ProcInfo) :- % recursion for this procedure? psi_maybe_require_tailrec :: maybe(require_tail_recursion), + % If this procedure is marked as obsolete, this will be a + % "yes(_)" wrapped around a list of the predicate names that + % the compiler should suggest as possible replacements. + % (Note that the list of possible replacements may be empty.) + % In the usual case where this predicate is NOT marked + % as obsolete, this will be "no". + psi_proc_obsolete_in_favour_of :: maybe(list(sym_name_arity)), + %-----------------------------------------------------------% % Information needed by the LLDS code generator. %-----------------------------------------------------------% @@ -1030,15 +1041,6 @@ proc_info_reset_imported_structure_reuse(!ProcInfo) :- % Allocation of variables to stack slots. psi_stack_slots :: stack_slots, - % True iff tracing is enabled, this is a procedure that lives - % on the det stack, and the code of this procedure may create - % a frame on the det stack. (Only in these circumstances do we - % need to reserve a stack slot to hold the value of maxfr - % at the call, for use in implementing retry.) This slot - % is used only with the LLDS backend XXX. Its value is set - % during the live_vars pass; it is invalid before then. - psi_needs_maxfr_slot :: needs_maxfr_slot, - %-----------------------------------------------------------% % Information needed for tabling. %-----------------------------------------------------------% @@ -1076,15 +1078,6 @@ proc_info_reset_imported_structure_reuse(!ProcInfo) :- psi_table_attributes :: maybe(table_attributes), - % If this procedure is marked as obsolete, this will be a - % "yes(_)" wrapped around a list of the predicate names that - % the compiler should suggest as possible replacements. - % (Note that the list of possible replacements may be empty.) - % In the usual case where this predicate is NOT marked - % as obsolete, this will be "no". - psi_proc_obsolete_in_favour_of :: maybe(list( - sym_name_arity)), - %-----------------------------------------------------------% % Information needed for deep profiling. %-----------------------------------------------------------% @@ -1095,9 +1088,18 @@ proc_info_reset_imported_structure_reuse(!ProcInfo) :- % The results of program analyses. %-----------------------------------------------------------% + % If set, it means this procedure was created from another + % procedure by the untupling transformation. This slot records + % which of the procedure's arguments were derived from which + % arguments in the original procedure. + % + % This is effectively a record of the *procedure*'s origin. + % (The pred_origin field records the *predicate*'s origin.) + psi_maybe_untuple_info :: maybe(untuple_proc_info), + % Information about the relative sizes of the input and output % args of the procedure. Set by termination analysis. - psi_maybe_arg_sizes :: maybe(arg_size_info), + psi_maybe_arg_size_infos :: maybe(arg_size_info), % The termination properties of the procedure. % Set by termination analysis. @@ -1153,8 +1155,6 @@ proc_info_get_maybe_head_modes_constr(PI, X) :- X = PI ^ proc_sub_info ^ psi_maybe_head_modes_constr. proc_info_get_cse_nopull_contexts(PI, X) :- X = PI ^ proc_sub_info ^ psi_cse_nopull_contexts. -proc_info_get_maybe_untuple_info(PI, X) :- - X = PI ^ proc_sub_info ^ psi_maybe_untuple_info. proc_info_get_var_name_remap(PI, X) :- X = PI ^ proc_sub_info ^ psi_proc_var_name_remap. proc_info_get_statevar_warnings(PI, X) :- @@ -1173,12 +1173,16 @@ proc_info_get_has_parallel_conj(PI, X) :- X = PI ^ proc_sub_info ^ psi_proc_has_parallel_conj. proc_info_get_has_user_event(PI, X) :- X = PI ^ proc_sub_info ^ psi_proc_has_user_event. +proc_info_get_needs_maxfr_slot(PI, X) :- + X = PI ^ proc_sub_info ^ psi_needs_maxfr_slot. proc_info_get_has_tail_rec_call(PI, X) :- X = PI ^ proc_sub_info ^ psi_proc_has_tail_rec_call. proc_info_get_oisu_kind_fors(PI, X) :- X = PI ^ proc_sub_info ^ psi_oisu_kind_fors. proc_info_get_maybe_require_tailrec_info(PI, X) :- X = PI ^ proc_sub_info ^ psi_maybe_require_tailrec. +proc_info_get_obsolete_in_favour_of(PI, X) :- + X = PI ^ proc_sub_info ^ psi_proc_obsolete_in_favour_of. proc_info_get_reg_r_headvars(PI, X) :- X = PI ^ proc_sub_info ^ psi_reg_r_headvars. proc_info_get_maybe_arg_info(PI, X) :- @@ -1189,20 +1193,18 @@ proc_info_get_initial_liveness(PI, X) :- X = PI ^ proc_sub_info ^ psi_initial_liveness. proc_info_get_stack_slots(PI, X) :- X = PI ^ proc_sub_info ^ psi_stack_slots. -proc_info_get_needs_maxfr_slot(PI, X) :- - X = PI ^ proc_sub_info ^ psi_needs_maxfr_slot. proc_info_get_call_table_tip(PI, X) :- X = PI ^ proc_sub_info ^ psi_call_table_tip. proc_info_get_maybe_proc_table_io_info(PI, X) :- X = PI ^ proc_sub_info ^ psi_maybe_table_io_info. proc_info_get_table_attributes(PI, X) :- X = PI ^ proc_sub_info ^ psi_table_attributes. -proc_info_get_obsolete_in_favour_of(PI, X) :- - X = PI ^ proc_sub_info ^ psi_proc_obsolete_in_favour_of. proc_info_get_maybe_deep_profile_info(PI, X) :- X = PI ^ proc_sub_info ^ psi_maybe_deep_prof_info. +proc_info_get_maybe_untuple_info(PI, X) :- + X = PI ^ proc_sub_info ^ psi_maybe_untuple_info. proc_info_get_maybe_arg_size_info(PI, X) :- - X = PI ^ proc_sub_info ^ psi_maybe_arg_sizes. + X = PI ^ proc_sub_info ^ psi_maybe_arg_size_infos. proc_info_get_maybe_termination_info(PI, X) :- X = PI ^ proc_sub_info ^ psi_maybe_termination. proc_info_get_termination2_info(PI, X) :- @@ -1239,8 +1241,6 @@ proc_info_set_head_modes_constraint(X, !PI) :- !PI ^ proc_sub_info ^ psi_maybe_head_modes_constr := yes(X). proc_info_set_cse_nopull_contexts(X, !PI) :- !PI ^ proc_sub_info ^ psi_cse_nopull_contexts := X. -proc_info_set_maybe_untuple_info(X, !PI) :- - !PI ^ proc_sub_info ^ psi_maybe_untuple_info := X. proc_info_set_var_name_remap(X, !PI) :- !PI ^ proc_sub_info ^ psi_proc_var_name_remap := X. proc_info_set_statevar_warnings(X, !PI) :- @@ -1259,12 +1259,16 @@ proc_info_set_has_parallel_conj(X, !PI) :- !PI ^ proc_sub_info ^ psi_proc_has_parallel_conj := X. proc_info_set_has_user_event(X, !PI) :- !PI ^ proc_sub_info ^ psi_proc_has_user_event := X. +proc_info_set_needs_maxfr_slot(X, !PI) :- + !PI ^ proc_sub_info ^ psi_needs_maxfr_slot := X. proc_info_set_has_tail_rec_call(X, !PI) :- !PI ^ proc_sub_info ^ psi_proc_has_tail_rec_call := X. proc_info_set_oisu_kind_fors(X, !PI) :- !PI ^ proc_sub_info ^ psi_oisu_kind_fors := X. proc_info_set_require_tailrec_info(X, !PI) :- !PI ^ proc_sub_info ^ psi_maybe_require_tailrec := yes(X). +proc_info_set_obsolete_in_favour_of(X, !PI) :- + !PI ^ proc_sub_info ^ psi_proc_obsolete_in_favour_of := X. proc_info_set_reg_r_headvars(X, !PI) :- !PI ^ proc_sub_info ^ psi_reg_r_headvars := X. proc_info_set_arg_info(X, !PI) :- @@ -1275,20 +1279,18 @@ proc_info_set_initial_liveness(X, !PI) :- !PI ^ proc_sub_info ^ psi_initial_liveness := X. proc_info_set_stack_slots(X, !PI) :- !PI ^ proc_sub_info ^ psi_stack_slots := X. -proc_info_set_needs_maxfr_slot(X, !PI) :- - !PI ^ proc_sub_info ^ psi_needs_maxfr_slot := X. proc_info_set_call_table_tip(X, !PI) :- !PI ^ proc_sub_info ^ psi_call_table_tip := X. proc_info_set_maybe_proc_table_io_info(X, !PI) :- !PI ^ proc_sub_info ^ psi_maybe_table_io_info := X. proc_info_set_table_attributes(X, !PI) :- !PI ^ proc_sub_info ^ psi_table_attributes := X. -proc_info_set_obsolete_in_favour_of(X, !PI) :- - !PI ^ proc_sub_info ^ psi_proc_obsolete_in_favour_of := X. proc_info_set_maybe_deep_profile_info(X, !PI) :- !PI ^ proc_sub_info ^ psi_maybe_deep_prof_info := X. +proc_info_set_maybe_untuple_info(X, !PI) :- + !PI ^ proc_sub_info ^ psi_maybe_untuple_info := X. proc_info_set_maybe_arg_size_info(X, !PI) :- - !PI ^ proc_sub_info ^ psi_maybe_arg_sizes := X. + !PI ^ proc_sub_info ^ psi_maybe_arg_size_infos := X. proc_info_set_maybe_termination_info(X, !PI) :- !PI ^ proc_sub_info ^ psi_maybe_termination := X. proc_info_set_termination2_info(X, !PI) :- diff --git a/compiler/llds.m b/compiler/llds.m index 9fdd98c18..042fb2699 100644 --- a/compiler/llds.m +++ b/compiler/llds.m @@ -29,6 +29,7 @@ :- import_module hlds.hlds_module. :- import_module hlds.pred_proc_id. :- import_module hlds.proc_info_types. +:- import_module hlds.proc_table_struct. :- import_module libs. :- import_module libs.trace_params. :- import_module ll_backend.layout. diff --git a/compiler/llds_out_global.m b/compiler/llds_out_global.m index 001bafc6c..7eb95abdc 100644 --- a/compiler/llds_out_global.m +++ b/compiler/llds_out_global.m @@ -59,7 +59,7 @@ :- import_module backend_libs.c_util. :- import_module backend_libs.name_mangle. :- import_module backend_libs.rtti. -:- import_module hlds.proc_info_types. +:- import_module hlds.proc_table_struct. :- import_module ll_backend.llds_out.llds_out_data. :- import_module mdbcomp. :- import_module mdbcomp.prim_data. diff --git a/compiler/ml_top_gen.m b/compiler/ml_top_gen.m index 901212e6d..8be50720e 100644 --- a/compiler/ml_top_gen.m +++ b/compiler/ml_top_gen.m @@ -41,6 +41,7 @@ :- import_module hlds.hlds_pred. :- import_module hlds.pred_proc_id. :- import_module hlds.proc_info_types. +:- import_module hlds.proc_table_struct. :- import_module libs. :- import_module libs.globals. :- import_module libs.options. diff --git a/compiler/notes/compiler_design.html b/compiler/notes/compiler_design.html index fffa0defe..92ab911b3 100644 --- a/compiler/notes/compiler_design.html +++ b/compiler/notes/compiler_design.html @@ -889,6 +889,8 @@ about the properties of predicates and functions. hlds_module.m defines the top-level parts of the HLDS, including the type module_info.
  • +proc_table_struct.m defines types that represent tabled procedures. +
  • status.m defines the type that records the import/export status of entities such as types, insts, modes, and predicates.
  • diff --git a/compiler/proc_gen.m b/compiler/proc_gen.m index ade9d943e..fce111a8e 100644 --- a/compiler/proc_gen.m +++ b/compiler/proc_gen.m @@ -79,6 +79,7 @@ :- import_module hlds.instmap. :- import_module hlds.pred_name. :- import_module hlds.proc_info_types. +:- import_module hlds.proc_table_struct. :- import_module libs. :- import_module libs.file_util. :- import_module libs.globals. diff --git a/compiler/proc_info_types.m b/compiler/proc_info_types.m index 8259eb03e..14e774470 100644 --- a/compiler/proc_info_types.m +++ b/compiler/proc_info_types.m @@ -24,8 +24,8 @@ :- import_module hlds.instmap. :- import_module hlds.pred_proc_id. :- import_module mdbcomp. -:- import_module mdbcomp.goal_path. -:- import_module mdbcomp.program_representation. +:- import_module mdbcomp.goal_path. % for forward_goal_path +:- import_module mdbcomp.program_representation. % for coverage_point_info :- import_module parse_tree. :- import_module parse_tree.prog_data. :- import_module parse_tree.prog_data_pragma. @@ -40,15 +40,154 @@ %---------------------------------------------------------------------------% +:- type can_process + ---> cannot_process_yet + ; can_process_now. + + % Values of this type are used only for choosing the wording of + % determinism diagnostics. +:- type detism_decl + ---> detism_decl_explicit + ; detism_decl_implicit + % The determinism of the procedure is not declared, + % but the procedure needs no declaration, because either + % + % - the procedure is for a function, which are implicitly det + % unless explicitly declared otherwise, or + % + % - the procedure was created by the compiler, e.g. + % to implement a unify/index/compare predicate, + % to implement an instance method, or as implied mode. + ; detism_decl_none. + % The determinism of the procedure is not declared. + +:- type is_address_taken + ---> address_is_taken + ; address_is_not_taken. + + % Is a procedure the subject of any foreign_export pragmas? + % +:- type proc_foreign_exports + ---> no_foreign_exports + ; has_foreign_exports. + +:- type has_parallel_conj + ---> has_parallel_conj + ; has_no_parallel_conj. + +:- type has_user_event + ---> has_user_event + ; has_no_user_event. + +:- type needs_maxfr_slot + ---> needs_maxfr_slot + ; does_not_need_maxfr_slot. + +%---------------------% + +:- type has_tail_rec_call + ---> has_tail_rec_call( + has_self_tail_rec_call, + has_mutual_tail_rec_call + ). + +:- type has_self_tail_rec_call + ---> has_self_tail_rec_call + ; has_no_self_tail_rec_call. + +:- type has_mutual_tail_rec_call + ---> has_mutual_tail_rec_call + ; has_no_mutual_tail_rec_call. + +%---------------------------------------------------------------------------% + +:- type oisu_pred_kind_for + ---> oisu_creator_for(type_ctor) + ; oisu_mutator_for(type_ctor) + ; oisu_destructor_for(type_ctor). + % NOTE: `codegen_liveness' records liveness in the sense used by code % generation. This is *not* the same thing as the notion of liveness % used by mode analysis! See compiler/notes/glossary.html. % :- type codegen_liveness == set_of_progvar. % The live variables. -:- type is_address_taken - ---> address_is_taken - ; address_is_not_taken. +%---------------------------------------------------------------------------% + +:- type special_proc_return + ---> generator_return( + % The generator is stored in this location. We can't use an + % rval to represent the location, since we don't want this + % module to depend on the ll_backend package. + generator_rval :: string, + + % What should we pass as the value of the debug parameter + % in the call to MR_tbl_mmos_return_answer? + return_debug :: string + ). + +%---------------------% + +:- type proc_table_io_info + ---> proc_table_io_info( + % The information we need to display an I/O action to the user. + % + % The table_arg_infos correspond one to one to the elements + % of the block saved for an I/O action. The first element + % will be the pointer to the proc_layout of the action's + % procedure. + % + % The right tvarset for interpreting the types in the + % table_arg_infos is the one in the proc_info in which + % the proc_table_io_info is stored. + + maybe(table_arg_infos) + ). + +:- type table_arg_infos + ---> table_arg_infos( + list(table_arg_info), + map(tvar, table_locn) + ). + +:- type table_arg_info + ---> table_arg_info( + orig_var_num :: int, + orig_var_name :: string, + slot_num :: int, + arg_type :: mer_type + ). + + % This type is analogous to layout_locn in llds.m, but it refers + % not to lvals, but to slots in the extended answer blocks used by + % I/O action tabling for declarative debugging. +:- type table_locn + ---> table_locn_direct(int) + ; table_locn_indirect(int, int). + +%---------------------------------------------------------------------------% + +:- type deep_profile_proc_info + ---> deep_profile_proc_info( + % This field is set during the first part of the deep profiling + % transformation; tail recursion, if that is enabled. + deep_rec :: maybe(deep_recursion_info), + + % This field is set during the second part; it will be bound + % to `no' before and during the first part, and to `yes' + % after the second. The contents of this field govern + % what will go into MR_ProcStatic structures. + deep_layout :: maybe(hlds_deep_layout), + + % This field stores the original body of a procedure, + % before either part of the deep profiling transformation + % was executed. For inner procedures created by the tail + % recursion part of the deep profiling transformation, + % it holds the original body of the outer procedure. + deep_orig_body :: deep_original_body + ). + +%---------------------% :- type deep_recursion_info ---> deep_recursion_info( @@ -79,6 +218,25 @@ rec_call_sites :: list(int) ). +%---------------------% + +:- type hlds_deep_layout + ---> hlds_deep_layout( + deep_layout_static :: hlds_proc_static, + deep_layout_excp :: hlds_deep_excp_vars + ). + +%---------------------% + +:- type hlds_proc_static + ---> hlds_proc_static( % defines part of MR_ProcStatic + proc_static_file_name :: string, + proc_static_line_number :: int, + proc_is_in_interface :: bool, + call_site_statics :: list(call_site_static_data), + coverage_points :: list(coverage_point_info) + ). + :- type call_site_static_data % defines MR_CallSiteStatic ---> normal_call( normal_callee :: rtti_proc_label, @@ -108,15 +266,6 @@ callback_goal_path :: forward_goal_path ). -:- type hlds_proc_static - ---> hlds_proc_static( % defines part of MR_ProcStatic - proc_static_file_name :: string, - proc_static_line_number :: int, - proc_is_in_interface :: bool, - call_site_statics :: list(call_site_static_data), - coverage_points :: list(coverage_point_info) - ). - % The hlds_deep_excp_vars gives the variables that hold the values returned % by the call port code, which are needed to let exception.throw perform % the work we need to do at the excp port. @@ -130,31 +279,7 @@ old_outermost :: maybe(prog_var) ). -:- type hlds_deep_layout - ---> hlds_deep_layout( - deep_layout_static :: hlds_proc_static, - deep_layout_excp :: hlds_deep_excp_vars - ). - -:- type deep_profile_proc_info - ---> deep_profile_proc_info( - % This field is set during the first part of the deep profiling - % transformation; tail recursion, if that is enabled. - deep_rec :: maybe(deep_recursion_info), - - % This field is set during the second part; it will be bound - % to `no' before and during the first part, and to `yes' - % after the second. The contents of this field govern - % what will go into MR_ProcStatic structures. - deep_layout :: maybe(hlds_deep_layout), - - % This field stores the original body of a procedure, - % before either part of the deep profiling transformation - % was executed. For inner procedures created by the tail - % recursion part of the deep profiling transformation, - % it holds the original body of the outer procedure. - deep_orig_body :: deep_original_body - ). +%---------------------% :- type deep_original_body ---> deep_original_body( @@ -165,216 +290,14 @@ dob_detism :: determinism ). -:- type table_arg_infos - ---> table_arg_infos( - list(table_arg_info), - map(tvar, table_locn) - ). - -:- type table_arg_info - ---> table_arg_info( - orig_var_num :: int, - orig_var_name :: string, - slot_num :: int, - arg_type :: mer_type - ). - - % This type is analogous to layout_locn in llds.m, but it refers - % not to lvals, but to slots in the extended answer blocks used by - % I/O action tabling for declarative debugging. -:- type table_locn - ---> table_locn_direct(int) - ; table_locn_indirect(int, int). - - % This type differs from the type table_step_kind in table_statistics.m - % in the library in that - % (a) in gives more information about the type of the corresponding - % argument (if this info is needed and available), - % (b) it doesn't have to be an enum, and - % (c) it doesn't have to handle dummy steps. - % -:- type table_trie_step - ---> table_trie_step_dummy - ; table_trie_step_int(int_type) - ; table_trie_step_char - ; table_trie_step_string - ; table_trie_step_float - ; table_trie_step_enum( - % The int gives the maximum enum value in the enum type + 1, - % and thus the size of the corresponding trie node. - % If the enum type is not a subtype, then the value is equal to - % the number of alternatives in the type. - int - ) - ; table_trie_step_foreign_enum - ; table_trie_step_general( - mer_type, - table_is_poly, - table_value_or_addr - ) - ; table_trie_step_typeinfo - ; table_trie_step_typeclassinfo - ; table_trie_step_promise_implied. - -:- type table_is_poly - ---> table_is_mono % The table type is monomorphic. - ; table_is_poly. % The table type is polymorphic. - -:- type table_value_or_addr - ---> table_value % We are tabling the value itself. - ; table_addr. % We are tabling only the address. - - % Return a description of what kind of statistics we collect for a trie - % step of a given kind. The description is the name of a value in the C - % enum type MR_TableStepStatsKind. (We will need to generalize this - % when we implement tabling for non-C backends.) - % -:- func table_step_stats_kind(table_trie_step) = string. - -:- type proc_table_io_info - ---> proc_table_io_info( - % The information we need to display an I/O action to the user. - % - % The table_arg_infos correspond one to one to the elements - % of the block saved for an I/O action. The first element - % will be the pointer to the proc_layout of the action's - % procedure. - % - % The right tvarset for interpreting the types in the - % table_arg_infos is the one in the proc_info in which - % the proc_table_io_info is stored. - - maybe(table_arg_infos) - ). - -:- type table_step_desc - ---> table_step_desc( - tsd_var_name :: string, - tsd_step :: table_trie_step - ). - -:- type proc_table_struct_info - ---> proc_table_struct_info( - % The information we need to create the data structures - % created by tabling for a procedure, and to interpret them - % for the debugger (except the information -such as - % determinism- that is already available from proc_layout - % structures. - % - % The table_arg_infos list first all the input arguments, - % then all the output arguments. - % - % The right tvarset for interpreting the types in the - % table_arg_infos is the one stored below. It is taken from - % the proc_info of the procedure whose table this structure - % describes. Since we care only about the shapes of the types, - % we don't care about neither the actual numerical values - % nor the names of the type variables, so we don't care if - % the tvarset in that proc_info changes after table_gen.m - % takes the snapshot stored here. - % - % We record the rtti_proc_label of the procedure whose table - % this is. We can't record its identity in the form of a - % pred_proc_id, since that won't work if the procedure is - % deleted before the code generation phase. - - ptsi_proc_label :: rtti_proc_label, - ptsi_tvarset :: tvarset, - ptsi_context :: prog_context, - ptsi_num_inputs :: int, - ptsi_num_outputs :: int, - ptsi_input_steps :: list(table_step_desc), - ptsi_maybe_output_steps :: maybe(list(table_step_desc)), - ptsi_gen_arg_infos :: table_arg_infos, - ptsi_eval_method :: tabled_eval_method - ). - -:- type special_proc_return - ---> generator_return( - % The generator is stored in this location. We can't use an - % rval to represent the location, since we don't want this - % module to depend on the ll_backend package. - generator_rval :: string, - - % What should we pass as the value of the debug parameter - % in the call to MR_tbl_mmos_return_answer? - return_debug :: string - ). - -:- type structure_sharing_domain_and_status - ---> structure_sharing_domain_and_status( - structure_sharing_domain, - analysis_status - ). - -:- type structure_reuse_domain_and_status - ---> structure_reuse_domain_and_status( - structure_reuse_domain, - analysis_status - ). +%---------------------------------------------------------------------------% :- type untuple_proc_info ---> untuple_proc_info( map(prog_var, list(prog_var)) ). -:- type can_process - ---> cannot_process_yet - ; can_process_now. - - % Values of this type are used only for choosing the wording of - % determinism diagnostics. -:- type detism_decl - ---> detism_decl_explicit - ; detism_decl_implicit - % The determinism of the procedure is not declared, - % but the procedure needs no declaration, because either - % - % - the procedure is for a function, which are implicitly det - % unless explicitly declared otherwise, or - % - % - the procedure was created by the compiler, e.g. - % to implement a unify/index/compare predicate, - % to implement an instance method, or as implied mode. - ; detism_decl_none. - % The determinism of the procedure is not declared. - -:- type needs_maxfr_slot - ---> needs_maxfr_slot - ; does_not_need_maxfr_slot. - -:- type has_parallel_conj - ---> has_parallel_conj - ; has_no_parallel_conj. - -:- type has_user_event - ---> has_user_event - ; has_no_user_event. - -:- type has_self_tail_rec_call - ---> has_self_tail_rec_call - ; has_no_self_tail_rec_call. - -:- type has_mutual_tail_rec_call - ---> has_mutual_tail_rec_call - ; has_no_mutual_tail_rec_call. - -:- type has_tail_rec_call - ---> has_tail_rec_call( - has_self_tail_rec_call, - has_mutual_tail_rec_call - ). - -:- type oisu_pred_kind_for - ---> oisu_creator_for(type_ctor) - ; oisu_mutator_for(type_ctor) - ; oisu_destructor_for(type_ctor). - - % Is a procedure the subject of any foreign_export pragmas? - % -:- type proc_foreign_exports - ---> no_foreign_exports - ; has_foreign_exports. +%---------------------% % Gives an indication of whether or not the procedure % might throw an exception. @@ -385,6 +308,8 @@ proc_maybe_excep_analysis_status :: maybe(analysis_status) ). +%---------------------% + % Gives an indication of whether or not the procedure modifies the trail. % :- type proc_trailing_info @@ -393,6 +318,8 @@ proc_maybe_trail_analysis_status :: maybe(analysis_status) ). +%---------------------% + % Gives an indication of whether or not the procedure, or one of its % subgoals, calls a procedure that is tabled using minimal model tabling. :- type proc_mm_tabling_info @@ -408,6 +335,14 @@ proc_mm_analysis_status :: maybe(analysis_status) ). +%---------------------% + +:- type structure_sharing_domain_and_status + ---> structure_sharing_domain_and_status( + structure_sharing_domain, + analysis_status + ). + :- type structure_sharing_info ---> structure_sharing_info( maybe_sharing :: maybe(structure_sharing_domain_and_status), @@ -439,6 +374,16 @@ s_sharing :: structure_sharing_domain ). +:- func structure_sharing_info_init = structure_sharing_info. + +%---------------------% + +:- type structure_reuse_domain_and_status + ---> structure_reuse_domain_and_status( + structure_reuse_domain, + analysis_status + ). + :- type structure_reuse_info ---> structure_reuse_info( maybe_reuse :: maybe(structure_reuse_domain_and_status), @@ -464,55 +409,14 @@ r_reuse :: structure_reuse_domain ). -:- func structure_sharing_info_init = structure_sharing_info. - :- func structure_reuse_info_init = structure_reuse_info. %---------------------------------------------------------------------------% :- implementation. -:- import_module term. -:- import_module varset. - %---------------------------------------------------------------------------% -table_step_stats_kind(Step) = KindStr :- - ( - ( Step = table_trie_step_int(_) - ; Step = table_trie_step_char - ; Step = table_trie_step_string - ; Step = table_trie_step_float - ; Step = table_trie_step_typeinfo - ; Step = table_trie_step_typeclassinfo - ; Step = table_trie_step_foreign_enum - ), - KindStr = "MR_TABLE_STATS_DETAIL_HASH" - ; - Step = table_trie_step_enum(_), - KindStr = "MR_TABLE_STATS_DETAIL_ENUM" - ; - Step = table_trie_step_general(_Type, IsPoly, ValueOrAddr), - ( - ValueOrAddr = table_addr, - KindStr = "MR_TABLE_STATS_DETAIL_HASH" - ; - ValueOrAddr = table_value, - ( - IsPoly = table_is_mono, - KindStr = "MR_TABLE_STATS_DETAIL_DU" - ; - IsPoly = table_is_poly, - KindStr = "MR_TABLE_STATS_DETAIL_POLY" - ) - ) - ; - ( Step = table_trie_step_promise_implied - ; Step = table_trie_step_dummy - ), - KindStr = "MR_TABLE_STATS_DETAIL_NONE" - ). - structure_sharing_info_init = structure_sharing_info(no, no). structure_reuse_info_init = structure_reuse_info(no, no). diff --git a/compiler/proc_table_struct.m b/compiler/proc_table_struct.m new file mode 100644 index 000000000..2e1d86d74 --- /dev/null +++ b/compiler/proc_table_struct.m @@ -0,0 +1,164 @@ +%---------------------------------------------------------------------------% +% vim: ft=mercury ts=4 sw=4 et +%---------------------------------------------------------------------------% +% Copyright (C) 1996-2012 The University of Melbourne. +% Copyright (C) 2013-2026 The Mercury team. +% This file may only be copied under the terms of the GNU General +% Public License - see the file COPYING in the Mercury distribution. +%---------------------------------------------------------------------------% +% +% File: proc_table_struct.m. +% Main authors: fjh, conway. +% +% This module defines types that are specific to fields of proc_infos. +% +%---------------------------------------------------------------------------% + +:- module hlds.proc_table_struct. +:- interface. + +:- import_module hlds.hlds_rtti. +:- import_module hlds.proc_info_types. +:- import_module parse_tree. +:- import_module parse_tree.prog_data. +:- import_module parse_tree.prog_data_pragma. + +:- import_module list. +:- import_module maybe. + +%---------------------------------------------------------------------------% + +:- type proc_table_struct_info + ---> proc_table_struct_info( + % The information we need to create the data structures + % created by tabling for a procedure, and to interpret them + % for the debugger (except the information -such as + % determinism- that is already available from proc_layout + % structures. + % + % The table_arg_infos list first all the input arguments, + % then all the output arguments. + % + % The right tvarset for interpreting the types in the + % table_arg_infos is the one stored below. It is taken from + % the proc_info of the procedure whose table this structure + % describes. Since we care only about the shapes of the types, + % we don't care about neither the actual numerical values + % nor the names of the type variables, so we don't care if + % the tvarset in that proc_info changes after table_gen.m + % takes the snapshot stored here. + % + % We record the rtti_proc_label of the procedure whose table + % this is. We can't record its identity in the form of a + % pred_proc_id, since that won't work if the procedure is + % deleted before the code generation phase. + + ptsi_proc_label :: rtti_proc_label, + ptsi_tvarset :: tvarset, + ptsi_context :: prog_context, + ptsi_num_inputs :: int, + ptsi_num_outputs :: int, + ptsi_input_steps :: list(table_step_desc), + ptsi_maybe_output_steps :: maybe(list(table_step_desc)), + ptsi_gen_arg_infos :: table_arg_infos, + ptsi_eval_method :: tabled_eval_method + ). + +:- type table_step_desc + ---> table_step_desc( + tsd_var_name :: string, + tsd_step :: table_trie_step + ). + + % This type differs from the type table_step_kind in table_statistics.m + % in the library in that + % (a) in gives more information about the type of the corresponding + % argument (if this info is needed and available), + % (b) it doesn't have to be an enum, and + % (c) it doesn't have to handle dummy steps. + % +:- type table_trie_step + ---> table_trie_step_dummy + ; table_trie_step_int(int_type) + ; table_trie_step_char + ; table_trie_step_string + ; table_trie_step_float + ; table_trie_step_enum( + % The int gives the maximum enum value in the enum type + 1, + % and thus the size of the corresponding trie node. + % If the enum type is not a subtype, then the value is equal to + % the number of alternatives in the type. + int + ) + ; table_trie_step_foreign_enum + ; table_trie_step_general( + mer_type, + table_is_poly, + table_value_or_addr + ) + ; table_trie_step_typeinfo + ; table_trie_step_typeclassinfo + ; table_trie_step_promise_implied. + + % Return a description of what kind of statistics we collect for a trie + % step of a given kind. The description is the name of a value in the C + % enum type MR_TableStepStatsKind. (We will need to generalize this + % when we implement tabling for non-C backends.) + % +:- func table_step_stats_kind(table_trie_step) = string. + +:- type table_is_poly + ---> table_is_mono % The table type is monomorphic. + ; table_is_poly. % The table type is polymorphic. + +:- type table_value_or_addr + ---> table_value % We are tabling the value itself. + ; table_addr. % We are tabling only the address. + +%---------------------------------------------------------------------------% + +:- implementation. + +:- import_module varset. + +%---------------------------------------------------------------------------% + +table_step_stats_kind(Step) = KindStr :- + ( + ( Step = table_trie_step_int(_) + ; Step = table_trie_step_char + ; Step = table_trie_step_string + ; Step = table_trie_step_float + ; Step = table_trie_step_typeinfo + ; Step = table_trie_step_typeclassinfo + ; Step = table_trie_step_foreign_enum + ), + KindStr = "MR_TABLE_STATS_DETAIL_HASH" + ; + Step = table_trie_step_enum(_), + KindStr = "MR_TABLE_STATS_DETAIL_ENUM" + ; + Step = table_trie_step_general(_Type, IsPoly, ValueOrAddr), + ( + ValueOrAddr = table_addr, + KindStr = "MR_TABLE_STATS_DETAIL_HASH" + ; + ValueOrAddr = table_value, + ( + IsPoly = table_is_mono, + KindStr = "MR_TABLE_STATS_DETAIL_DU" + ; + IsPoly = table_is_poly, + KindStr = "MR_TABLE_STATS_DETAIL_POLY" + ) + ) + ; + ( Step = table_trie_step_promise_implied + ; Step = table_trie_step_dummy + ), + KindStr = "MR_TABLE_STATS_DETAIL_NONE" + ). + +%---------------------------------------------------------------------------% +:- end_module hlds.proc_table_struct. +%---------------------------------------------------------------------------% diff --git a/compiler/rtti.m b/compiler/rtti.m index ef051da13..fc81d68ee 100644 --- a/compiler/rtti.m +++ b/compiler/rtti.m @@ -29,7 +29,7 @@ :- import_module hlds. :- import_module hlds.hlds_rtti. -:- import_module hlds.proc_info_types. +:- import_module hlds.proc_table_struct. :- import_module libs. :- import_module libs.globals. :- import_module mdbcomp. diff --git a/compiler/table_gen.m b/compiler/table_gen.m index 80342efce..55cac20f5 100644 --- a/compiler/table_gen.m +++ b/compiler/table_gen.m @@ -79,6 +79,7 @@ :- import_module hlds.pred_proc_id. :- import_module hlds.pred_table. :- import_module hlds.proc_info_types. +:- import_module hlds.proc_table_struct. :- import_module hlds.status. :- import_module hlds.type_classify. :- import_module libs.