mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-15 13:55:07 +00:00
Estimated hours taken: 6 Change the LLDS representation of a module from containing a list of c_modules to containing four lists, of (a) compiler generated C code, (b) compiler generated data, (c) user-written C code and (d) exported C functions. This simplifies the several passes (e.g. transform_llds, llds_common) that only care about one kind of "c_module". compiler/llds.m: Change the definition of c_file along the lines above. compiler/llds_out.m: Write out the new data structure. Change some predicate names to make it clear what predicates handle the splitting of C files. Remove the obsolete #define of MR_USE_REDOFR compiler/base_type_info.m: compiler/base_type_layout.m: compiler/base_typeclass_info.m: Adapt to the new data structure. compiler/llds_common.m: Use the new data structure to simplify the code. Change the order of some arguments to conform to our usual conventions. compiler/transform_llds.m: Use the new data structure to simplify the code. compiler/mercury_compile.m: Adapt the gathering of the c_file components to the new data structure. Fix a predicate name. Fix a bug: stack layouts were always treated as static data, although proc layouts are only static if we have static code addresses. compiler/stack_layout.m: Return the proc layouts and the label layouts in separate lists, since only label layouts are always static data.
338 lines
10 KiB
Mathematica
338 lines
10 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.
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% This module looks for static data structures in create rvals so that
|
|
% it can make them global, in the hope of replacing multiple local definitions
|
|
% by a single global one.
|
|
%
|
|
% Processes a list of procedures, and a list of c_modules, intended
|
|
% to contain any extra c_data structures the compiler generates.
|
|
% Any other contents of the c_modules list will be untouched.
|
|
|
|
% Main author: zs.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module llds_common.
|
|
|
|
:- interface.
|
|
|
|
:- import_module llds.
|
|
:- import_module prog_data. % for module_name
|
|
:- import_module list.
|
|
|
|
:- pred llds_common(list(c_procedure)::in, list(comp_gen_c_data)::in,
|
|
module_name::in, list(c_procedure)::out, list(comp_gen_c_data)::out)
|
|
is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module llds_out.
|
|
|
|
:- import_module bool, int, assoc_list, map, std_util, require.
|
|
|
|
:- type cell_info
|
|
---> cell_info(
|
|
int % what is the number of the cell?
|
|
).
|
|
|
|
:- type common_info
|
|
---> common_info(
|
|
module_name, % base file name
|
|
int, % next cell number
|
|
map(list(maybe(rval)), cell_info)
|
|
% map cell contents to cell declaration
|
|
% information
|
|
).
|
|
|
|
llds_common(Procedures0, Data0, BaseName, Procedures, Data) :-
|
|
map__init(CellMap0),
|
|
Info0 = common_info(BaseName, 0, CellMap0),
|
|
llds_common__process_procs(Procedures0, Procedures, Info0, Info1),
|
|
llds_common__process_datas(Data0, Data1, Info1, Info),
|
|
Info = common_info(_, _, CellMap),
|
|
map__to_assoc_list(CellMap, CellPairs0),
|
|
list__sort(lambda([CellPairA::in, CellPairB::in, Compare::out] is det,
|
|
(
|
|
CellPairA = _ - cell_info(ANum),
|
|
CellPairB = _ - cell_info(BNum),
|
|
compare(Compare, ANum, BNum)
|
|
)), CellPairs0, CellPairs),
|
|
llds_common__cell_pairs_to_modules(CellPairs, BaseName, CommonData),
|
|
list__append(CommonData, Data1, Data).
|
|
|
|
:- pred llds_common__cell_pairs_to_modules(
|
|
assoc_list(list(maybe(rval)), cell_info)::in, module_name::in,
|
|
list(comp_gen_c_data)::out) is det.
|
|
|
|
llds_common__cell_pairs_to_modules([], _, []).
|
|
llds_common__cell_pairs_to_modules([Args - CellInfo | CellPairs], BaseName,
|
|
[Common | Commons]) :-
|
|
CellInfo = cell_info(VarNum),
|
|
Common = comp_gen_c_data(BaseName, common(VarNum), no, Args, []),
|
|
llds_common__cell_pairs_to_modules(CellPairs, BaseName, Commons).
|
|
|
|
:- pred llds_common__process_create(tag::in, list(maybe(rval))::in,
|
|
rval::out, common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_create(Tag, Args0, Rval, Info0, Info) :-
|
|
llds_common__process_maybe_rvals(Args0, Args, Info0, Info1),
|
|
Info1 = common_info(BaseName, NextCell0, CellMap0),
|
|
( map__search(CellMap0, Args, CellInfo0) ->
|
|
CellInfo0 = cell_info(VarNum),
|
|
DataConst = data_addr_const(
|
|
data_addr(BaseName, common(VarNum))),
|
|
Rval = mkword(Tag, const(DataConst)),
|
|
Info = Info1
|
|
;
|
|
DataConst = data_addr_const(
|
|
data_addr(BaseName, common(NextCell0))),
|
|
Rval = mkword(Tag, const(DataConst)),
|
|
CellInfo = cell_info(NextCell0),
|
|
NextCell is NextCell0 + 1,
|
|
map__det_insert(CellMap0, Args, CellInfo, CellMap),
|
|
Info = common_info(BaseName, NextCell, CellMap)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% The rest of the file is quite boring. Its only job is to traverse
|
|
% the various components of c_modules to arrive at the creates.
|
|
|
|
:- pred llds_common__process_datas(list(comp_gen_c_data)::in,
|
|
list(comp_gen_c_data)::out, common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_datas([], [], Info, Info).
|
|
llds_common__process_datas([Data0 | Datas0], [Data | Datas], Info0, Info) :-
|
|
llds_common__process_data(Data0, Data, Info0, Info1),
|
|
llds_common__process_datas(Datas0, Datas, Info1, Info).
|
|
|
|
:- pred llds_common__process_data(comp_gen_c_data::in, comp_gen_c_data::out,
|
|
common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_data(
|
|
comp_gen_c_data(Name, DataName, Export, Args0, Refs),
|
|
comp_gen_c_data(Name, DataName, Export, Args, Refs),
|
|
Info0, Info) :-
|
|
llds_common__process_maybe_rvals(Args0, Args, Info0, Info).
|
|
|
|
:- pred llds_common__process_procs(list(c_procedure)::in,
|
|
list(c_procedure)::out, common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_procs([], [], Info, Info).
|
|
llds_common__process_procs([Proc0 | Procs0], [Proc | Procs], Info0, Info) :-
|
|
llds_common__process_proc(Proc0, Proc, Info0, Info1),
|
|
llds_common__process_procs(Procs0, Procs, Info1, Info).
|
|
|
|
:- pred llds_common__process_proc(c_procedure::in, c_procedure::out,
|
|
common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_proc(Proc0, Proc, Info0, Info) :-
|
|
Proc0 = c_procedure(Name, Arity, PredProcId, Instrs0),
|
|
llds_common__process_instrs(Instrs0, Instrs, Info0, Info),
|
|
Proc = c_procedure(Name, Arity, PredProcId, Instrs).
|
|
|
|
:- pred llds_common__process_instrs(list(instruction)::in,
|
|
list(instruction)::out, common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_instrs([], [], Info, Info).
|
|
llds_common__process_instrs([Uinstr0 - Comment | Instrs0],
|
|
[Uinstr - Comment | Instrs], Info0, Info) :-
|
|
llds_common__process_instr(Uinstr0, Uinstr, Info0, Info1),
|
|
llds_common__process_instrs(Instrs0, Instrs, Info1, Info).
|
|
|
|
:- pred llds_common__process_instr(instr::in, instr::out,
|
|
common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_instr(Instr0, Instr, Info0, Info) :-
|
|
(
|
|
Instr0 = comment(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = livevals(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = block(NR, NF, Instrs0),
|
|
llds_common__process_instrs(Instrs0, Instrs, Info0, Info),
|
|
Instr = block(NR, NF, Instrs)
|
|
;
|
|
Instr0 = assign(Lval, Rval0),
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info),
|
|
Instr = assign(Lval, Rval)
|
|
;
|
|
Instr0 = call(_, _, _, _),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = mkframe(_, _),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = label(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = goto(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
% unlikely to find anything to share, but why not try?
|
|
Instr0 = computed_goto(Rval0, Labels),
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info),
|
|
Instr = computed_goto(Rval, Labels)
|
|
;
|
|
Instr0 = c_code(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
% unlikely to find anything to share, but why not try?
|
|
Instr0 = if_val(Rval0, Target),
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info),
|
|
Instr = if_val(Rval, Target)
|
|
;
|
|
% unlikely to find anything to share, but why not try?
|
|
Instr0 = incr_hp(Lval, MaybeTag, Rval0, Msg),
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info),
|
|
Instr = incr_hp(Lval, MaybeTag, Rval, Msg)
|
|
;
|
|
Instr0 = mark_hp(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
% unlikely to find anything to share, but why not try?
|
|
Instr0 = restore_hp(Rval0),
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info),
|
|
Instr = restore_hp(Rval)
|
|
;
|
|
Instr0 = store_ticket(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
% unlikely to find anything to share, but why not try?
|
|
Instr0 = reset_ticket(Rval0, Reason),
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info),
|
|
Instr = reset_ticket(Rval, Reason)
|
|
;
|
|
Instr0 = discard_ticket,
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = mark_ticket_stack(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = discard_tickets_to(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = incr_sp(_, _),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = decr_sp(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = init_sync_term(_, _),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = fork(_, _, _),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = join_and_terminate(_),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = join_and_continue(_, _),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
;
|
|
Instr0 = pragma_c(_, _, _, _, _),
|
|
Instr = Instr0,
|
|
Info = Info0
|
|
).
|
|
|
|
:- pred llds_common__process_rval(rval::in, rval::out,
|
|
common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info) :-
|
|
(
|
|
Rval0 = lval(_),
|
|
Rval = Rval0,
|
|
Info = Info0
|
|
;
|
|
Rval0 = var(_),
|
|
error("var rval found in llds_common__process_rval")
|
|
;
|
|
Rval0 = create(Tag, Args, Unique, _LabelNo, _Msg),
|
|
( Unique = no ->
|
|
llds_common__process_create(Tag, Args, Rval,
|
|
Info0, Info)
|
|
;
|
|
Rval = Rval0,
|
|
Info = Info0
|
|
)
|
|
;
|
|
Rval0 = mkword(Tag, SubRval0),
|
|
llds_common__process_rval(SubRval0, SubRval, Info0, Info),
|
|
Rval = mkword(Tag, SubRval)
|
|
;
|
|
Rval0 = const(_),
|
|
Rval = Rval0,
|
|
Info = Info0
|
|
;
|
|
Rval0 = unop(Unop, SubRval0),
|
|
llds_common__process_rval(SubRval0, SubRval, Info0, Info),
|
|
Rval = unop(Unop, SubRval)
|
|
;
|
|
Rval0 = binop(Binop, Left0, Right0),
|
|
llds_common__process_rval(Left0, Left, Info0, Info1),
|
|
llds_common__process_rval(Right0, Right, Info1, Info),
|
|
Rval = binop(Binop, Left, Right)
|
|
;
|
|
Rval0 = mem_addr(MemRef0),
|
|
llds_common__process_mem_ref(MemRef0, MemRef, Info0, Info),
|
|
Rval = mem_addr(MemRef)
|
|
).
|
|
|
|
:- pred llds_common__process_mem_ref(mem_ref::in, mem_ref::out,
|
|
common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_mem_ref(stackvar_ref(N), stackvar_ref(N), Info, Info).
|
|
llds_common__process_mem_ref(framevar_ref(N), framevar_ref(N), Info, Info).
|
|
llds_common__process_mem_ref(heap_ref(Rval0, Tag, N), heap_ref(Rval, Tag, N),
|
|
Info0, Info) :-
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info).
|
|
|
|
:- pred llds_common__process_rvals(list(rval)::in, list(rval)::out,
|
|
common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_rvals([], [], Info, Info).
|
|
llds_common__process_rvals([Rval0 | Rvals0], [Rval | Rvals], Info0, Info) :-
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info1),
|
|
llds_common__process_rvals(Rvals0, Rvals, Info1, Info).
|
|
|
|
:- pred llds_common__process_maybe_rvals(list(maybe(rval))::in,
|
|
list(maybe(rval))::out, common_info::in, common_info::out) is det.
|
|
|
|
llds_common__process_maybe_rvals([], [], Info, Info).
|
|
llds_common__process_maybe_rvals([MaybeRval0 | MaybeRvals0],
|
|
[MaybeRval | MaybeRvals], Info0, Info) :-
|
|
(
|
|
MaybeRval0 = yes(Rval0),
|
|
llds_common__process_rval(Rval0, Rval, Info0, Info1),
|
|
MaybeRval = yes(Rval)
|
|
;
|
|
MaybeRval0 = no,
|
|
MaybeRval = no,
|
|
Info1 = Info0
|
|
),
|
|
llds_common__process_maybe_rvals(MaybeRvals0, MaybeRvals, Info1, Info).
|