mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-19 07:45:09 +00:00
Estimated hours taken: 6 Branches: main compiler/hlds_llds.m: Remove the dependence of this module on ll_backend.llds by defining types using abstract descriptions of LLDS storage locations. These have the added advantage that they express the intent of the affected data structures more directly. For example, the stack slot type used to be able to map a variable to a register or to a field of a cell on the heap, which doesn't make sense. This is no longer the case. The cost of the conversion operations now required is partly paid for by our new ability to avoid some old sanity checks. compiler/llds.m: compiler/code_util.m: Add some utility predicates to operate on the new data structures. compiler/code_aux.m: compiler/code_gen.m: compiler/code_info.m: compiler/continuation_info.m: compiler/follow_vars.m: compiler/lookup_switch.m: compiler/par_conj_gen.m: compiler/stack_alloc.m: compiler/store_alloc.m: compiler/var_locn.m: Conform to the changes in hlds_llds.m. In some cases, improve the style of the affected predicates, e.g. by introducing state variable syntax. compiler/hlds_out.m: Conform to the changes in hlds_llds.m, and avoid importing ll_backend.
114 lines
3.8 KiB
Mathematica
114 lines
3.8 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1994-2004 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.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Auxiliary code generator module. Unlike code_util, it imports code_info.
|
|
%
|
|
% Main authors: conway, zs.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module ll_backend__code_aux.
|
|
|
|
:- interface.
|
|
|
|
:- import_module hlds__hlds_goal.
|
|
:- import_module hlds__hlds_llds.
|
|
:- import_module ll_backend__code_info.
|
|
:- import_module parse_tree__prog_data.
|
|
|
|
:- import_module bool.
|
|
|
|
% code_aux__contains_simple_recursive_call(G, CI, Last) succeeds
|
|
% if G is a conjunction of goals, exactly one of which is a recursive
|
|
% call (CI says what the current procedure is), and there are no
|
|
% other goals that cause control to leave this procedure. Last is
|
|
% set dependening on whether the recursive call is last in the
|
|
% conjunction or not.
|
|
|
|
% XXX should avoid the dependency on code_info here
|
|
:- pred code_aux__contains_simple_recursive_call(hlds_goal::in, code_info::in,
|
|
bool::out) is semidet.
|
|
|
|
:- pred code_aux__explain_stack_slots(stack_slots::in, prog_varset::in,
|
|
string::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module hlds__goal_form.
|
|
:- import_module ll_backend__llds.
|
|
:- import_module ll_backend__llds_out.
|
|
|
|
:- import_module string, list, assoc_list, map, std_util, varset.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
code_aux__contains_simple_recursive_call(Goal - _, CodeInfo, Last) :-
|
|
Goal = conj(Goals),
|
|
code_aux__contains_simple_recursive_call_expr(Goals, CodeInfo, Last).
|
|
|
|
:- pred code_aux__contains_simple_recursive_call_expr(list(hlds_goal)::in,
|
|
code_info::in, bool::out) is semidet.
|
|
|
|
code_aux__contains_simple_recursive_call_expr([Goal|Goals], CodeInfo, Last) :-
|
|
Goal = GoalExpr - _,
|
|
(
|
|
contains_only_builtins_expr(GoalExpr)
|
|
->
|
|
code_aux__contains_simple_recursive_call_expr(Goals, CodeInfo,
|
|
Last)
|
|
;
|
|
code_aux__is_recursive_call(GoalExpr, CodeInfo),
|
|
( Goals = [] ->
|
|
Last = yes
|
|
;
|
|
contains_only_builtins_list(Goals),
|
|
Last = no
|
|
)
|
|
).
|
|
|
|
:- pred code_aux__is_recursive_call(hlds_goal_expr::in, code_info::in)
|
|
is semidet.
|
|
|
|
code_aux__is_recursive_call(Goal, CodeInfo) :-
|
|
Goal = call(CallPredId, CallProcId, _, BuiltinState, _, _),
|
|
BuiltinState = not_builtin,
|
|
code_info__get_pred_id(CodeInfo, PredId),
|
|
PredId = CallPredId,
|
|
code_info__get_proc_id(CodeInfo, ProcId),
|
|
ProcId = CallProcId.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
code_aux__explain_stack_slots(StackSlots, VarSet, Explanation) :-
|
|
map__to_assoc_list(StackSlots, StackSlotsList),
|
|
code_aux__explain_stack_slots_2(StackSlotsList, VarSet, "",
|
|
Explanation1),
|
|
string__append("\nStack slot assignments (if any):\n", Explanation1,
|
|
Explanation).
|
|
|
|
:- pred code_aux__explain_stack_slots_2(assoc_list(prog_var, stack_slot)::in,
|
|
prog_varset::in, string::in, string::out) is det.
|
|
|
|
code_aux__explain_stack_slots_2([], _, !Explanation).
|
|
code_aux__explain_stack_slots_2([Var - Slot | Rest], VarSet, !Explanation) :-
|
|
code_aux__explain_stack_slots_2(Rest, VarSet, !Explanation),
|
|
(
|
|
Slot = det_slot(SlotNum),
|
|
StackStr = "stackvar"
|
|
;
|
|
Slot = nondet_slot(SlotNum),
|
|
StackStr = "framevar"
|
|
),
|
|
int_to_string(SlotNum, SlotStr),
|
|
varset__lookup_name(VarSet, Var, VarName),
|
|
string__append_list([VarName, "\t ->\t", StackStr, SlotStr, "\n",
|
|
!.Explanation], !:Explanation).
|
|
|
|
%---------------------------------------------------------------------------%
|