Files
mercury/compiler/transform_llds.m
Fergus Henderson 7597790760 Use sub-modules to structure the modules in the Mercury compiler directory.
The main aim of this change is to make the overall, high-level structure
of the compiler clearer, and to encourage better encapsulation of the
major components.

compiler/libs.m:
compiler/backend_libs.m:
compiler/parse_tree.m:
compiler/hlds.m:
compiler/check_hlds.m:
compiler/transform_hlds.m:
compiler/bytecode_backend.m:
compiler/aditi_backend.m:
compiler/ml_backend.m:
compiler/ll_backend.m:
compiler/top_level.m:
	New files.  One module for each of the major components of the
	Mercury compiler.  These modules contain (as separate sub-modules)
	all the other modules in the Mercury compiler, except gcc.m and
	mlds_to_gcc.m.

Mmakefile:
compiler/Mmakefile:
	Handle the fact that the top-level module is now `top_level',
	not `mercury_compile' (since `mercury_compile' is a sub-module
	of `top_level').

compiler/Mmakefile:
	Update settings of *FLAGS-<modulename> to use the appropriate
	nested module names.

compiler/recompilation_check.m:
compiler/recompilation_version.m:
compiler/recompilation_usage.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/recompilation.version.m:
	Convert the `recompilation_*' modules into sub-modules of the
	`recompilation' module.

compiler/*.m:
compiler/*.pp:
	Module-qualify the module names in `:- module', `:- import_module',
	and `:- use_module' declarations.

compiler/base_type_info.m:
compiler/base_type_layout.m:
	Deleted these unused empty modules.

compiler/prog_data.m:
compiler/globals.m:
	Move the `foreign_language' type from prog_data to globals.

compiler/mlds.m:
compiler/ml_util.m:
compiler/mlds_to_il.m:
	Import `globals', for `foreign_language'.

Mmake.common.in:
trace/Mmakefile:
runtime/Mmakefile:
	Rename the %.check.c targets as %.check_hdr.c,
	to avoid conflicts with compiler/recompilation.check.c.
2002-03-20 12:37:56 +00:00

195 lines
6.7 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 1998-2001 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.
%-----------------------------------------------------------------------------%
%
% Module: transform_llds
%
% Main authors: petdr
%
% This module does source to source transformations of the llds data
% structure. This is sometimes necessary to avoid limits in some
% compilers.
%
% This module currently transforms computed gotos into a binary search
% down to smaller computed gotos. This avoids a limitation in the lcc
% compiler.
%
%-----------------------------------------------------------------------------%
:- module ll_backend__transform_llds.
:- interface.
:- import_module ll_backend__llds, io.
:- pred transform_llds(c_file, c_file, io__state, io__state).
:- mode transform_llds(in, out, di, uo) is det.
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module backend_libs__builtin_ops, libs__globals, libs__options.
:- import_module ll_backend__opt_util, parse_tree__prog_data.
:- import_module bool, int, list, require, std_util, counter.
transform_llds(LLDS0, LLDS) -->
globals__io_lookup_int_option(max_jump_table_size, Size),
(
{ Size = 0 }
->
{ LLDS = LLDS0 }
;
transform_c_file(LLDS0, LLDS)
).
%-----------------------------------------------------------------------------%
:- pred transform_c_file(c_file, c_file, io__state, io__state).
:- mode transform_c_file(in, out, di, uo) is det.
transform_c_file(c_file(ModuleName, HeaderInfo, A, B, C, D, Modules0),
c_file(ModuleName, HeaderInfo, A, B, C, D, Modules)) -->
transform_c_module_list(Modules0, Modules).
%-----------------------------------------------------------------------------%
:- pred transform_c_module_list(list(comp_gen_c_module),
list(comp_gen_c_module), io__state, io__state).
:- mode transform_c_module_list(in, out, di, uo) is det.
transform_c_module_list([], []) --> [].
transform_c_module_list([M0 | M0s], [M | Ms]) -->
transform_c_module(M0, M),
transform_c_module_list(M0s, Ms).
%-----------------------------------------------------------------------------%
:- pred transform_c_module(comp_gen_c_module, comp_gen_c_module,
io__state, io__state).
:- mode transform_c_module(in, out, di, uo) is det.
transform_c_module(comp_gen_c_module(Name, Procedures0),
comp_gen_c_module(Name, Procedures)) -->
transform_c_procedure_list(Procedures0, Procedures).
%-----------------------------------------------------------------------------%
:- pred transform_c_procedure_list(list(c_procedure), list(c_procedure),
io__state, io__state).
:- mode transform_c_procedure_list(in, out, di, uo) is det.
transform_c_procedure_list([], []) --> [].
transform_c_procedure_list([P0 | P0s], [P | Ps]) -->
transform_c_procedure(P0, P),
transform_c_procedure_list(P0s, Ps).
%-----------------------------------------------------------------------------%
:- pred transform_c_procedure(c_procedure, c_procedure, io__state, io__state).
:- mode transform_c_procedure(in, out, di, uo) is det.
transform_c_procedure(Proc0, Proc) -->
{ Proc0 = c_procedure(Name, Arity, PPId, Instrs0,
ProcLabel, C0, Recons) },
{ Proc = c_procedure(Name, Arity, PPId, Instrs,
ProcLabel, C, Recons) },
transform_instructions(Instrs0, ProcLabel, C0, C, Instrs).
%-----------------------------------------------------------------------------%
:- pred transform_instructions(list(instruction), proc_label, counter, counter,
list(instruction), io__state, io__state).
:- mode transform_instructions(in, in, in, out, out, di, uo) is det.
transform_instructions(Instrs0, ProcLabel, C0, C, Instrs) -->
transform_instructions_2(Instrs0, ProcLabel, C0, C, Instrs).
:- pred transform_instructions_2(list(instruction), proc_label,
counter, counter, list(instruction), io__state, io__state).
:- mode transform_instructions_2(in, in, in, out, out, di, uo) is det.
transform_instructions_2([], _, C, C, []) --> [].
transform_instructions_2([Instr0 | Instrs0], ProcLabel, C0, C, Instrs) -->
transform_instruction(Instr0, ProcLabel, C0, InstrsA, C1),
transform_instructions_2(Instrs0, ProcLabel, C1, C, InstrsB),
{ list__append(InstrsA, InstrsB, Instrs) }.
%-----------------------------------------------------------------------------%
:- pred transform_instruction(instruction, proc_label, counter,
list(instruction), counter, io__state, io__state).
:- mode transform_instruction(in, in, in, out, out, di, uo) is det.
transform_instruction(Instr0, ProcLabel, C0, Instrs, C) -->
globals__io_lookup_int_option(max_jump_table_size, Size),
(
{ Instr0 = computed_goto(_Rval, Labels) - _},
{ list__length(Labels, L) },
{ L > Size }
->
split_computed_goto(Instr0, Size, L, ProcLabel, C0, Instrs, C)
;
{ Instrs = [Instr0] },
{ C = C0 }
).
%-----------------------------------------------------------------------------%
%
% split_computed_goto(I, S, L, P, N0, Is, N)
%
% If instruction, I, is a computed_goto whose jump_table size is
% greater then S, then split the table in half and insert the
% instructions, Is, to do a binary search down to a jump_table
% whose size is sufficiently small.
%
:- pred split_computed_goto(instruction, int, int, proc_label, counter,
list(instruction), counter, io__state, io__state).
:- mode split_computed_goto(in, in, in, in, in, out, out, di, uo) is det.
split_computed_goto(Instr0, MaxSize, Length, ProcLabel, C0, Instrs, C) -->
(
{ Length =< MaxSize }
->
{ Instrs = [Instr0] },
{ C = C0 }
;
{ Instr0 = computed_goto(Rval, Labels) - _Comment }
->
{ counter__allocate(N, C0, C1) },
{ Mid = Length // 2 },
(
{ list__split_list(Mid, Labels, Start0, End0) }
->
{ Start = Start0, End = End0 }
;
{ error("split_computed_goto: list__split_list") }
),
{ Index = binop((-), Rval, const(int_const(Mid))) },
{ Test = binop((>=), Rval, const(int_const(Mid))) },
{ ElseAddr = label(local(N, ProcLabel)) },
{ ElseLabel = label(local(N, ProcLabel)) - ""},
{ IfInstr = if_val(Test, ElseAddr ) - "Binary search"},
{ ThenInstr = computed_goto(Rval, Start) - "Then section" },
{ ElseInstr = computed_goto(Index, End) - "Else section" },
split_computed_goto(ThenInstr, MaxSize, Mid, ProcLabel, C1,
ThenInstrs, C2),
split_computed_goto(ElseInstr, MaxSize, Length - Mid,
ProcLabel, C2, ElseInstrs, C),
{ list__append(ThenInstrs, [ElseLabel | ElseInstrs], InstrsA) },
{ Instrs = [IfInstr | InstrsA] }
;
{ error("split_computed_goto") }
).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%