mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-19 15:54:18 +00:00
det_analysis: Added some code to fix up disjunctions that have at most one solution. We now transform a disjunction to an if-then-else only if the disjunction is locally nondet. If the disjunction cannot fail, we replace it with a disjunct that cannot fail and issue a warning; we issue a warning in several other cases as well. mercury_to_mercury: Fix two duplicate fact bugs pointed out by the new det_analysis. peephole: Add a new optimization: a stack frame teardown followed by a conditional branch to a label that builds a stack frame is now replaced by code that starts with the conditional branch to the code after the stack frame setup, and has the stack frame teardown only in the fall through code. This optimization is applied only after frameopt. opt_util: Export a previously internal predicate for use by peephole. optimize, value_number: Conform to the new interface of peephole. frameopt: Add some debugging code (now commented out) that helped in making the above optimization. prog_io: Cosmetic changes.
243 lines
6.9 KiB
ObjectPascal
243 lines
6.9 KiB
ObjectPascal
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1995 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.
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% optimize.m - LLDS to LLDS optimizations.
|
|
|
|
% Main author: zs.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module optimize.
|
|
|
|
:- interface.
|
|
|
|
:- import_module llds, io, options.
|
|
|
|
:- pred optimize__main(list(c_procedure), list(c_procedure),
|
|
io__state, io__state).
|
|
:- mode optimize__main(in, out, di, uo) is det.
|
|
|
|
:- pred optimize__proc(c_procedure, c_procedure, io__state, io__state).
|
|
:- mode optimize__proc(in, out, di, uo) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module jumpopt, labelopt, dupelim, frameopt, peephole, value_number.
|
|
:- import_module globals, opt_util, opt_debug.
|
|
:- import_module list, map, bimap, int, std_util.
|
|
|
|
optimize__main([], []) --> [].
|
|
optimize__main([Proc0|Procs0], [Proc|Procs]) -->
|
|
optimize__proc(Proc0, Proc),
|
|
optimize__main(Procs0, Procs).
|
|
|
|
optimize__proc(c_procedure(Name, Arity, Mode, Instrs0),
|
|
c_procedure(Name, Arity, Mode, Instrs)) -->
|
|
globals__io_lookup_int_option(optimize_repeat, AllRepeat),
|
|
globals__io_lookup_int_option(optimize_vnrepeat, VnRepeat),
|
|
{ NovnRepeat is AllRepeat - VnRepeat },
|
|
optimize__repeat(NovnRepeat, no, Instrs0, Instrs1),
|
|
optimize__repeat(VnRepeat, yes, Instrs1, Instrs2),
|
|
optimize__nonrepeat(Instrs2, Instrs),
|
|
#if NU_PROLOG
|
|
{ putprop(opt, opt, Instrs) },
|
|
{ fail }.
|
|
optimize__proc(c_procedure(Name, Arity, Mode, Instrs0),
|
|
c_procedure(Name, Arity, Mode, Instrs)) -->
|
|
{ getprop(opt, opt, Instrs, Ref) },
|
|
{ erase(Ref) },
|
|
globals__io_lookup_bool_option(statistics, Statistics),
|
|
maybe_report_stats(Statistics),
|
|
#endif
|
|
{ true }.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred optimize__repeat(int, bool, list(instruction), list(instruction),
|
|
io__state, io__state).
|
|
:- mode optimize__repeat(in, in, in, out, di, uo) is det.
|
|
|
|
optimize__repeat(Iter0, DoVn, Instrs0, Instrs) -->
|
|
(
|
|
{ Iter0 > 0 }
|
|
->
|
|
{ bimap__init(TeardownMap) },
|
|
optimize__repeated(Instrs0, DoVn, no, TeardownMap,
|
|
Instrs1, Mod),
|
|
( { Mod = yes } ->
|
|
{ Iter1 is Iter0 - 1 },
|
|
optimize__repeat(Iter1, DoVn, Instrs1, Instrs)
|
|
;
|
|
{ Instrs = Instrs1 }
|
|
)
|
|
;
|
|
{ Instrs = Instrs0 }
|
|
).
|
|
|
|
% We short-circuit jump sequences before normal peepholing
|
|
% to create more opportunities for use of the tailcall macro.
|
|
|
|
:- pred optimize__repeated(list(instruction), bool, bool,
|
|
bimap(label, label), list(instruction), bool, io__state, io__state).
|
|
:- mode optimize__repeated(in, in, in, in, out, out, di, uo) is det.
|
|
|
|
optimize__repeated(Instrs0, DoVn, Final, TeardownMap, Instrs, Mod) -->
|
|
globals__io_lookup_bool_option(very_verbose, VeryVerbose),
|
|
{ opt_util__find_first_label(Instrs0, Label) },
|
|
{ opt_util__format_label(Label, LabelStr) },
|
|
|
|
globals__io_lookup_bool_option(optimize_value_number, ValueNumber),
|
|
( { ValueNumber = yes, DoVn = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing value number for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
value_number__main(Instrs0, Instrs1)
|
|
;
|
|
{ Instrs1 = Instrs0 }
|
|
),
|
|
globals__io_lookup_bool_option(optimize_jumps, Jumpopt),
|
|
globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt),
|
|
( { Jumpopt = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing jumps for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ jumpopt__main(Instrs1, FullJumpopt, Final, Instrs2, Mod1) }
|
|
;
|
|
{ Instrs2 = Instrs1 },
|
|
{ Mod1 = no }
|
|
),
|
|
globals__io_lookup_bool_option(optimize_peep, Peephole),
|
|
( { Peephole = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing locally for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ peephole__optimize(Instrs2, Instrs3, TeardownMap, Final,
|
|
Mod2) }
|
|
;
|
|
{ Instrs3 = Instrs2 },
|
|
{ Mod2 = no }
|
|
),
|
|
globals__io_lookup_bool_option(optimize_labels, LabelElim),
|
|
( { LabelElim = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing labels for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ labelopt__main(Instrs3, Final, Instrs4, Mod3) }
|
|
;
|
|
{ Instrs4 = Instrs3 },
|
|
{ Mod3 = no }
|
|
),
|
|
globals__io_lookup_bool_option(optimize_dups, DupElim),
|
|
( { DupElim = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing duplicates for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ dupelim__main(Instrs4, Instrs) }
|
|
;
|
|
{ Instrs = Instrs4 }
|
|
),
|
|
{ Mod1 = no, Mod2 = no, Mod3 = no, Instrs = Instrs0 ->
|
|
Mod = no
|
|
;
|
|
Mod = yes
|
|
},
|
|
globals__io_lookup_bool_option(statistics, Statistics),
|
|
maybe_report_stats(Statistics),
|
|
#if NU_PROLOG
|
|
{ putprop(opt, opt, Instrs - Mod) },
|
|
{ fail }.
|
|
optimize__repeated(Instrs0, _, _, Instrs, Mod) -->
|
|
{ getprop(opt, opt, Instrs - Mod, Ref) },
|
|
{ erase(Ref) },
|
|
globals__io_lookup_bool_option(statistics, Statistics),
|
|
maybe_report_stats(Statistics),
|
|
#endif
|
|
{ true }.
|
|
|
|
:- pred optimize__nonrepeat(list(instruction), list(instruction),
|
|
io__state, io__state).
|
|
:- mode optimize__nonrepeat(in, out, di, uo) is det.
|
|
|
|
optimize__nonrepeat(Instrs0, Instrs) -->
|
|
globals__io_lookup_bool_option(very_verbose, VeryVerbose),
|
|
{ opt_util__find_first_label(Instrs0, Label) },
|
|
{ opt_util__format_label(Label, LabelStr) },
|
|
|
|
globals__io_lookup_bool_option(optimize_frames, FrameOpt),
|
|
( { FrameOpt = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing frames for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
globals__io_lookup_bool_option(optimize_delay_slot, DelaySlot),
|
|
{ frameopt__main(Instrs0, Instrs1, DelaySlot, TeardownMap, _) }
|
|
;
|
|
{ Instrs1 = Instrs0 },
|
|
{ bimap__init(TeardownMap) }
|
|
),
|
|
globals__io_lookup_bool_option(optimize_peep, Peephole),
|
|
( { FrameOpt = yes, Peephole = yes } ->
|
|
% get rid of useless incr_sp/decr_sp pairs
|
|
{ peephole__optimize(Instrs1, Instrs2, TeardownMap, yes, _) }
|
|
;
|
|
{ Instrs2 = Instrs1 }
|
|
),
|
|
globals__io_lookup_bool_option(optimize_value_number, ValueNumber),
|
|
( { ValueNumber = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing post value number for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ value_number__post_main(Instrs2, Instrs3) }
|
|
;
|
|
{ Instrs3 = Instrs2 }
|
|
),
|
|
( { FrameOpt = yes ; ValueNumber = yes } ->
|
|
optimize__repeated(Instrs3, no, yes, TeardownMap,
|
|
Instrs4, RepMod),
|
|
( { RepMod = yes, FrameOpt = yes, Peephole = yes } ->
|
|
{ bimap__init(Empty2) },
|
|
{ peephole__optimize(Instrs4, Instrs5, Empty2, yes, _) }
|
|
;
|
|
{ Instrs5 = Instrs4 }
|
|
),
|
|
( { frameopt__is_succip_restored(Instrs4) } ->
|
|
{ Instrs = Instrs5 }
|
|
;
|
|
{ frameopt__dont_save_succip(Instrs5, Instrs) }
|
|
)
|
|
;
|
|
{ Instrs = Instrs3 }
|
|
).
|