Files
mercury/compiler/lco.m
Thomas Conway a70b59e83c Add a test to find the number of words needed to represent a
configure.in:
        Add a test to find the number of words needed to represent a
        synchronization term.

boehm_gc/gc.h:
        fix a declaration by replacing the args () with (void).
boehm_gc/solaris_pthreads.c:
        add a missing include
        check the return values of pthread calls.

compiler/*.m:
        Add handling for the new HLDS goal type par_conj.
        Add handling for the four new LLDS instructions:
                init_sync_term
                fork
                join_and_terminate
                join_and_continue

compiler/code_info.m:
        add a new alternative for slot_contents - sync_term.

compiler/handle_options.m:
        add .par as part of the grade

compiler/hlds_goal.m:
        add the new goal type par_conj.

compiler/instmap.m:
        add instmap__unify which takes a list of instmaps
                and abstractly unifies them.
        add unify_instmap_delta which tajes two instmap deltas
                and abstractly unifies them.

compiler/llds.m:
        add the new llds instructions.

compiler/mode_info.m:
        add par_conj as a lock reason.

library/Makefile:
        work around a bug in the solaris version pthread.h

library/benchmarking.m:
        reference the stack zones from the engine structure
        rather than from global variables.

library/{nc,sp}_builtin.nl:
        add an op declaration for &.

library/std_util.m:
        change references to global variables to references inside
        the engine structure.

runtime/Mmakefile:
        add mercury_thread.{c,h}
        add THREADLIBS to the libraries

runtime/*.{c,h}
        Remove some old junk from the previous processes/shrd-mem
        changes that found their way into the repository.
        Add MR_ prefixes to lots of names.

runtime/mercury_context.c:
        Add init_thread_stuff for creating and initializing a
        context structure for the current thread.

runtime/mercury_context.h:
        add a field to the mercury context which stores the thread id
        of the thread where this context originated.
        add various macros for implementing the new llds instructions.

runtime/mercury_engine.c:
        initialize the engine structure, rather than a bunch of globals.

runtime/mercury_engine.h:
        declare the mercury_engine structure.

runtime/mercury_regorder.h:
        if MR_THREAD_SAFE, and there is at least one global register
        then use mr0 as a pointer to the mercury engine structure.

scripts/init_grade_options.sh-subr
        add thread_safe

scripts/mgnuc.in
        add THREAD_OPTS

scripts/ml.in:
        add THREAD_LIBS
1998-06-09 02:16:31 +00:00

169 lines
6.0 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 1996-1998 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
% Main author: zs
% This module looks for opportunities to apply the "last call modulo
% constructor application" optimization.
%-----------------------------------------------------------------------------%
:- module lco.
:- interface.
:- import_module hlds_module, hlds_pred.
:- import_module io.
:- pred lco_modulo_constructors(pred_id, proc_id, module_info,
proc_info, proc_info, io__state, io__state).
:- mode lco_modulo_constructors(in, in, in, in, out, di, uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module hlds_goal, passes_aux, hlds_out.
:- import_module list, require, std_util.
%-----------------------------------------------------------------------------%
lco_modulo_constructors(PredId, ProcId, ModuleInfo, ProcInfo0, ProcInfo) -->
{ proc_info_goal(ProcInfo0, Goal0) },
{ lco_in_goal(Goal0, ModuleInfo, Goal) },
( { Goal = Goal0 } ->
{ ProcInfo = ProcInfo0 }
;
{ ProcInfo = ProcInfo0 }, % for now
% { proc_info_set_goal(ProcInfo0, Goal, ProcInfo) },
io__write_string("% Can introduce LCO in "),
hlds_out__write_pred_proc_id(ModuleInfo, PredId, ProcId),
io__write_string("\n")
).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- pred lco_in_goal(hlds_goal, module_info, hlds_goal).
:- mode lco_in_goal(in, in, out) is det.
lco_in_goal(Goal0 - GoalInfo, ModuleInfo, Goal - GoalInfo) :-
lco_in_goal_2(Goal0, ModuleInfo, Goal).
%-----------------------------------------------------------------------------%
:- pred lco_in_goal_2(hlds_goal_expr, module_info, hlds_goal_expr).
:- mode lco_in_goal_2(in, in, out) is det.
lco_in_goal_2(conj(Goals0), ModuleInfo, conj(Goals)) :-
list__reverse(Goals0, RevGoals0),
lco_in_conj(RevGoals0, [], ModuleInfo, Goals).
% XXX Some execution algorithm issues here.
lco_in_goal_2(par_conj(_Goals0, SM), _ModuleInfo, par_conj(_Goals, SM)) :-
error("sorry: lco of parallel conjunction not implemented").
lco_in_goal_2(disj(Goals0, SM), ModuleInfo, disj(Goals, SM)) :-
lco_in_disj(Goals0, ModuleInfo, Goals).
lco_in_goal_2(switch(Var, Det, Cases0, SM), ModuleInfo,
switch(Var, Det, Cases, SM)) :-
lco_in_cases(Cases0, ModuleInfo, Cases).
lco_in_goal_2(if_then_else(Vars, Cond, Then0, Else0, SM), ModuleInfo,
if_then_else(Vars, Cond, Then, Else, SM)) :-
lco_in_goal(Then0, ModuleInfo, Then),
lco_in_goal(Else0, ModuleInfo, Else).
lco_in_goal_2(some(Vars, Goal0), ModuleInfo, some(Vars, Goal)) :-
lco_in_goal(Goal0, ModuleInfo, Goal).
lco_in_goal_2(not(Goal), _ModuleInfo, not(Goal)).
lco_in_goal_2(higher_order_call(A,B,C,D,E,F), _ModuleInfo,
higher_order_call(A,B,C,D,E,F)).
lco_in_goal_2(class_method_call(A,B,C,D,E,F), _ModuleInfo,
class_method_call(A,B,C,D,E,F)).
lco_in_goal_2(call(A,B,C,D,E,F), _ModuleInfo, call(A,B,C,D,E,F)).
lco_in_goal_2(unify(A,B,C,D,E), _ModuleInfo, unify(A,B,C,D,E)).
lco_in_goal_2(pragma_c_code(A,B,C,D,E,F,G), _,
pragma_c_code(A,B,C,D,E,F,G)).
%-----------------------------------------------------------------------------%
:- pred lco_in_disj(list(hlds_goal), module_info, list(hlds_goal)).
:- mode lco_in_disj(in, in, out) is det.
lco_in_disj([], __ModuleInfo, []).
lco_in_disj([Goal0 | Goals0], ModuleInfo, [Goal | Goals]) :-
lco_in_goal(Goal0, ModuleInfo, Goal),
lco_in_disj(Goals0, ModuleInfo, Goals).
%-----------------------------------------------------------------------------%
:- pred lco_in_cases(list(case), module_info, list(case)).
:- mode lco_in_cases(in, in, out) is det.
lco_in_cases([], __ModuleInfo, []).
lco_in_cases([case(Cons, Goal0) | Cases0], ModuleInfo,
[case(Cons, Goal) | Cases]) :-
lco_in_goal(Goal0, ModuleInfo, Goal),
lco_in_cases(Cases0, ModuleInfo, Cases).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
% lco_in_conj(RevGoals, Unifies, ModuleInfo, Goals)
%
% Given a conjunction whose structure is: "goals*,call,construct*",
% move the construction unifications before the call.
%
% For now the transformation results are usable by humans only.
% XXX Later we will have to modify the instantiation states
% recorded for the variables involved in the constructions.
% The ModuleInfo will be probably be needed by this code.
%
% We traverse the conjunction backwards (the caller has reversed the list).
% RevGoals is the list of remaining goals in the reversed conjunction list.
% RevUnifies is the list of assignments and constructions delayed by any
% previous recursive invocations of lco_in_conj.
%
% invariant: append(reverse(RevGoals), Unifies) = original conjunction
:- pred lco_in_conj(list(hlds_goal), list(hlds_goal), module_info,
list(hlds_goal)).
:- mode lco_in_conj(in, in, in, out) is det.
lco_in_conj([], Unifies, __ModuleInfo, Unifies).
lco_in_conj([Goal0 | Goals0], Unifies0, ModuleInfo, Goals) :-
Goal0 = GoalExpr0 - _,
(
GoalExpr0 = unify(_, _, _, Unif, _),
Unif = construct(_, _, _, _)
->
Unifies1 = [Goal0 | Unifies0],
lco_in_conj(Goals0, Unifies1, ModuleInfo, Goals)
;
GoalExpr0 = call(_, _, _, _, _, _)
->
list__append(Unifies0, [Goal0], LaterGoals),
list__reverse(Goals0, FrontGoals),
list__append(FrontGoals, LaterGoals, Goals)
;
% The conjunction does not follow the pattern "unify*, goal"
% so we cannot optimize it; reconstruct the original goal list
list__reverse([Goal0 | Goals0], FrontGoals),
list__append(FrontGoals, Unifies0, Goals)
).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%