Generate diagnostics for .par.mm grades.

compiler/handle_options.m:
runtime/mercury_grade.h:
scripts/final_grade_options.sh-subr:
    Generate an error message for grades that mix parallel execution
    and minimal model tabling.

compiler/compute_grade.m:
    Improve two comments.
This commit is contained in:
Zoltan Somogyi
2021-06-13 21:41:56 +10:00
parent 6310117ca5
commit f66a7d6642
4 changed files with 73 additions and 22 deletions

View File

@@ -167,9 +167,11 @@ check_grade_component_compatibility(Globals, Target, GC_Method, !Specs) :-
ProfileMemory = no ProfileMemory = no
), ),
% NOTE: compatibility with profile_deep is checked elsewhere. % Compatibility with profile_deep is checked by
% handle_profiling_options in handle_options.m.
% NOTE: compatibility with debugging is checked elsewhere. % Compatibility with debugging is checked by
% handle_debugging_options in handle_options.m.
% Trailing is only supported by the C back-ends. % Trailing is only supported by the C back-ends.
% %

View File

@@ -1641,8 +1641,6 @@ handle_minimal_model_options(!Globals, AllowHijacksMMSC, !Specs) :-
UseMinimalModelStackCopy), UseMinimalModelStackCopy),
globals.lookup_bool_option(!.Globals, use_minimal_model_own_stacks, globals.lookup_bool_option(!.Globals, use_minimal_model_own_stacks,
UseMinimalModelOwnStacks), UseMinimalModelOwnStacks),
bool.or(UseMinimalModelStackCopy, UseMinimalModelOwnStacks,
UseMinimalModel),
% Minimal model tabling is not compatible with high level code % Minimal model tabling is not compatible with high level code
% or with trailing; see the comments in runtime/mercury_grade.h. % or with trailing; see the comments in runtime/mercury_grade.h.
( if ( if
@@ -1653,25 +1651,46 @@ handle_minimal_model_options(!Globals, AllowHijacksMMSC, !Specs) :-
[words("You cannot use both forms of minimal model tabling"), [words("You cannot use both forms of minimal model tabling"),
words("at once."), nl], words("at once."), nl],
add_error(phase_options, DualMMSpec, !Specs) add_error(phase_options, DualMMSpec, !Specs)
else if
UseMinimalModel = bool.yes,
globals.lookup_bool_option(!.Globals, highlevel_code, yes)
then
MMHLSpec =
[words("Minimal model tabling is incompatible with"),
words("high level code."), nl],
add_error(phase_options, MMHLSpec, !Specs)
else if
UseMinimalModel = bool.yes,
globals.lookup_bool_option(!.Globals, use_trail, yes)
then
MMTrailSpec =
[words("Minimal model tabling is incompatible with"),
words("trailing."), nl],
add_error(phase_options, MMTrailSpec, !Specs)
else else
true true
), ),
bool.or(UseMinimalModelStackCopy, UseMinimalModelOwnStacks,
UseMinimalModel),
(
UseMinimalModel = bool.yes,
globals.lookup_bool_option(!.Globals, highlevel_code, HighLevelCode),
(
HighLevelCode = yes,
MMHLSpec =
[words("Minimal model tabling is incompatible with"),
words("high level code."), nl],
add_error(phase_options, MMHLSpec, !Specs)
;
HighLevelCode = no
),
globals.lookup_bool_option(!.Globals, use_trail, UseTrail),
(
UseTrail = yes,
MMTrailSpec =
[words("Minimal model tabling is incompatible with"),
words("trailing."), nl],
add_error(phase_options, MMTrailSpec, !Specs)
;
UseTrail = no
),
globals.lookup_bool_option(!.Globals, parallel, Parallel),
(
Parallel = yes,
MMParSpec =
[words("Minimal model tabling is incompatible with"),
words("parallel execution."), nl],
add_error(phase_options, MMParSpec, !Specs)
;
Parallel = no
)
;
UseMinimalModel = no
),
% Stack copy minimal model tabling needs to be able to rewrite all % Stack copy minimal model tabling needs to be able to rewrite all
% the redoips in a given nondet stack segments. If we allow hijacks, % the redoips in a given nondet stack segments. If we allow hijacks,

View File

@@ -290,6 +290,28 @@
#error "high level code and minimal model tabling are not compatible" #error "high level code and minimal model tabling are not compatible"
#endif #endif
// Tabling is incompatible with multiple threads of execution for several
// reasons. The main one is that when we find that the entry for a call's
// input arguments in the called procedure's call table is already active
// before the call, all forms of tabling treat it as a sign of infinite
// recursion, as in e.g. f(42, ...) calling ... calling f(42, ...).
// However, in a grade that allows more than thread of execution to be active
// at the same time, the two f(42, ...) calls need not be related as
// ancestor and descendant; they could be independent calls in different
// threads. This invalidates the basic assumption on top of which
// tabling is built.
//
// There are other reasons as well. The data structures used by tabling
// are not protected by critical sections, so simultaneous access by more
// than one thread at the same time can cause data corruption, and
// in the process of suspending one call in one thread, the stack copy
// implementation of minimal model tabling can actively overwrite parts
// of the stack that are still being used by other threads.
#if defined(MR_THREAD_SAFE)
#error "parallel execution and minimal model tabling are not compatible"
#endif
// Neither form of the minimal model tabling works if the system recovers // Neither form of the minimal model tabling works if the system recovers
// memory allocated after a choice point when backtracking to that choice // memory allocated after a choice point when backtracking to that choice
// point. This rules out the use of the native Mercury collector, as well as // point. This rules out the use of the native Mercury collector, as well as

View File

@@ -11,8 +11,7 @@
# An `sh' subroutine for handling implications between grade-related # An `sh' subroutine for handling implications between grade-related
# options. Used by the `ml', `mgnuc' and `c2init' scripts. # options. Used by the `ml', `mgnuc' and `c2init' scripts.
# #
# The code here should be inserted after a script's option-parsing # The code here should be inserted after a script's option-parsing loop.
# loop.
# #
# IMPORTANT: any changes to the handling of grades here may also require # IMPORTANT: any changes to the handling of grades here may also require
# changes to compiler/handle_options.m. # changes to compiler/handle_options.m.
@@ -43,6 +42,15 @@ case ${use_trail},${use_minimal_model} in
;; ;;
esac esac
# .par grade is not compatible with .*mm*
# (see comment in runtime/mercury_grade.h for rationale)
case ${use_trail},${use_minimal_model} in
true,true)
echo "parallel execution and minimal model tabling are not compatible" 1>&2
exit 1
;;
esac
# .exts grade is not compatible with .stseg # .exts grade is not compatible with .stseg
# (they are alternative ways of doing the same thing) # (they are alternative ways of doing the same thing)
case ${extend_stacks},${stack_segments} in case ${extend_stacks},${stack_segments} in