mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-15 13:55:07 +00:00
Estimated hours taken: 20 Branches: main Add a new optimization, --use-local-vars, to the LLDS backend. This optimization is intended to replace references to fake registers and stack slots with references to temporary variables in C code, since accessing these should be cheaper. With this optimization and one for delaying construction unifications, the eager code generator should generate code at least good as that produced by the old value numbering pass. This should make it possible to get rid of value numbering, which is much harder to maintain. compiler/use_local_vars.m: New module containing the optimization. compiler/notes/compiler_design.html: Mention the new module. compiler/exprn_aux.m: Add new utility predicates for use by use_local_vars. If --debug-opt is specified, do not dump instruction sequences to standard output. Instead, put them in separate files, where they can be compared more easily. compiler/options.m: Add the --use-local-vars option to control whether the use_local_vars pass gets run. compiler/llds.m: Add liveness information to the c_code and pragma_foreign_code LLDS instructions, in order to allow use_local_vars to work in the presence of automatically-generated C code (e.g. by debugging). compiler/livemap.m: Use the new liveness information to generate useful livemap information even in the presence of automatically generated C code. compiler/code_gen.m: compiler/code_info.m: compiler/dupelim.m: compiler/frameopt.m: compiler/llds_common.m: compiler/llds_out.m: compiler/middle_rec.m: compiler/opt_debug.m: compiler/opt_util.m: compiler/pragma_c_gen.m: compiler/trace.m: compiler/vn_block.m: compiler/vn_cost.m: compiler/vn_filter.m: compiler/vn_verify.m: Provide and/or ignore this additional liveness information. compiler/wrap_block.m: The post_value_number pass wraps LLDS instruction sequences using temporaries in a block instruction which actually declares those temporaries. It used to be used only by value numbering; it is now also used by use_local_vars. It has therefore been renamed and put in its own file. compiler/optimize.m: Invoke use_local_vars if required, and call wrap_blocks instead of post_value_number. compiler/value_number.m: Since the value numbering pass still cannot handle automatically generated C code, check for it explicitly now that livemap carries out only a weaker check. compiler/basic_block.m: Add a module qualification. library/set.m: library/set_bbbtree.m: library/set_ordlist.m: library/set_unordlist.m: Add a new predicate, union_list, to each implementation of sets, for use by some of the new code above. tests/general/array_test.m: Print out the result of each operation as soon as it is done, so that if you get a seg fault, you know which operations have completed and which haven't.
469 lines
15 KiB
Mathematica
469 lines
15 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1996-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.
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% optimize.m - LLDS to LLDS optimizations.
|
|
|
|
% Main author: zs.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module optimize.
|
|
|
|
:- interface.
|
|
|
|
:- import_module llds.
|
|
:- import_module io, list.
|
|
|
|
:- pred optimize_main(list(c_procedure)::in, global_data::in,
|
|
list(c_procedure)::out, io__state::di, io__state::uo) is det.
|
|
|
|
:- pred optimize__proc(c_procedure::in, global_data::in,
|
|
c_procedure::out, io__state::di, io__state::uo) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module jumpopt, labelopt, dupelim, peephole.
|
|
:- import_module frameopt, delay_slot, value_number, use_local_vars, options.
|
|
:- import_module globals, passes_aux, opt_util, opt_debug, vn_debug.
|
|
:- import_module wrap_blocks, hlds_pred, llds_out, continuation_info.
|
|
|
|
:- import_module bool, int, string.
|
|
:- import_module map, bimap, set, std_util, require, counter.
|
|
|
|
optimize_main([], _, []) --> [].
|
|
optimize_main([Proc0 | Procs0], GlobalData, [Proc | Procs]) -->
|
|
optimize__proc(Proc0, GlobalData, Proc),
|
|
optimize_main(Procs0, GlobalData, Procs).
|
|
|
|
optimize__proc(CProc0, GlobalData, CProc) -->
|
|
{ CProc0 = c_procedure(Name, Arity, PredProcId, Instrs0,
|
|
ProcLabel, C0, ContainsReconstruction) },
|
|
optimize__init_opt_debug_info(Name, Arity, PredProcId, Instrs0, C0,
|
|
OptDebugInfo0),
|
|
globals__io_lookup_int_option(optimize_repeat, AllRepeat),
|
|
globals__io_lookup_int_option(optimize_vnrepeat, VnRepeat),
|
|
globals__io_lookup_bool_option(optimize_value_number, ValueNumber),
|
|
{
|
|
global_data_maybe_get_proc_layout(GlobalData, PredProcId,
|
|
ProcLayout)
|
|
->
|
|
LabelMap = ProcLayout^internal_map,
|
|
map__sorted_keys(LabelMap, LayoutLabels),
|
|
set__sorted_list_to_set(LayoutLabels, LayoutLabelSet)
|
|
;
|
|
set__init(LayoutLabelSet)
|
|
},
|
|
( { ValueNumber = yes } ->
|
|
{ NovnRepeat is AllRepeat - VnRepeat },
|
|
optimize__repeat(NovnRepeat, no, ContainsReconstruction,
|
|
LayoutLabelSet, Instrs0, ProcLabel, C0, C1,
|
|
OptDebugInfo0, OptDebugInfo1, Instrs1),
|
|
optimize__middle(Instrs1, no, LayoutLabelSet, ProcLabel,
|
|
C1, C2, OptDebugInfo1, OptDebugInfo2, Instrs2),
|
|
optimize__repeat(VnRepeat, yes, ContainsReconstruction,
|
|
LayoutLabelSet, Instrs2, ProcLabel, C2, C,
|
|
OptDebugInfo2, OptDebugInfo, Instrs3)
|
|
;
|
|
optimize__repeat(AllRepeat, no, ContainsReconstruction,
|
|
LayoutLabelSet, Instrs0, ProcLabel, C0, C1,
|
|
OptDebugInfo0, OptDebugInfo1, Instrs1),
|
|
optimize__middle(Instrs1, yes, LayoutLabelSet, ProcLabel,
|
|
C1, C, OptDebugInfo1, OptDebugInfo, Instrs3)
|
|
),
|
|
optimize__last(Instrs3, LayoutLabelSet, C, OptDebugInfo, Instrs),
|
|
{ CProc = c_procedure(Name, Arity, PredProcId, Instrs,
|
|
ProcLabel, C, ContainsReconstruction) }.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- type opt_debug_info
|
|
---> opt_debug_info(
|
|
string, % base file name
|
|
int % last file number written
|
|
)
|
|
; no_opt_debug_info.
|
|
|
|
:- pred optimize__init_opt_debug_info(string::in, int::in, pred_proc_id::in,
|
|
list(instruction)::in, counter::in, opt_debug_info::out,
|
|
io__state::di, io__state::uo) is det.
|
|
|
|
optimize__init_opt_debug_info(Name, Arity, PredProcId, Instrs0, Counter,
|
|
OptDebugInfo) -->
|
|
globals__io_lookup_bool_option(debug_opt, DebugOpt),
|
|
(
|
|
{ DebugOpt = yes },
|
|
{ llds_out__name_mangle(Name, MangledName) },
|
|
{ PredProcId = proc(PredId, ProcId) },
|
|
{ pred_id_to_int(PredId, PredIdInt) },
|
|
{ proc_id_to_int(ProcId, ProcIdInt) },
|
|
{ string__int_to_string(Arity, ArityStr) },
|
|
{ string__int_to_string(PredIdInt, PredIdStr) },
|
|
{ string__int_to_string(ProcIdInt, ProcIdStr) },
|
|
{ string__append_list([MangledName, "_", ArityStr,
|
|
".pred", PredIdStr, ".proc", ProcIdStr], BaseName) },
|
|
{ OptDebugInfo = opt_debug_info(BaseName, 0) },
|
|
|
|
{ string__append_list([BaseName, ".opt0"], FileName) },
|
|
io__tell(FileName, Res),
|
|
( { Res = ok } ->
|
|
{ counter__allocate(NextLabel, Counter, _) },
|
|
opt_debug__msg(yes, NextLabel, "before optimization"),
|
|
opt_debug__dump_instrs(yes, Instrs0),
|
|
io__told
|
|
;
|
|
{ string__append("cannot open ", FileName, ErrorMsg) },
|
|
{ error(ErrorMsg) }
|
|
)
|
|
;
|
|
{ DebugOpt = no },
|
|
{ OptDebugInfo = no_opt_debug_info }
|
|
).
|
|
|
|
:- pred optimize__maybe_opt_debug(list(instruction)::in, counter::in,
|
|
string::in, opt_debug_info::in, opt_debug_info::out,
|
|
io__state::di, io__state::uo) is det.
|
|
|
|
optimize__maybe_opt_debug(Instrs, Counter, Msg,
|
|
OptDebugInfo0, OptDebugInfo) -->
|
|
(
|
|
{ OptDebugInfo0 = opt_debug_info(BaseName, OptNum0) },
|
|
{ OptNum = OptNum0 + 1 },
|
|
{ string__int_to_string(OptNum0, OptNum0Str) },
|
|
{ string__int_to_string(OptNum, OptNumStr) },
|
|
{ string__append_list([BaseName, ".opt", OptNum0Str],
|
|
OptFileName0) },
|
|
{ string__append_list([BaseName, ".opt", OptNumStr],
|
|
OptFileName) },
|
|
{ string__append_list([BaseName, ".diff", OptNumStr],
|
|
DiffFileName) },
|
|
io__tell(OptFileName, Res),
|
|
( { Res = ok } ->
|
|
{ counter__allocate(NextLabel, Counter, _) },
|
|
opt_debug__msg(yes, NextLabel, Msg),
|
|
opt_debug__dump_instrs(yes, Instrs),
|
|
io__told
|
|
;
|
|
{ string__append("cannot open ", OptFileName,
|
|
ErrorMsg) },
|
|
{ error(ErrorMsg) }
|
|
),
|
|
% Although the -u is not fully portable, it is available
|
|
% on all the systems we intend to use it on, and the main user
|
|
% of --debug-opt (zs) strongly prefers -u to -c.
|
|
{ string__append_list(["diff -u ",
|
|
OptFileName0, " ", OptFileName,
|
|
" > ", DiffFileName], DiffCommand) },
|
|
io__call_system(DiffCommand, _),
|
|
{ OptDebugInfo = opt_debug_info(BaseName, OptNum) }
|
|
;
|
|
{ OptDebugInfo0 = no_opt_debug_info },
|
|
{ OptDebugInfo = no_opt_debug_info }
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred optimize__repeat(int::in, bool::in, contains_reconstruction::in,
|
|
set(label)::in, list(instruction)::in, proc_label::in,
|
|
counter::in, counter::out, opt_debug_info::in, opt_debug_info::out,
|
|
list(instruction)::out,
|
|
io__state::di, io__state::uo) is det.
|
|
|
|
optimize__repeat(Iter0, DoVn, ContainsReconstruction, LayoutLabelSet, Instrs0,
|
|
ProcLabel, C0, C, OptDebugInfo0, OptDebugInfo, Instrs) -->
|
|
( { Iter0 > 0 } ->
|
|
{ Iter1 = Iter0 - 1 },
|
|
( { Iter1 = 0 } ->
|
|
{ Final = yes }
|
|
;
|
|
{ Final = no }
|
|
),
|
|
optimize__repeated(Instrs0, DoVn, ContainsReconstruction,
|
|
Final, LayoutLabelSet, ProcLabel, C0, C1,
|
|
OptDebugInfo0, OptDebugInfo1, Instrs1, Mod),
|
|
( { Mod = yes } ->
|
|
optimize__repeat(Iter1, DoVn, ContainsReconstruction,
|
|
LayoutLabelSet, Instrs1, ProcLabel, C1, C,
|
|
OptDebugInfo1, OptDebugInfo, Instrs)
|
|
;
|
|
{ Instrs = Instrs1 },
|
|
{ C = C1 },
|
|
{ OptDebugInfo = OptDebugInfo0 }
|
|
)
|
|
;
|
|
{ Instrs = Instrs0 },
|
|
{ C = C0 },
|
|
{ OptDebugInfo = OptDebugInfo0 }
|
|
).
|
|
|
|
% We short-circuit jump sequences before normal peepholing
|
|
% to create more opportunities for use of the tailcall macro.
|
|
|
|
:- pred optimize__repeated(list(instruction)::in, bool::in,
|
|
contains_reconstruction::in, bool::in, set(label)::in,
|
|
proc_label::in, counter::in, counter::out,
|
|
opt_debug_info::in, opt_debug_info::out, list(instruction)::out,
|
|
bool::out, io__state::di, io__state::uo) is det.
|
|
|
|
optimize__repeated(Instrs0, DoVn, ContainsReconstruction, Final,
|
|
LayoutLabelSet, ProcLabel, C0, C, OptDebugInfo0, OptDebugInfo,
|
|
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, ContainsReconstruction,
|
|
LayoutLabelSet, ProcLabel, C0, C1, Instrs1),
|
|
optimize__maybe_opt_debug(Instrs1, C1, "after value numbering",
|
|
OptDebugInfo0, OptDebugInfo1)
|
|
;
|
|
{ Instrs1 = Instrs0 },
|
|
{ C1 = C0 },
|
|
{ OptDebugInfo1 = OptDebugInfo0 }
|
|
),
|
|
globals__io_lookup_bool_option(optimize_jumps, Jumpopt),
|
|
globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt),
|
|
globals__io_lookup_bool_option(checked_nondet_tailcalls,
|
|
CheckedNondetTailCalls),
|
|
globals__io_get_trace_level(TraceLevel),
|
|
( { Jumpopt = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing jumps for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ jumpopt_main(Instrs1, LayoutLabelSet, TraceLevel, ProcLabel,
|
|
C1, C2, FullJumpopt, Final, CheckedNondetTailCalls,
|
|
Instrs2, Mod1) },
|
|
optimize__maybe_opt_debug(Instrs2, C2, "after jump opt",
|
|
OptDebugInfo1, OptDebugInfo2)
|
|
;
|
|
{ Instrs2 = Instrs1 },
|
|
{ C2 = C1 },
|
|
{ OptDebugInfo2 = OptDebugInfo1 },
|
|
{ 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")
|
|
;
|
|
[]
|
|
),
|
|
globals__io_get_gc_method(GC_Method),
|
|
{ peephole__optimize(GC_Method, Instrs2, Instrs3, Mod2) },
|
|
optimize__maybe_opt_debug(Instrs3, C2, "after peephole",
|
|
OptDebugInfo2, OptDebugInfo3)
|
|
;
|
|
{ Instrs3 = Instrs2 },
|
|
{ OptDebugInfo3 = OptDebugInfo2 },
|
|
{ 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, LayoutLabelSet,
|
|
Instrs4, Mod3) },
|
|
optimize__maybe_opt_debug(Instrs4, C2, "after label opt",
|
|
OptDebugInfo3, OptDebugInfo4)
|
|
;
|
|
{ Instrs4 = Instrs3 },
|
|
{ OptDebugInfo4 = OptDebugInfo3 },
|
|
{ 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, ProcLabel, C2, C, Instrs) },
|
|
optimize__maybe_opt_debug(Instrs, C, "after duplicates",
|
|
OptDebugInfo4, OptDebugInfo)
|
|
;
|
|
{ Instrs = Instrs4 },
|
|
{ OptDebugInfo = OptDebugInfo4 },
|
|
{ C = C2 }
|
|
),
|
|
{ Mod1 = no, Mod2 = no, Mod3 = no, Instrs = Instrs0 ->
|
|
Mod = no
|
|
;
|
|
Mod = yes
|
|
},
|
|
globals__io_lookup_bool_option(statistics, Statistics),
|
|
maybe_report_stats(Statistics).
|
|
|
|
:- pred optimize__middle(list(instruction)::in, bool::in, set(label)::in,
|
|
proc_label::in, counter::in, counter::out,
|
|
opt_debug_info::in, opt_debug_info::out, list(instruction)::out,
|
|
io__state::di, io__state::uo) is det.
|
|
|
|
optimize__middle(Instrs0, Final, LayoutLabelSet, ProcLabel, C0, C,
|
|
OptDebugInfo0, OptDebugInfo, 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")
|
|
;
|
|
[]
|
|
),
|
|
{ frameopt_main(Instrs0, ProcLabel, C0, C1, Instrs1,
|
|
Mod1, Jumps) },
|
|
optimize__maybe_opt_debug(Instrs1, C1, "after frame opt",
|
|
OptDebugInfo0, OptDebugInfo1),
|
|
globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt),
|
|
globals__io_lookup_bool_option(checked_nondet_tailcalls,
|
|
CheckedNondetTailCalls),
|
|
globals__io_get_trace_level(TraceLevel),
|
|
( { Jumps = yes, FullJumpopt = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing jumps for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ jumpopt_main(Instrs1, LayoutLabelSet, TraceLevel,
|
|
ProcLabel, C1, C2, FullJumpopt, Final,
|
|
CheckedNondetTailCalls, Instrs2, _Mod2) },
|
|
optimize__maybe_opt_debug(Instrs2, C2, "after jumps",
|
|
OptDebugInfo1, OptDebugInfo2)
|
|
;
|
|
{ Instrs2 = Instrs1 },
|
|
{ OptDebugInfo2 = OptDebugInfo1 },
|
|
{ C2 = C1 }
|
|
),
|
|
( { Mod1 = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing labels for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ labelopt_main(Instrs2, Final, LayoutLabelSet,
|
|
Instrs3, _Mod3) },
|
|
optimize__maybe_opt_debug(Instrs3, C2, "after labels",
|
|
OptDebugInfo2, OptDebugInfo3)
|
|
;
|
|
{ OptDebugInfo3 = OptDebugInfo2 },
|
|
{ Instrs3 = Instrs2 }
|
|
)
|
|
;
|
|
{ Instrs3 = Instrs0 },
|
|
{ OptDebugInfo3 = OptDebugInfo0 },
|
|
{ C2 = C0 }
|
|
),
|
|
globals__io_lookup_bool_option(use_local_vars, UseLocalVars),
|
|
(
|
|
{ UseLocalVars = yes },
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing local vars for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
globals__io_lookup_int_option(num_real_r_regs, NumRealRRegs),
|
|
{ use_local_vars__main(Instrs3, Instrs,
|
|
ProcLabel, NumRealRRegs, C2, C) },
|
|
optimize__maybe_opt_debug(Instrs, C, "after use_local_vars",
|
|
OptDebugInfo3, OptDebugInfo)
|
|
;
|
|
{ UseLocalVars = no },
|
|
{ Instrs = Instrs3 },
|
|
{ OptDebugInfo = OptDebugInfo3 },
|
|
{ C = C2 }
|
|
).
|
|
|
|
:- pred optimize__last(list(instruction)::in, set(label)::in,
|
|
counter::in, opt_debug_info::in, list(instruction)::out,
|
|
io__state::di, io__state::uo) is det.
|
|
|
|
optimize__last(Instrs0, LayoutLabelSet, C, OptDebugInfo0, 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_delay_slot, DelaySlot),
|
|
globals__io_lookup_bool_option(optimize_value_number, ValueNumber),
|
|
globals__io_lookup_bool_option(use_local_vars, UseLocalVars),
|
|
( { DelaySlot = yes ; ValueNumber = yes ; UseLocalVars = yes } ->
|
|
% We must get rid of any extra labels added by other passes,
|
|
% since they can confuse both wrap_blocks and delay_slot.
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing labels for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ labelopt_main(Instrs0, no, LayoutLabelSet, Instrs1, _Mod1) },
|
|
optimize__maybe_opt_debug(Instrs1, C, "after label opt",
|
|
OptDebugInfo0, OptDebugInfo1)
|
|
;
|
|
{ OptDebugInfo1 = OptDebugInfo0 },
|
|
{ Instrs1 = Instrs0 }
|
|
),
|
|
( { DelaySlot = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing delay slot for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ fill_branch_delay_slot(Instrs1, Instrs2) },
|
|
optimize__maybe_opt_debug(Instrs2, C, "after delay slots",
|
|
OptDebugInfo1, OptDebugInfo2)
|
|
;
|
|
{ OptDebugInfo2 = OptDebugInfo1 },
|
|
{ Instrs2 = Instrs1 }
|
|
),
|
|
( { ValueNumber = yes ; UseLocalVars = yes } ->
|
|
( { VeryVerbose = yes } ->
|
|
io__write_string("% Optimizing post value number for "),
|
|
io__write_string(LabelStr),
|
|
io__write_string("\n")
|
|
;
|
|
[]
|
|
),
|
|
{ wrap_blocks(Instrs2, Instrs) },
|
|
optimize__maybe_opt_debug(Instrs, C, "after wrap blocks",
|
|
OptDebugInfo2, _OptDebugInfo)
|
|
;
|
|
{ Instrs = Instrs1 }
|
|
).
|