mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-06 07:49:02 +00:00
492 lines
19 KiB
Mathematica
492 lines
19 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2016, 2018-2020, 2022, 2024 The Mercury team.
|
|
% This file is distributed under the terms specified in COPYING.LIB.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% This module defines grade_vars, a representation for grades that allows
|
|
% the compiler to answer simple questions such as "should the generated high
|
|
% level C code use nested functions?" in a type safe manner. It provides
|
|
% a mechanism to convert solutions from the solver, which uses a different
|
|
% representation, to this representation.
|
|
%
|
|
% See compiler/notes/grade_library.html for documentation of the
|
|
% relationship between these representations, and their uses.
|
|
%
|
|
|
|
:- module grade_lib.grade_vars.
|
|
:- interface.
|
|
|
|
:- import_module grade_lib.grade_solver.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% This function translates the representation of a grade from a form
|
|
% which has just one type (solver_var_id) for all solver variables and
|
|
% just one type (solver_var_value_id) for all solver variable values,
|
|
% and translates it into a representation which has a separate type
|
|
% (grade_var_<varname>) for each solver variable, whose function symbols
|
|
% include only the values appropriate for that variable.
|
|
%
|
|
% The solver needs the first, uniform representation, since without it,
|
|
% one cannot write generic code that can handle all the requirements.
|
|
% However, this representation cannot express the fact that each solver
|
|
% variable has only a restricted set of valid values. The code that deals
|
|
% with grade strings is much easier to write if one can assume that
|
|
% the invariant expressing this fact holds. The return value of this
|
|
% function guarantees that invariant.
|
|
%
|
|
% If some bug in the solver, or in the data it is given, causes
|
|
% a violation of the invariant, this function will throw an exception.
|
|
%
|
|
:- func success_map_to_grade_vars(success_soln_map) = grade_vars.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type grade_vars
|
|
---> grade_vars(
|
|
gv_pregen :: grade_var_pregen,
|
|
gv_backend :: grade_var_backend,
|
|
gv_target :: grade_var_target,
|
|
gv_gcc_conf :: grade_var_gcc_conf,
|
|
gv_low_tag_bits_use :: grade_var_low_tag_bits_use,
|
|
gv_stack_len :: grade_var_stack_len,
|
|
gv_trail :: grade_var_trail,
|
|
gv_minmodel :: grade_var_minmodel,
|
|
gv_thread_safe :: grade_var_thread_safe,
|
|
gv_gc :: grade_var_gc,
|
|
gv_deep_prof :: grade_var_deep_prof,
|
|
gv_mprof_call :: grade_var_mprof_call,
|
|
gv_mprof_time :: grade_var_mprof_time,
|
|
gv_mprof_memory :: grade_var_mprof_memory,
|
|
gv_tscope_prof :: grade_var_tscope_prof,
|
|
gv_term_size_prof :: grade_var_term_size_prof,
|
|
gv_debug :: grade_var_debug,
|
|
gv_ssdebug :: grade_var_ssdebug,
|
|
gv_target_debug :: grade_var_target_debug,
|
|
gv_rbmm :: grade_var_rbmm,
|
|
gv_rbmm_debug :: grade_var_rbmm_debug,
|
|
gv_rbmm_prof :: grade_var_rbmm_prof,
|
|
gv_merc_file :: grade_var_merc_file,
|
|
gv_merc_float :: grade_var_merc_float
|
|
).
|
|
|
|
:- type grade_var_pregen
|
|
---> grade_var_pregen_no
|
|
; grade_var_pregen_yes.
|
|
|
|
:- type grade_var_backend
|
|
---> grade_var_backend_mlds
|
|
; grade_var_backend_llds.
|
|
|
|
:- type grade_var_target
|
|
---> grade_var_target_c
|
|
; grade_var_target_csharp
|
|
; grade_var_target_java.
|
|
|
|
:- type grade_var_nested_funcs
|
|
---> grade_var_nested_funcs_no
|
|
; grade_var_nested_funcs_yes.
|
|
|
|
% We could record whether we use gcc registers and gcc gotos independently.
|
|
% (We use gcc labels only if we use gcc gotos, so our choices on those
|
|
% two grade variables are not independent.) However, we choose to use
|
|
% this flat representation, because we may not wish to support all
|
|
% of the possible combinations. Some gcc bugs may show up only in
|
|
% the presence of certain combinations, and since some combinations
|
|
% (jump, fast and asm_jump in particular) are rarely used and thus
|
|
% not well tested, we wouldn't necessarily find out about them.
|
|
% This flat representation allows us to pick and choose which
|
|
% combinations we support.
|
|
:- type grade_var_gcc_conf % labels, gotos, regs
|
|
---> grade_var_gcc_conf_none % no no no
|
|
; grade_var_gcc_conf_reg % no no yes
|
|
; grade_var_gcc_conf_jump % no yes no
|
|
; grade_var_gcc_conf_fast % no yes yes
|
|
; grade_var_gcc_conf_asm_jump % yes yes no
|
|
; grade_var_gcc_conf_asm_fast. % yes yes yes
|
|
|
|
:- type grade_var_low_tag_bits_use
|
|
---> grade_var_low_tag_bits_use_0
|
|
; grade_var_low_tag_bits_use_2
|
|
; grade_var_low_tag_bits_use_3.
|
|
|
|
:- type grade_var_stack_len
|
|
---> grade_var_stack_len_std
|
|
; grade_var_stack_len_segments
|
|
; grade_var_stack_len_extend.
|
|
|
|
:- type grade_var_trail
|
|
---> grade_var_trail_no
|
|
; grade_var_trail_yes.
|
|
|
|
:- type grade_var_minmodel
|
|
---> grade_var_minmodel_no
|
|
; grade_var_minmodel_stack_copy
|
|
; grade_var_minmodel_stack_copy_debug
|
|
; grade_var_minmodel_own_stack
|
|
; grade_var_minmodel_own_stack_debug.
|
|
|
|
:- type grade_var_thread_safe
|
|
---> grade_var_thread_safe_c_no
|
|
; grade_var_thread_safe_c_yes
|
|
; grade_var_thread_safe_target_native.
|
|
|
|
:- type grade_var_gc
|
|
---> grade_var_gc_none
|
|
; grade_var_gc_bdw
|
|
; grade_var_gc_bdw_debug
|
|
; grade_var_gc_target_native
|
|
; grade_var_gc_accurate
|
|
; grade_var_gc_history.
|
|
|
|
:- type grade_var_deep_prof
|
|
---> grade_var_deep_prof_no
|
|
; grade_var_deep_prof_yes.
|
|
|
|
:- type grade_var_mprof_call
|
|
---> grade_var_mprof_call_no
|
|
; grade_var_mprof_call_yes.
|
|
|
|
:- type grade_var_mprof_time
|
|
---> grade_var_mprof_time_no
|
|
; grade_var_mprof_time_yes.
|
|
|
|
:- type grade_var_mprof_memory
|
|
---> grade_var_mprof_memory_no
|
|
; grade_var_mprof_memory_yes.
|
|
|
|
:- type grade_var_tscope_prof
|
|
---> grade_var_tscope_prof_no
|
|
; grade_var_tscope_prof_yes.
|
|
|
|
:- type grade_var_term_size_prof
|
|
---> grade_var_term_size_prof_no
|
|
; grade_var_term_size_prof_cells
|
|
; grade_var_term_size_prof_words.
|
|
|
|
:- type grade_var_debug
|
|
---> grade_var_debug_none
|
|
; grade_var_debug_debug
|
|
; grade_var_debug_decldebug.
|
|
|
|
:- type grade_var_ssdebug
|
|
---> grade_var_ssdebug_no
|
|
; grade_var_ssdebug_yes.
|
|
|
|
:- type grade_var_target_debug
|
|
---> grade_var_target_debug_no
|
|
; grade_var_target_debug_yes.
|
|
|
|
:- type grade_var_rbmm
|
|
---> grade_var_rbmm_no
|
|
; grade_var_rbmm_yes.
|
|
|
|
:- type grade_var_rbmm_debug
|
|
---> grade_var_rbmm_debug_no
|
|
; grade_var_rbmm_debug_yes.
|
|
|
|
:- type grade_var_rbmm_prof
|
|
---> grade_var_rbmm_prof_no
|
|
; grade_var_rbmm_prof_yes.
|
|
|
|
:- type grade_var_merc_file
|
|
---> grade_var_merc_file_no
|
|
; grade_var_merc_file_yes.
|
|
|
|
:- type grade_var_merc_float
|
|
---> grade_var_merc_float_is_boxed_c_double
|
|
; grade_var_merc_float_is_unboxed_c_double
|
|
; grade_var_merc_float_is_unboxed_c_float.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module grade_lib.grade_spec.
|
|
|
|
:- import_module map.
|
|
:- import_module require.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
success_map_to_grade_vars(!.SuccMap) = GradeVars :-
|
|
map.det_remove(svar_ac_gcc_regs_avail, _GccRegsAvail, !SuccMap),
|
|
map.det_remove(svar_ac_gcc_gotos_avail, _GccGotosAvail, !SuccMap),
|
|
map.det_remove(svar_ac_gcc_labels_avail, _GccLabelsAvail, !SuccMap),
|
|
map.det_remove(svar_ac_low_tag_bits_avail, _LowTagBitsAvail, !SuccMap),
|
|
map.det_remove(svar_ac_size_of_double, _SizeOfDouble, !SuccMap),
|
|
map.det_remove(svar_ac_merc_file, MercFile, !SuccMap),
|
|
|
|
map.det_remove(svar_pregen, Pregen, !SuccMap),
|
|
map.det_remove(svar_backend, Backend, !SuccMap),
|
|
map.det_remove(svar_target, Target, !SuccMap),
|
|
map.det_remove(svar_gcc_conf, GccConf, !SuccMap),
|
|
map.det_remove(svar_low_tag_bits_use, LowTagBitsUse, !SuccMap),
|
|
map.det_remove(svar_stack_len, StackLen, !SuccMap),
|
|
map.det_remove(svar_trail, Trail, !SuccMap),
|
|
map.det_remove(svar_minmodel, MinimalModel, !SuccMap),
|
|
map.det_remove(svar_thread_safe, ThreadSafe, !SuccMap),
|
|
map.det_remove(svar_gc, Gc, !SuccMap),
|
|
map.det_remove(svar_deep_prof, DeepProf, !SuccMap),
|
|
map.det_remove(svar_mprof_call, MprofCall, !SuccMap),
|
|
map.det_remove(svar_mprof_time, MprofTime, !SuccMap),
|
|
map.det_remove(svar_mprof_memory, MprofMemory, !SuccMap),
|
|
map.det_remove(svar_tscope_prof, TScopeProf, !SuccMap),
|
|
map.det_remove(svar_term_size_prof, TermSizeProf, !SuccMap),
|
|
map.det_remove(svar_debug, Debug, !SuccMap),
|
|
map.det_remove(svar_ssdebug, SSDebug, !SuccMap),
|
|
map.det_remove(svar_target_debug, TargetDebug, !SuccMap),
|
|
map.det_remove(svar_rbmm, RBMM, !SuccMap),
|
|
map.det_remove(svar_rbmm_debug, RBMMDebug, !SuccMap),
|
|
map.det_remove(svar_rbmm_prof, RBMMProf, !SuccMap),
|
|
map.det_remove(svar_request_single_prec_float, _ReqSinglePrecFloat,
|
|
!SuccMap),
|
|
map.det_remove(svar_merc_float, MercFloat, !SuccMap),
|
|
expect(map.is_empty(!.SuccMap), $pred, "unexpected entries in SuccMap"),
|
|
|
|
( if Pregen = svalue_pregen_no then
|
|
GradeVarPregen = grade_var_pregen_no
|
|
else if Pregen = svalue_pregen_yes then
|
|
GradeVarPregen = grade_var_pregen_yes
|
|
else
|
|
unexpected($pred, "unexpected value of Pregen")
|
|
),
|
|
|
|
( if Backend = svalue_backend_mlds then
|
|
GradeVarBackend = grade_var_backend_mlds
|
|
else if Backend = svalue_backend_llds then
|
|
GradeVarBackend = grade_var_backend_llds
|
|
else
|
|
unexpected($pred, "unexpected value of Backend")
|
|
),
|
|
|
|
( if Target = svalue_target_c then
|
|
GradeVarTarget = grade_var_target_c
|
|
else if Target = svalue_target_csharp then
|
|
GradeVarTarget = grade_var_target_csharp
|
|
else if Target = svalue_target_java then
|
|
GradeVarTarget = grade_var_target_java
|
|
else
|
|
unexpected($pred, "unexpected value of Target")
|
|
),
|
|
|
|
( if GccConf = svalue_gcc_conf_none then
|
|
GradeVarGccConf = grade_var_gcc_conf_none
|
|
else if GccConf = svalue_gcc_conf_reg then
|
|
GradeVarGccConf = grade_var_gcc_conf_reg
|
|
else if GccConf = svalue_gcc_conf_jump then
|
|
GradeVarGccConf = grade_var_gcc_conf_jump
|
|
else if GccConf = svalue_gcc_conf_fast then
|
|
GradeVarGccConf = grade_var_gcc_conf_fast
|
|
else if GccConf = svalue_gcc_conf_asm_jump then
|
|
GradeVarGccConf = grade_var_gcc_conf_asm_jump
|
|
else if GccConf = svalue_gcc_conf_asm_fast then
|
|
GradeVarGccConf = grade_var_gcc_conf_asm_fast
|
|
else
|
|
unexpected($pred, "unexpected value of GccConf")
|
|
),
|
|
|
|
( if LowTagBitsUse = svalue_low_tag_bits_use_0 then
|
|
GradeVarLowTagBitsUse = grade_var_low_tag_bits_use_0
|
|
else if LowTagBitsUse = svalue_low_tag_bits_use_2 then
|
|
GradeVarLowTagBitsUse = grade_var_low_tag_bits_use_2
|
|
else if LowTagBitsUse = svalue_low_tag_bits_use_3 then
|
|
GradeVarLowTagBitsUse = grade_var_low_tag_bits_use_3
|
|
else
|
|
unexpected($pred, "unexpected value of LowTagBitsUse")
|
|
),
|
|
|
|
( if StackLen = svalue_stack_len_std then
|
|
GradeVarStackLen = grade_var_stack_len_std
|
|
else if StackLen = svalue_stack_len_segments then
|
|
GradeVarStackLen = grade_var_stack_len_segments
|
|
else if StackLen = svalue_stack_len_extend then
|
|
GradeVarStackLen = grade_var_stack_len_extend
|
|
else
|
|
unexpected($pred, "unexpected value of StackLen")
|
|
),
|
|
|
|
( if Trail = svalue_trail_no then
|
|
GradeVarTrail = grade_var_trail_no
|
|
else if Trail = svalue_trail_yes then
|
|
GradeVarTrail = grade_var_trail_yes
|
|
else
|
|
unexpected($pred, "unexpected value of Trail")
|
|
),
|
|
|
|
( if MinimalModel = svalue_minmodel_no then
|
|
GradeVarMinimalModel = grade_var_minmodel_no
|
|
else if MinimalModel = svalue_minmodel_stack_copy then
|
|
GradeVarMinimalModel = grade_var_minmodel_stack_copy
|
|
else if MinimalModel = svalue_minmodel_stack_copy_debug then
|
|
GradeVarMinimalModel = grade_var_minmodel_stack_copy_debug
|
|
else if MinimalModel = svalue_minmodel_own_stack then
|
|
GradeVarMinimalModel = grade_var_minmodel_own_stack
|
|
else if MinimalModel = svalue_minmodel_own_stack_debug then
|
|
GradeVarMinimalModel = grade_var_minmodel_own_stack_debug
|
|
else
|
|
unexpected($pred, "unexpected value of MinimalModel")
|
|
),
|
|
|
|
( if ThreadSafe = svalue_thread_safe_c_no then
|
|
GradeVarThreadSafe = grade_var_thread_safe_c_no
|
|
else if ThreadSafe = svalue_thread_safe_c_yes then
|
|
GradeVarThreadSafe = grade_var_thread_safe_c_yes
|
|
else if ThreadSafe = svalue_thread_safe_target_native then
|
|
GradeVarThreadSafe = grade_var_thread_safe_target_native
|
|
else
|
|
unexpected($pred, "unexpected value of ThreadSafe")
|
|
),
|
|
|
|
( if Gc = svalue_gc_none then
|
|
GradeVarGc = grade_var_gc_none
|
|
else if Gc = svalue_gc_bdw then
|
|
GradeVarGc = grade_var_gc_bdw
|
|
else if Gc = svalue_gc_bdw_debug then
|
|
GradeVarGc = grade_var_gc_bdw_debug
|
|
else if Gc = svalue_gc_target_native then
|
|
GradeVarGc = grade_var_gc_target_native
|
|
else if Gc = svalue_gc_accurate then
|
|
GradeVarGc = grade_var_gc_accurate
|
|
else if Gc = svalue_gc_history then
|
|
GradeVarGc = grade_var_gc_history
|
|
else
|
|
unexpected($pred, "unexpected value of Gc")
|
|
),
|
|
|
|
( if DeepProf = svalue_deep_prof_no then
|
|
GradeVarDeepProf = grade_var_deep_prof_no
|
|
else if DeepProf = svalue_deep_prof_yes then
|
|
GradeVarDeepProf = grade_var_deep_prof_yes
|
|
else
|
|
unexpected($pred, "unexpected value of DeepProf")
|
|
),
|
|
|
|
( if MprofCall = svalue_mprof_call_no then
|
|
GradeVarMprofCall = grade_var_mprof_call_no
|
|
else if MprofCall = svalue_mprof_call_yes then
|
|
GradeVarMprofCall = grade_var_mprof_call_yes
|
|
else
|
|
unexpected($pred, "unexpected value of MprofCall")
|
|
),
|
|
|
|
( if MprofTime = svalue_mprof_time_no then
|
|
GradeVarMprofTime = grade_var_mprof_time_no
|
|
else if MprofTime = svalue_mprof_time_yes then
|
|
GradeVarMprofTime = grade_var_mprof_time_yes
|
|
else
|
|
unexpected($pred, "unexpected value of MprofTime")
|
|
),
|
|
|
|
( if MprofMemory = svalue_mprof_memory_no then
|
|
GradeVarMprofMemory = grade_var_mprof_memory_no
|
|
else if MprofMemory = svalue_mprof_memory_yes then
|
|
GradeVarMprofMemory = grade_var_mprof_memory_yes
|
|
else
|
|
unexpected($pred, "unexpected value of MprofMemory")
|
|
),
|
|
|
|
( if TScopeProf = svalue_tscope_prof_no then
|
|
GradeVarTScopeProf = grade_var_tscope_prof_no
|
|
else if TScopeProf = svalue_tscope_prof_yes then
|
|
GradeVarTScopeProf = grade_var_tscope_prof_yes
|
|
else
|
|
unexpected($pred, "unexpected value of TScopeProf")
|
|
),
|
|
|
|
( if TermSizeProf = svalue_term_size_prof_no then
|
|
GradeVarTermSizeProf = grade_var_term_size_prof_no
|
|
else if TermSizeProf = svalue_term_size_prof_cells then
|
|
GradeVarTermSizeProf = grade_var_term_size_prof_cells
|
|
else if TermSizeProf = svalue_term_size_prof_words then
|
|
GradeVarTermSizeProf = grade_var_term_size_prof_words
|
|
else
|
|
unexpected($pred, "unexpected value of TermSizeProf")
|
|
),
|
|
|
|
( if Debug = svalue_debug_none then
|
|
GradeVarDebug = grade_var_debug_none
|
|
else if Debug = svalue_debug_debug then
|
|
GradeVarDebug = grade_var_debug_debug
|
|
else if Debug = svalue_debug_decldebug then
|
|
GradeVarDebug = grade_var_debug_decldebug
|
|
else
|
|
unexpected($pred, "unexpected value of Debug")
|
|
),
|
|
|
|
( if SSDebug = svalue_ssdebug_no then
|
|
GradeVarSSDebug = grade_var_ssdebug_no
|
|
else if SSDebug = svalue_ssdebug_yes then
|
|
GradeVarSSDebug = grade_var_ssdebug_yes
|
|
else
|
|
unexpected($pred, "unexpected value of SSDebug")
|
|
),
|
|
|
|
( if TargetDebug = svalue_target_debug_no then
|
|
GradeVarTargetDebug = grade_var_target_debug_no
|
|
else if TargetDebug = svalue_target_debug_yes then
|
|
GradeVarTargetDebug = grade_var_target_debug_yes
|
|
else
|
|
unexpected($pred, "unexpected value of TargetDebug")
|
|
),
|
|
|
|
( if RBMM = svalue_rbmm_no then
|
|
GradeVarRBMM = grade_var_rbmm_no
|
|
else if RBMM = svalue_rbmm_yes then
|
|
GradeVarRBMM = grade_var_rbmm_yes
|
|
else
|
|
unexpected($pred, "unexpected value of RBMM")
|
|
),
|
|
|
|
( if RBMMDebug = svalue_rbmm_debug_no then
|
|
GradeVarRBMMDebug = grade_var_rbmm_debug_no
|
|
else if RBMMDebug = svalue_rbmm_debug_yes then
|
|
GradeVarRBMMDebug = grade_var_rbmm_debug_yes
|
|
else
|
|
unexpected($pred, "unexpected value of RBMMDebug")
|
|
),
|
|
|
|
( if RBMMProf = svalue_rbmm_prof_no then
|
|
GradeVarRBMMProf = grade_var_rbmm_prof_no
|
|
else if RBMMProf = svalue_rbmm_prof_yes then
|
|
GradeVarRBMMProf = grade_var_rbmm_prof_yes
|
|
else
|
|
unexpected($pred, "unexpected value of RBMMProf")
|
|
),
|
|
|
|
( if MercFile = svalue_ac_merc_file_no then
|
|
GradeVarMercFile = grade_var_merc_file_no
|
|
else if MercFile = svalue_ac_merc_file_yes then
|
|
GradeVarMercFile = grade_var_merc_file_yes
|
|
else
|
|
unexpected($pred, "unexpected value of MercFile")
|
|
),
|
|
|
|
( if MercFloat = svalue_merc_float_is_boxed_c_double then
|
|
GradeVarMercFloat = grade_var_merc_float_is_boxed_c_double
|
|
else if MercFloat = svalue_merc_float_is_unboxed_c_double then
|
|
GradeVarMercFloat = grade_var_merc_float_is_unboxed_c_double
|
|
else if MercFloat = svalue_merc_float_is_unboxed_c_float then
|
|
GradeVarMercFloat = grade_var_merc_float_is_unboxed_c_float
|
|
else
|
|
unexpected($pred, "unexpected value of MercFloat")
|
|
),
|
|
|
|
GradeVars = grade_vars(GradeVarPregen, GradeVarBackend, GradeVarTarget,
|
|
GradeVarGccConf, GradeVarLowTagBitsUse, GradeVarStackLen,
|
|
GradeVarTrail,
|
|
GradeVarMinimalModel, GradeVarThreadSafe, GradeVarGc,
|
|
GradeVarDeepProf,
|
|
GradeVarMprofCall, GradeVarMprofTime, GradeVarMprofMemory,
|
|
GradeVarTScopeProf, GradeVarTermSizeProf,
|
|
GradeVarDebug, GradeVarSSDebug, GradeVarTargetDebug,
|
|
GradeVarRBMM, GradeVarRBMMDebug, GradeVarRBMMProf,
|
|
GradeVarMercFile, GradeVarMercFloat
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module grade_lib.grade_vars.
|
|
%---------------------------------------------------------------------------%
|