mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-15 22:03:26 +00:00
code_gen.pp: Put the comment about the contents of stack slots before the initial label, since this way it will be preserved by optimizations. cse_detection.m: Extended the search to look for cses in if-then-elses and switches as well as disjunctions. Removed InstmapDelta from preds in which it was not being used. det_analysis.m: Make the diagnosis routines more robust. The changes here avoid the Philip's problems with lexical.m. jumpopt.m: Minor formatting changes. livemap.m: Avoid duplicating livevals instructions when optimizations are repeated, since this can confuse some optimizations. llds.m: Minor documentation change. make_hlds.m: Minor formatting change. mercury_compile.pp: Do not map arguments to registers if any semantic errors have been found. middle_rec.m and code_aux.m: Apply middle recursion only if tail recursion is not possible, since tail recursion yields more efficient code. opt_util.m: Added a predicate to recognize constant conditions in if_vals. Modified a predicate to make it better suited for frameopt. optimize.pp: Changed the way optimizations were repeated to allow better control. Repeat peephole once more after frameopt, since the new frameopt can benefit from this. options.m: Removed the --compile-to-c option, which was obsolete. Added an option for predicate-wide value numbering, which is off by default. Changed some of the default values of optimization flags to reduce compilation time while holding the loss of speed of generated code to a minimum. peephole.m: Look for if_vals whose conditions are constants, and eliminate the if_val or turn it into a goto depending on the value of the constant. Generalized the condition for optimizing incr_sp/decr_sp pairs. value_number.m: Added a prepass to separate primary tag tests in if-then-elses from the test of the secondary tag, which requires dereferencing the pointer. Added sanity check routines to test two aspects of the generated code. First, whether it produces the same values for the live variables as the original code, and second, whether it has moved any dereferences of a pointer before a test of the tag of that pointer. If either test fails, we use the old instruction sequence. vn_debug.m: New messages to announce the failure of the sanity checks. They are enabled by default, but of course can only appear if value numbering is turned on (it is still off by default). vn_flush.m: Threaded a list of forbidden lvals (lvals that may not be assigned to) through the flushing routines. When saving the old value of an lval that is being assigned to, we use this list to avoid modifying any of the values used on the right hand side of the assignment, even if the saving of an old value results in assignment that requires another save, and so on recursively. When the flushing of a node_lval referred to a shared vn, the uses of the access vns of the node_lvals were not being adjusted properly. Now they are. vn_order.m: The ctrl_vn phase of the ordering was designed to ensure that all nodes that need not come before a control node come after it. However, nodes were created after this phase operated, causing leakage of some value nodes in front of control nodes. Some of these led to pointer dereferences before tag tests, causing bus errors. The ctrl_vn phase is now last to avoid this problem. vn_table.m: Added an extra interface predicate to support the sanity checks in value_number. vn_util.m: The transformation of c1-e2 into (0-e2)+c1 during vnrval simplification could lead to an infinite loop in the compiler if c1 was zero. A test for this case now prevents the loop.
422 lines
15 KiB
Mathematica
422 lines
15 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% 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.
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% vn_table.m - predicates for managing vn tables.
|
|
|
|
% author: zs.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module vn_table.
|
|
|
|
:- interface.
|
|
|
|
:- import_module vn_type.
|
|
:- import_module list, map.
|
|
|
|
% The definitions of the types are exported only for debugging.
|
|
|
|
:- type lval_to_vn_table == map(vnlval, vn).
|
|
:- type rval_to_vn_table == map(vnrval, vn).
|
|
:- type vn_to_rval_table == map(vn, vnrval).
|
|
:- type vn_to_uses_table == map(vn, list(vn_src)).
|
|
:- type vn_to_locs_table == map(vn, list(vnlval)).
|
|
:- type loc_to_vn_table == map(vnlval, vn).
|
|
|
|
:- type vn_tables ---> vn_tables(vn,
|
|
lval_to_vn_table, rval_to_vn_table,
|
|
vn_to_rval_table, vn_to_uses_table,
|
|
vn_to_locs_table, loc_to_vn_table).
|
|
|
|
:- pred vn__init_tables(vn_tables).
|
|
:- mode vn__init_tables(out) is det.
|
|
|
|
:- pred vn__lookup_desired_value(vnlval, vn, string, vn_tables).
|
|
:- mode vn__lookup_desired_value(in, out, in, in) is det.
|
|
|
|
:- pred vn__lookup_assigned_vn(vnrval, vn, string, vn_tables).
|
|
:- mode vn__lookup_assigned_vn(in, out, in, in) is det.
|
|
|
|
:- pred vn__lookup_defn(vn, vnrval, string, vn_tables).
|
|
:- mode vn__lookup_defn(in, out, in, in) is det.
|
|
|
|
:- pred vn__lookup_uses(vn, list(vn_src), string, vn_tables).
|
|
:- mode vn__lookup_uses(in, out, in, in) is det.
|
|
|
|
:- pred vn__lookup_current_locs(vn, list(vnlval), string, vn_tables).
|
|
:- mode vn__lookup_current_locs(in, out, in, in) is det.
|
|
|
|
:- pred vn__lookup_current_value(vnlval, vn, string, vn_tables).
|
|
:- mode vn__lookup_current_value(in, out, in, in) is det.
|
|
|
|
:- pred vn__search_desired_value(vnlval, vn, vn_tables).
|
|
:- mode vn__search_desired_value(in, out, in) is semidet.
|
|
|
|
:- pred vn__search_assigned_vn(vnrval, vn, vn_tables).
|
|
:- mode vn__search_assigned_vn(in, out, in) is semidet.
|
|
|
|
:- pred vn__search_defn(vn, vnrval, vn_tables).
|
|
:- mode vn__search_defn(in, out, in) is semidet.
|
|
|
|
:- pred vn__search_uses(vn, list(vn_src), vn_tables).
|
|
:- mode vn__search_uses(in, out, in) is semidet.
|
|
|
|
:- pred vn__search_current_locs(vn, list(vnlval), vn_tables).
|
|
:- mode vn__search_current_locs(in, out, in) is semidet.
|
|
|
|
:- pred vn__search_current_value(vnlval, vn, vn_tables).
|
|
:- mode vn__search_current_value(in, out, in) is semidet.
|
|
|
|
:- pred vn__get_vnlval_vn_list(vn_tables, assoc_list(vnlval, vn)).
|
|
:- mode vn__get_vnlval_vn_list(in, out) is det.
|
|
|
|
:- pred vn__add_new_use(vn, vn_src, vn_tables, vn_tables).
|
|
:- mode vn__add_new_use(in, in, di, uo) is det.
|
|
|
|
:- pred vn__del_old_use(vn, vn_src, vn_tables, vn_tables).
|
|
:- mode vn__del_old_use(in, in, di, uo) is det.
|
|
|
|
:- pred vn__del_old_uses(list(vn), vn_src, vn_tables, vn_tables).
|
|
:- mode vn__del_old_uses(in, in, di, uo) is det.
|
|
|
|
:- pred vn__record_first_vnrval(vnrval, vn, vn_tables, vn_tables).
|
|
:- mode vn__record_first_vnrval(in, out, di, uo) is det.
|
|
|
|
:- pred vn__record_first_vnlval(vnlval, vn, vn_tables, vn_tables).
|
|
:- mode vn__record_first_vnlval(in, out, di, uo) is det.
|
|
|
|
:- pred vn__set_desired_value(vnlval, vn, vn_tables, vn_tables).
|
|
:- mode vn__set_desired_value(in, in, di, uo) is det.
|
|
|
|
:- pred vn__set_current_value(vnlval, vn, vn_tables, vn_tables).
|
|
:- mode vn__set_current_value(in, in, di, uo) is det.
|
|
|
|
:- pred vn__set_parallel_value(vnlval, vn, vn_tables, vn_tables).
|
|
:- mode vn__set_parallel_value(in, in, di, uo) is det.
|
|
|
|
:- pred vn__get_all_vnrvals(list(vnrval), vn_tables).
|
|
:- mode vn__get_all_vnrvals(out, in) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module opt_debug.
|
|
:- import_module int, string, require.
|
|
|
|
vn__init_tables(VnTables) :-
|
|
map__init(Lval_to_vn_table0),
|
|
map__init(Rval_to_vn_table0),
|
|
map__init(Vn_to_rval_table0),
|
|
map__init(Vn_to_uses_table0),
|
|
map__init(Vn_to_locs_table0),
|
|
map__init(Loc_to_vn_table0),
|
|
VnTables = vn_tables(0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table0,
|
|
Vn_to_locs_table0, Loc_to_vn_table0).
|
|
|
|
vn__lookup_desired_value(Vnlval, Vn, From, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
Lval_to_vn_table, _Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
( map__search(Lval_to_vn_table, Vnlval, VnPrime) ->
|
|
Vn = VnPrime
|
|
;
|
|
opt_debug__dump_vnlval(Vnlval, Value),
|
|
string__append_list([From, ": cannot find desired value for ", Value], Error),
|
|
error(Error)
|
|
).
|
|
|
|
vn__lookup_assigned_vn(Vnrval, Vn, From, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
( map__search(Rval_to_vn_table, Vnrval, VnPrime) ->
|
|
Vn = VnPrime
|
|
;
|
|
opt_debug__dump_vnrval(Vnrval, Value),
|
|
string__append_list([From, ": cannot find assigned vn for ", Value], Error),
|
|
error(Error)
|
|
).
|
|
|
|
vn__lookup_defn(Vn, Vnrval, From, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, _Rval_to_vn_table,
|
|
Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
( map__search(Vn_to_rval_table, Vn, VnrvalPrime) ->
|
|
Vnrval = VnrvalPrime
|
|
;
|
|
opt_debug__dump_vn(Vn, Value),
|
|
string__append_list([From, ": cannot find definition for ", Value], Error),
|
|
error(Error)
|
|
).
|
|
|
|
vn__lookup_uses(Vn, Uses, From, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, _Rval_to_vn_table,
|
|
_Vn_to_rval_table, Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
( map__search(Vn_to_uses_table, Vn, UsesPrime) ->
|
|
Uses = UsesPrime
|
|
;
|
|
opt_debug__dump_vn(Vn, Value),
|
|
string__append_list([From, ": cannot find uses for ", Value], Error),
|
|
error(Error)
|
|
).
|
|
|
|
vn__lookup_current_locs(Vn, Locs, From, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, _Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
Vn_to_locs_table, _Loc_to_vn_table),
|
|
( map__search(Vn_to_locs_table, Vn, LocsPrime) ->
|
|
Locs = LocsPrime
|
|
;
|
|
opt_debug__dump_vn(Vn, Value),
|
|
string__append_list([From, ": cannot find current locs for ", Value], Error),
|
|
error(Error)
|
|
).
|
|
|
|
vn__lookup_current_value(Vnlval, Vn, From, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, _Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, Loc_to_vn_table),
|
|
( map__search(Loc_to_vn_table, Vnlval, VnPrime) ->
|
|
Vn = VnPrime
|
|
;
|
|
opt_debug__dump_vnlval(Vnlval, Value),
|
|
string__append_list([From, ": cannot find current value for ", Value], Error),
|
|
error(Error)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
vn__search_desired_value(Vnlval, Vn, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
Lval_to_vn_table, _Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
map__search(Lval_to_vn_table, Vnlval, Vn).
|
|
|
|
vn__search_assigned_vn(Vnrval, Vn, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
map__search(Rval_to_vn_table, Vnrval, Vn).
|
|
|
|
vn__search_defn(Vn, Vnrval, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, _Rval_to_vn_table,
|
|
Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
map__search(Vn_to_rval_table, Vn, Vnrval).
|
|
|
|
vn__search_uses(Vn, Uses, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, _Rval_to_vn_table,
|
|
_Vn_to_rval_table, Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
map__search(Vn_to_uses_table, Vn, Uses).
|
|
|
|
vn__search_current_locs(Vn, Locs, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, _Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
Vn_to_locs_table, _Loc_to_vn_table),
|
|
map__search(Vn_to_locs_table, Vn, Locs).
|
|
|
|
vn__search_current_value(Vnlval, Vn, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, _Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, Loc_to_vn_table),
|
|
map__search(Loc_to_vn_table, Vnlval, Vn).
|
|
|
|
vn__get_vnlval_vn_list(VnTables, Lval_vn_list) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
Lval_to_vn_table, _Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
map__to_assoc_list(Lval_to_vn_table, Lval_vn_list).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
vn__add_new_use(Vn, NewUse, VnTables0, VnTables) :-
|
|
VnTables0 = vn_tables(NextVn0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table0,
|
|
Vn_to_locs_table0, Loc_to_vn_table0),
|
|
( map__search(Vn_to_uses_table0, Vn, Uses0Prime) ->
|
|
Uses0 = Uses0Prime
|
|
;
|
|
error("cannot find old use set in add_new_use")
|
|
),
|
|
(
|
|
list__member(NewUse, Uses0),
|
|
\+ NewUse = src_access(_)
|
|
->
|
|
opt_debug__dump_tables(VnTables0, T_str),
|
|
opt_debug__dump_vn(Vn, V_str),
|
|
opt_debug__dump_use(NewUse, U_str),
|
|
string__append_list(["\n", T_str, "\n",
|
|
"new use for vn ", V_str, " = ", U_str, "\n",
|
|
"new use already known"], Msg),
|
|
error(Msg)
|
|
;
|
|
Uses1 = [NewUse | Uses0]
|
|
),
|
|
map__set(Vn_to_uses_table0, Vn, Uses1, Vn_to_uses_table1),
|
|
VnTables = vn_tables(NextVn0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table1,
|
|
Vn_to_locs_table0, Loc_to_vn_table0).
|
|
|
|
vn__del_old_use(Vn, OldUse, VnTables0, VnTables) :-
|
|
VnTables0 = vn_tables(NextVn0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table0,
|
|
Vn_to_locs_table0, Loc_to_vn_table0),
|
|
( map__search(Vn_to_uses_table0, Vn, Uses0Prime) ->
|
|
Uses0 = Uses0Prime
|
|
;
|
|
error("cannot find old use set in add_new_use")
|
|
),
|
|
% a given src_access may appear several times, we delete just one
|
|
( list__delete_first(Uses0, OldUse, Uses1Prime) ->
|
|
Uses1 = Uses1Prime
|
|
;
|
|
% OldUse may not be in Uses0; it may have been deleted earlier
|
|
% (if constant) or it may be an artificially introduced
|
|
% src_liveval for a shared vn
|
|
Uses1 = Uses0
|
|
),
|
|
map__set(Vn_to_uses_table0, Vn, Uses1, Vn_to_uses_table1),
|
|
VnTables = vn_tables(NextVn0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table1,
|
|
Vn_to_locs_table0, Loc_to_vn_table0).
|
|
|
|
vn__del_old_uses([], _OldUse, VnTables, VnTables).
|
|
vn__del_old_uses([Vn | Vns], OldUse, VnTables0, VnTables) :-
|
|
vn__del_old_use(Vn, OldUse, VnTables0, VnTables1),
|
|
vn__del_old_uses(Vns, OldUse, VnTables1, VnTables).
|
|
|
|
vn__record_first_vnrval(Vnrval, Vn, VnTables0, VnTables) :-
|
|
VnTables0 = vn_tables(NextVn0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table0,
|
|
Vn_to_locs_table0, Loc_to_vn_table0),
|
|
Vn = NextVn0,
|
|
NextVn1 is NextVn0 + 1,
|
|
map__det_insert(Rval_to_vn_table0, Vnrval, Vn, Rval_to_vn_table1),
|
|
map__det_insert(Vn_to_rval_table0, Vn, Vnrval, Vn_to_rval_table1),
|
|
map__det_insert(Vn_to_uses_table0, Vn, [], Vn_to_uses_table1),
|
|
map__det_insert(Vn_to_locs_table0, Vn, [], Vn_to_locs_table1),
|
|
VnTables = vn_tables(NextVn1,
|
|
Lval_to_vn_table0, Rval_to_vn_table1,
|
|
Vn_to_rval_table1, Vn_to_uses_table1,
|
|
Vn_to_locs_table1, Loc_to_vn_table0).
|
|
|
|
vn__record_first_vnlval(Vnlval, Vn, VnTables0, VnTables) :-
|
|
VnTables0 = vn_tables(NextVn0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table0,
|
|
Vn_to_locs_table0, Loc_to_vn_table0),
|
|
Vn = NextVn0,
|
|
NextVn is NextVn0 + 1,
|
|
map__det_insert(Lval_to_vn_table0, Vnlval, Vn, Lval_to_vn_table1),
|
|
map__det_insert(Rval_to_vn_table0, vn_origlval(Vnlval), Vn, Rval_to_vn_table1),
|
|
map__det_insert(Vn_to_rval_table0, Vn, vn_origlval(Vnlval), Vn_to_rval_table1),
|
|
map__det_insert(Vn_to_uses_table0, Vn, [], Vn_to_uses_table1),
|
|
map__det_insert(Vn_to_locs_table0, Vn, [Vnlval], Vn_to_locs_table1),
|
|
map__det_insert(Loc_to_vn_table0, Vnlval, Vn, Loc_to_vn_table1),
|
|
VnTables = vn_tables(NextVn,
|
|
Lval_to_vn_table1, Rval_to_vn_table1,
|
|
Vn_to_rval_table1, Vn_to_uses_table1,
|
|
Vn_to_locs_table1, Loc_to_vn_table1).
|
|
|
|
vn__set_desired_value(Vnlval, Vn, VnTables0, VnTables) :-
|
|
VnTables0 = vn_tables(NextVn0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table0,
|
|
Vn_to_locs_table0, Loc_to_vn_table0),
|
|
( map__search(Loc_to_vn_table0, Vnlval, _) ->
|
|
map__set(Lval_to_vn_table0, Vnlval, Vn, Lval_to_vn_table1),
|
|
VnTables = vn_tables(NextVn0,
|
|
Lval_to_vn_table1, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table0,
|
|
Vn_to_locs_table0, Loc_to_vn_table0)
|
|
;
|
|
vn__record_first_vnlval(Vnlval, _, VnTables0, VnTables1),
|
|
VnTables1 = vn_tables(NextVn1,
|
|
Lval_to_vn_table1, Rval_to_vn_table1,
|
|
Vn_to_rval_table1, Vn_to_uses_table1,
|
|
Vn_to_locs_table1, Loc_to_vn_table1),
|
|
map__set(Lval_to_vn_table1, Vnlval, Vn, Lval_to_vn_table2),
|
|
VnTables = vn_tables(NextVn1,
|
|
Lval_to_vn_table2, Rval_to_vn_table1,
|
|
Vn_to_rval_table1, Vn_to_uses_table1,
|
|
Vn_to_locs_table1, Loc_to_vn_table1)
|
|
).
|
|
|
|
% We put the newly generated vnlval at the end of the list of vnlvals
|
|
% containing this vn. This is because if there are several registers
|
|
% holding a vn, we pick the one at the front, and on superscalar
|
|
% machines it is better not to use a register immediately after
|
|
% its definition.
|
|
|
|
vn__set_current_value(Vnlval, Vn, VnTables0, VnTables) :-
|
|
VnTables0 = vn_tables(NextVn0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table0,
|
|
Vn_to_locs_table0, Loc_to_vn_table0),
|
|
( map__search(Loc_to_vn_table0, Vnlval, OldVn) ->
|
|
|
|
% change the forward mapping
|
|
map__set(Loc_to_vn_table0, Vnlval, Vn, Loc_to_vn_table1),
|
|
|
|
% change the reverse mapping, first for old vn, then the new
|
|
map__lookup(Vn_to_locs_table0, OldVn, OldLocs0),
|
|
list__delete_all(OldLocs0, Vnlval, OldLocs1),
|
|
map__set(Vn_to_locs_table0, OldVn, OldLocs1, Vn_to_locs_table1),
|
|
|
|
map__lookup(Vn_to_locs_table0, Vn, NewLocs0),
|
|
list__append(NewLocs0, [Vnlval], NewLocs1),
|
|
map__set(Vn_to_locs_table1, Vn, NewLocs1, Vn_to_locs_table2)
|
|
;
|
|
% The search in the condition can fail for newly introduced
|
|
% templocs
|
|
|
|
% change the forward mapping
|
|
map__set(Loc_to_vn_table0, Vnlval, Vn, Loc_to_vn_table1),
|
|
|
|
% change the reverse mapping
|
|
map__lookup(Vn_to_locs_table0, Vn, NewLocs0),
|
|
list__append(NewLocs0, [Vnlval], NewLocs1),
|
|
map__set(Vn_to_locs_table0, Vn, NewLocs1, Vn_to_locs_table2)
|
|
),
|
|
VnTables = vn_tables(NextVn0,
|
|
Lval_to_vn_table0, Rval_to_vn_table0,
|
|
Vn_to_rval_table0, Vn_to_uses_table0,
|
|
Vn_to_locs_table2, Loc_to_vn_table1).
|
|
|
|
vn__set_parallel_value(Vnlval, Vn, VnTables0, VnTables) :-
|
|
vn__set_desired_value(Vnlval, Vn, VnTables0, VnTables1),
|
|
vn__set_current_value(Vnlval, Vn, VnTables1, VnTables).
|
|
|
|
vn__get_all_vnrvals(Vnrvals, VnTables) :-
|
|
VnTables = vn_tables(_NextVn,
|
|
_Lval_to_vn_table, Rval_to_vn_table,
|
|
_Vn_to_rval_table, _Vn_to_uses_table,
|
|
_Vn_to_locs_table, _Loc_to_vn_table),
|
|
map__keys(Rval_to_vn_table, Vnrvals).
|