[m-rev.] for review: stack slot optimization, part 1
Zoltan Somogyi
zs at cs.mu.OZ.AU
Sat Mar 9 20:19:12 AEDT 2002
However reviews this should first read the paper about the optimization.
While the diff is very long, most of it is trivial changes caused by the change
in the structures of goal_exprs and goal_infos.
Zoltan.
-------------------
This diff implements stack slot optimization for the LLDS back end based on
the idea that after a unification such as A = f(B, C, D), saving the
variable A on the stack indirectly also saves the values of B, C and D.
Figuring out what subset of {B,C,D} to access via A and what subset to access
via their own stack slots is a tricky optimization problem. The algorithm we
use to solve it is described in the paper "Using the heap to eliminate stack
accesses" by Zoltan Somogyi and Peter Stuckey, available in ~zs/rep/stackslot.
That paper also describes (and has examples of) the source-to-source
transformation that implements the optimization.
The optimization needs to know what variables are flushed at call sites
and at program points that establish resume points (e.g. entries to
disjunctions and if-then-elses). We already had code to compute this
information in live_vars.m, but this code was being invoked too late.
This diff modifies live_vars.m to allow it to be invoked both by the stack
slot optimization transformation and by the code generator, and allows its
function to be tailored to the requirements of each invocation.
The information computed by live_vars.m is specific to the LLDS back end,
since the MLDS back ends do not (yet) have the same control over stack
frame layout. We therefore store this information in a new back end specific
field in goal_infos. For uniformity, we make all the other existing back end
specific fields in goal_infos, as well as the similarly back end specific
store map field of goal_exprs, subfields of this new field. This happens
to significantly reduce the sizes of goal_infos.
To allow a more meaningful comparison of the gains produced by the new
optimization, do not save any variables across erroneous calls even if
the new optimization is not enabled.
compiler/stack_opt.m:
New module containing the code that performs the transformation
to optimize stack slot usage.
compiler/matching.m:
New module containing an algorithm for maximal matching in bipartite
graphs, specialized for the graphs needed by stack_opt.m.
compiler/mercury_compile.m:
Invoke the new optimization if the options ask for it.
compiler/stack_alloc.m:
New module containing code that is shared between the old,
non-optimizing stack slot allocation system and the new, optimizing
stack slot allocation system, and the code for actually allocating
stack slots in the absence of optimization.
compiler/stack_alloc.m:
Live_vars.m used to have two tasks: find out what variables need to be
saved on the stack, and allocating those variables to stack slots.
Live_vars.m now does only the first task; stack_alloc.m now does
the second, using code that used to be in live_vars.m.
compiler/notes/compiler_design.html:
Document the new modules (as well as trace_params.m, which wasn't
documented earlier).
compiler/live_vars.m:
Delete the code that is now in stack_alloc.m and graph_colour.m.
Separate out the kinds of stack uses due to nondeterminism: the stack
slots used by nondet calls, and the stack slots used by resumption
points, in order to allow the reuse of stack slots used by resumption
points after execution has left their scope. This should allow the
same stack slots to be used by different variables in the resumption
point at the start of an else branch and nondet calls in the then
branch, since the resumption point of the else branch is not in effect
when the then branch is executed.
If the new option --opt-no-return-calls is set, then say that we do not
need to save any values across erroneous calls.
Use type classes to allow the information generated by this module
to be recorded in the way required by its invoker.
Package up the data structures being passed around readonly into a
single tuple.
compiler/store_alloc.m:
Allow this module to be invoked by stack_opt.m without invoking the
follow_vars transformation, since applying follow_vars before the form
of the HLDS code is otherwise final can be a pessimization.
Make the module_info a part of the record containing the readonly data
passed around during the traversal.
compiler/common.m:
Do not delete or move around unifications created by stack_opt.m.
compiler/call_gen.m:
compiler/code_info.m:
compiler/continuation_info.m:
compiler/var_locn.m:
Allow the code generator to delete its last record of the location
of a value when generating code to make an erroneous call, if the new
--opt-no-return-calls option is set.
compiler/code_gen.m:
Use a more useful algorithm to create the messages/comments that
we put into incr_sp instructions, e.g. by distinguishing between
predicates and functions. This is to allow the new scripts in the
tool directory to gather statistics about the effect of the
optimization on stack frame sizes.
library/exception.m:
Make a hand-written incr_sp follow the new pattern.
compiler/arg_info.m:
Add predicates to figure out the set of input, output and unused
arguments of a procedure in several different circumstances.
Previously, variants of these predicates were repeated in several
places.
compiler/goal_util.m:
Export some previously private utility predicates.
compiler/handle_options.m:
Turn off stack slot optimizations when debugging.
Add a new dump format useful for debugging --optimize-saved-vars.
compiler/hlds_llds.m:
New module for handling all the stuff specific to the LLDS back end
in HLDS goal_infos.
compiler/hlds_goal.m:
Move all the relevant stuff into the new back end specific field
in goal_infos.
compiler/notes/allocation.html:
Update the documentation of store maps to reflect their movement
into a subfield of goal_infos.
compiler/*.m:
Minor changes to accomodate the placement of all back end specific
information about goals in the new of store maps from goal_exprs.
compiler/use_local_vars.m:
Look for sequences in which several instructions use a fake register
or stack slot as a base register pointing to a cell, and make those
instructions use a local variable instead.
Without this, a key assumption of the stack slot optimization,
that accessing a field in a cell costs only one load or store
instruction, would be much less likely to be true. (With this
optimization, the assumption will be false only if the C compiler's
code generator runs out of registers in a basic block, which for
the code we generate should be unlikely even on x86s.)
compiler/options.m:
Make the old option --optimize-saved-vars ask for both the old stack
slot optimization (implemented by saved_vars.m) that only eliminates
the storing of constants in stack slots, and the new optimization.
Add two new options --optimize-saved-vars-{const,cell} to turn on
the two optimizations separately.
Add a bunch of options to specify the parameters of the new
optimizations, both in stack_opt.m and use_local_vars.m. These are
for implementors only; they are deliberately not documented.
doc/user_guide.texi:
Update the documentation of --optimize-saved-vars.
library/tree234.m:
Undo a previous change of mine that effectively applied this
optimization by hand. That change complicated the code, and now
the compiler can do the optimization automatically.
tools/extract_incr_sp:
A new script for extracting stack frame sizes and messages from
stack increment operations in the C code for LLDS grades.
tools/sum_incr_sp:
A new script that uses extract_incr_sp to extract information about
stack frame sizes from the C files saved from a stage 2 directory
by makebatch and summarizes the resulting information.
tools/compare_stacks:
tools/compare_sp:
A new script that compares the stack frame size information
extracted from two different stage 2 directories by sum_incr_sp,
reporting on both average stack frame sizes and on specific procedures
that have different stack frame sizes in the two versions.
Compare_stacks is the command people should invoke; compare_sp
is just an implementation artifact.
cvs diff: Diffing .
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/accumulator.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/accumulator.m,v
retrieving revision 1.18
diff -u -b -r1.18 accumulator.m
--- compiler/accumulator.m 13 Oct 2000 13:55:13 -0000 1.18
+++ compiler/accumulator.m 16 Jul 2001 13:44:29 -0000
@@ -429,7 +429,7 @@
(
Goal0 = conj([Goal1]) - _
;
- Goal0 = disj([Goal1], _) - _
+ Goal0 = disj([Goal1]) - _
)
->
standardize(Goal1, Goal)
@@ -454,7 +454,7 @@
identify_goal_type(PredId, ProcId, Goal, InitialInstMap,
Type, Base, BaseInstMap, Rec, RecInstMap) :-
(
- Goal = switch(_Var, _CanFail, Cases, _StoreMap) - _GoalInfo,
+ Goal = switch(_Var, _CanFail, Cases) - _GoalInfo,
Cases = [case(_IdA, GoalA), case(_IdB, GoalB)],
goal_to_conj_list(GoalA, GoalAList),
goal_to_conj_list(GoalB, GoalBList)
@@ -477,7 +477,7 @@
BaseInstMap = InitialInstMap,
RecInstMap = InitialInstMap
;
- Goal = disj(Goals, _StoreMap) - _GoalInfo,
+ Goal = disj(Goals) - _GoalInfo,
Goals = [GoalA, GoalB],
goal_to_conj_list(GoalA, GoalAList),
goal_to_conj_list(GoalB, GoalBList)
@@ -500,8 +500,7 @@
BaseInstMap = InitialInstMap,
RecInstMap = InitialInstMap
;
- Goal = if_then_else(_Vars, If, Then, Else, _StoreMap) -
- _GoalInfo,
+ Goal = if_then_else(_Vars, If, Then, Else) - _GoalInfo,
If = _IfGoal - IfGoalInfo,
goal_info_get_instmap_delta(IfGoalInfo, IfInstMapDelta),
@@ -1870,82 +1869,82 @@
top_level(switch_base_rec, Goal, OrigBaseGoal, OrigRecGoal,
NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
(
- Goal = switch(Var, CanFail, Cases0, StoreMap) - GoalInfo,
+ Goal = switch(Var, CanFail, Cases0) - GoalInfo,
Cases0 = [case(IdA, _), case(IdB, _)]
->
OrigCases = [case(IdA, OrigBaseGoal), case(IdB, OrigRecGoal)],
- OrigGoal = switch(Var, CanFail, OrigCases, StoreMap) - GoalInfo,
+ OrigGoal = switch(Var, CanFail, OrigCases) - GoalInfo,
NewCases = [case(IdA, NewBaseGoal), case(IdB, NewRecGoal)],
- NewGoal = switch(Var, CanFail, NewCases, StoreMap) - GoalInfo
+ NewGoal = switch(Var, CanFail, NewCases) - GoalInfo
;
error("top_level: not the correct top level")
).
top_level(switch_rec_base, Goal, OrigBaseGoal, OrigRecGoal,
NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
(
- Goal = switch(Var, CanFail, Cases0, StoreMap) - GoalInfo,
+ Goal = switch(Var, CanFail, Cases0) - GoalInfo,
Cases0 = [case(IdA, _), case(IdB, _)]
->
OrigCases = [case(IdA, OrigRecGoal), case(IdB, OrigBaseGoal)],
- OrigGoal = switch(Var, CanFail, OrigCases, StoreMap) - GoalInfo,
+ OrigGoal = switch(Var, CanFail, OrigCases) - GoalInfo,
NewCases = [case(IdA, NewRecGoal), case(IdB, NewBaseGoal)],
- NewGoal = switch(Var, CanFail, NewCases, StoreMap) - GoalInfo
+ NewGoal = switch(Var, CanFail, NewCases) - GoalInfo
;
error("top_level: not the correct top level")
).
top_level(disj_base_rec, Goal, OrigBaseGoal,
OrigRecGoal, NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
(
- Goal = disj(Goals, StoreMap) - GoalInfo,
+ Goal = disj(Goals) - GoalInfo,
Goals = [_, _]
->
OrigGoals = [OrigBaseGoal, OrigRecGoal],
- OrigGoal = disj(OrigGoals, StoreMap) - GoalInfo,
+ OrigGoal = disj(OrigGoals) - GoalInfo,
NewGoals = [NewBaseGoal, NewRecGoal],
- NewGoal = disj(NewGoals, StoreMap) - GoalInfo
+ NewGoal = disj(NewGoals) - GoalInfo
;
error("top_level: not the correct top level")
).
top_level(disj_rec_base, Goal, OrigBaseGoal,
OrigRecGoal, NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
(
- Goal = disj(Goals, StoreMap) - GoalInfo,
+ Goal = disj(Goals) - GoalInfo,
Goals = [_, _]
->
OrigGoals = [OrigRecGoal, OrigBaseGoal],
- OrigGoal = disj(OrigGoals, StoreMap) - GoalInfo,
+ OrigGoal = disj(OrigGoals) - GoalInfo,
NewGoals = [NewRecGoal, NewBaseGoal],
- NewGoal = disj(NewGoals, StoreMap) - GoalInfo
+ NewGoal = disj(NewGoals) - GoalInfo
;
error("top_level: not the correct top level")
).
top_level(ite_base_rec, Goal, OrigBaseGoal,
OrigRecGoal, NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
(
- Goal = if_then_else(Vars, If, _, _, StoreMap) - GoalInfo
+ Goal = if_then_else(Vars, If, _, _) - GoalInfo
->
OrigGoal = if_then_else(Vars, If,
- OrigBaseGoal, OrigRecGoal, StoreMap) - GoalInfo,
+ OrigBaseGoal, OrigRecGoal) - GoalInfo,
NewGoal = if_then_else(Vars, If,
- NewBaseGoal, NewRecGoal, StoreMap) - GoalInfo
+ NewBaseGoal, NewRecGoal) - GoalInfo
;
error("top_level: not the correct top level")
).
top_level(ite_rec_base, Goal, OrigBaseGoal,
OrigRecGoal, NewBaseGoal, NewRecGoal, OrigGoal, NewGoal) :-
(
- Goal = if_then_else(Vars, If, _, _, StoreMap) - GoalInfo
+ Goal = if_then_else(Vars, If, _, _) - GoalInfo
->
OrigGoal = if_then_else(Vars, If,
- OrigRecGoal, OrigBaseGoal, StoreMap) - GoalInfo,
+ OrigRecGoal, OrigBaseGoal) - GoalInfo,
NewGoal = if_then_else(Vars, If,
- NewRecGoal, NewBaseGoal, StoreMap) - GoalInfo
+ NewRecGoal, NewBaseGoal) - GoalInfo
;
error("top_level: not the correct top level")
).
Index: compiler/add_heap_ops.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/add_heap_ops.m,v
retrieving revision 1.3
diff -u -b -r1.3 add_heap_ops.m
--- compiler/add_heap_ops.m 5 Feb 2002 09:14:45 -0000 1.3
+++ compiler/add_heap_ops.m 7 Feb 2002 05:24:18 -0000
@@ -94,12 +94,12 @@
goal_expr_add_heap_ops(conj(Goals0), GI, conj(Goals) - GI) -->
conj_add_heap_ops(Goals0, Goals).
-goal_expr_add_heap_ops(par_conj(Goals0, SM), GI, par_conj(Goals, SM) - GI) -->
+goal_expr_add_heap_ops(par_conj(Goals0), GI, par_conj(Goals) - GI) -->
conj_add_heap_ops(Goals0, Goals).
-goal_expr_add_heap_ops(disj([], B), GI, disj([], B) - GI) --> [].
+goal_expr_add_heap_ops(disj([]), GI, disj([]) - GI) --> [].
-goal_expr_add_heap_ops(disj(Goals0, B), GoalInfo, Goal - GoalInfo) -->
+goal_expr_add_heap_ops(disj(Goals0), GoalInfo, Goal - GoalInfo) -->
{ Goals0 = [FirstDisjunct | _] },
{ goal_info_get_context(GoalInfo, Context) },
@@ -122,15 +122,13 @@
gen_mark_hp(SavedHeapPointerVar, Context, MarkHeapPointerGoal),
disj_add_heap_ops(Goals0, yes, yes(SavedHeapPointerVar),
GoalInfo, Goals),
- { Goal = conj([MarkHeapPointerGoal, disj(Goals, B) -
- GoalInfo]) }
+ { Goal = conj([MarkHeapPointerGoal, disj(Goals) - GoalInfo]) }
;
disj_add_heap_ops(Goals0, yes, no, GoalInfo, Goals),
- { Goal = disj(Goals, B) }
+ { Goal = disj(Goals) }
).
-goal_expr_add_heap_ops(switch(A, B, Cases0, D), GI,
- switch(A, B, Cases, D) - GI) -->
+goal_expr_add_heap_ops(switch(A, B, Cases0), GI, switch(A, B, Cases) - GI) -->
cases_add_heap_ops(Cases0, Cases).
goal_expr_add_heap_ops(not(InnerGoal), OuterGoalInfo, Goal) -->
@@ -144,7 +142,6 @@
{ determinism_components(Determinism, _CanFail, NumSolns) },
{ true_goal(Context, True) },
{ fail_goal(Context, Fail) },
- { map__init(SM) },
ModuleInfo =^ module_info,
{ NumSolns = at_most_zero ->
% The "then" part of the if-then-else will be unreachable,
@@ -157,14 +154,14 @@
;
ThenGoal = Fail
},
- { NewOuterGoal = if_then_else([], InnerGoal, ThenGoal, True, SM) },
+ { NewOuterGoal = if_then_else([], InnerGoal, ThenGoal, True) },
goal_expr_add_heap_ops(NewOuterGoal, OuterGoalInfo, Goal).
goal_expr_add_heap_ops(some(A, B, Goal0), GoalInfo,
some(A, B, Goal) - GoalInfo) -->
goal_add_heap_ops(Goal0, Goal).
-goal_expr_add_heap_ops(if_then_else(A, Cond0, Then0, Else0, E), GoalInfo,
+goal_expr_add_heap_ops(if_then_else(A, Cond0, Then0, Else0), GoalInfo,
Goal - GoalInfo) -->
goal_add_heap_ops(Cond0, Cond),
goal_add_heap_ops(Then0, Then),
@@ -187,11 +184,10 @@
{ Else1 = _ - Else1GoalInfo },
{ Else = conj([RestoreHeapPointerGoal, Else1]) -
Else1GoalInfo },
- { IfThenElse = if_then_else(A, Cond, Then, Else, E) -
- GoalInfo },
+ { IfThenElse = if_then_else(A, Cond, Then, Else) - GoalInfo },
{ Goal = conj([MarkHeapPointerGoal, IfThenElse]) }
;
- { Goal = if_then_else(A, Cond, Then, Else1, E) }
+ { Goal = if_then_else(A, Cond, Then, Else1) }
).
@@ -275,8 +271,7 @@
% Put this disjunct and the remaining disjuncts in a
% nested disjunction, so that the heap pointer variable
% can scope over these disjuncts
- { map__init(StoreMap) },
- { Disj = disj([Goal | Goals1], StoreMap) - DisjGoalInfo },
+ { Disj = disj([Goal | Goals1]) - DisjGoalInfo },
{ DisjGoals = [conj([MarkHeapPointerGoal, Disj]) -
DisjGoalInfo] }
;
Index: compiler/add_trail_ops.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/add_trail_ops.m,v
retrieving revision 1.6
diff -u -b -r1.6 add_trail_ops.m
--- compiler/add_trail_ops.m 26 Nov 2001 09:30:55 -0000 1.6
+++ compiler/add_trail_ops.m 29 Nov 2001 01:35:49 -0000
@@ -95,12 +95,12 @@
goal_expr_add_trail_ops(conj(Goals0), GI, conj(Goals) - GI) -->
conj_add_trail_ops(Goals0, Goals).
-goal_expr_add_trail_ops(par_conj(Goals0, SM), GI, par_conj(Goals, SM) - GI) -->
+goal_expr_add_trail_ops(par_conj(Goals0), GI, par_conj(Goals) - GI) -->
conj_add_trail_ops(Goals0, Goals).
-goal_expr_add_trail_ops(disj([], B), GI, disj([], B) - GI) --> [].
+goal_expr_add_trail_ops(disj([]), GI, disj([]) - GI) --> [].
-goal_expr_add_trail_ops(disj(Goals0, B), GoalInfo, Goal - GoalInfo) -->
+goal_expr_add_trail_ops(disj(Goals0), GoalInfo, Goal - GoalInfo) -->
{ Goals0 = [_|_] },
{ goal_info_get_context(GoalInfo, Context) },
@@ -113,10 +113,9 @@
new_ticket_var(TicketVar),
gen_store_ticket(TicketVar, Context, StoreTicketGoal),
disj_add_trail_ops(Goals0, yes, CodeModel, TicketVar, Goals),
- { Goal = conj([StoreTicketGoal, disj(Goals, B) - GoalInfo]) }.
+ { Goal = conj([StoreTicketGoal, disj(Goals) - GoalInfo]) }.
-goal_expr_add_trail_ops(switch(A, B, Cases0, D), GI,
- switch(A, B, Cases, D) - GI) -->
+goal_expr_add_trail_ops(switch(A, B, Cases0), GI, switch(A, B, Cases) - GI) -->
cases_add_trail_ops(Cases0, Cases).
goal_expr_add_trail_ops(not(InnerGoal), OuterGoalInfo, Goal) -->
@@ -130,7 +129,6 @@
{ determinism_components(Determinism, _CanFail, NumSolns) },
{ true_goal(Context, True) },
{ fail_goal(Context, Fail) },
- { map__init(SM) },
ModuleInfo =^ module_info,
{ NumSolns = at_most_zero ->
% The "then" part of the if-then-else will be unreachable,
@@ -144,7 +142,7 @@
;
ThenGoal = Fail
},
- { NewOuterGoal = if_then_else([], InnerGoal, ThenGoal, True, SM) },
+ { NewOuterGoal = if_then_else([], InnerGoal, ThenGoal, True) },
goal_expr_add_trail_ops(NewOuterGoal, OuterGoalInfo, Goal).
goal_expr_add_trail_ops(some(A, B, Goal0), OuterGoalInfo,
@@ -200,9 +198,7 @@
{ FailGoal = _ - FailGoalInfo },
{ FailCode = conj([ResetTicketUndoGoal,
DiscardTicketGoal, FailGoal]) - FailGoalInfo },
- { map__init(SM) },
- { Goal3 = disj([SuccCode, FailCode], SM) -
- OuterGoalInfo }
+ { Goal3 = disj([SuccCode, FailCode]) - OuterGoalInfo }
;
{ Goal3 = SuccCode }
),
@@ -212,7 +208,7 @@
{ Goal = some(A, B, Goal1) }
).
-goal_expr_add_trail_ops(if_then_else(A, Cond0, Then0, Else0, E), GoalInfo,
+goal_expr_add_trail_ops(if_then_else(A, Cond0, Then0, Else0), GoalInfo,
Goal - GoalInfo) -->
goal_add_trail_ops(Cond0, Cond),
goal_add_trail_ops(Then0, Then1),
@@ -248,7 +244,7 @@
{ Else1 = _ - Else1GoalInfo },
{ Else = conj([ResetTicketUndoGoal, DiscardTicketGoal, Else1])
- Else1GoalInfo },
- { IfThenElse = if_then_else(A, Cond, Then, Else, E) - GoalInfo },
+ { IfThenElse = if_then_else(A, Cond, Then, Else) - GoalInfo },
{ Goal = conj([StoreTicketGoal, IfThenElse]) }.
Index: compiler/arg_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/arg_info.m,v
retrieving revision 1.35
diff -u -b -r1.35 arg_info.m
--- compiler/arg_info.m 23 Nov 2000 04:32:26 -0000 1.35
+++ compiler/arg_info.m 15 Oct 2001 09:55:05 -0000
@@ -18,7 +18,7 @@
:- module arg_info.
:- interface.
:- import_module prog_data, hlds_module, hlds_pred, code_model, llds.
-:- import_module list, assoc_list.
+:- import_module list, assoc_list, set.
% Annotate every non-aditi procedure in the module with information
% about its argument passing interface.
@@ -29,9 +29,9 @@
:- pred make_arg_infos(list(type)::in, list(mode)::in, code_model::in,
module_info::in, list(arg_info)::out) is det.
- % Given a list of the head variables and their argument information,
- % return a list giving the input variables and their initial locations.
-:- pred arg_info__build_input_arg_list(assoc_list(prog_var, arg_info)::in,
+ % Given a procedure that already has its arg_info field filled in,
+ % return a list giving its input variables and their initial locations.
+:- pred arg_info__build_input_arg_list(proc_info::in,
assoc_list(prog_var, lval)::out) is det.
% Divide the given list of arguments into those treated as inputs
@@ -59,6 +59,31 @@
assoc_list(prog_var, arg_info)::out,
assoc_list(prog_var, arg_info)::out) is det.
+ % Partition the head variables of the given procedure into three sets:
+ % the inputs, the outputs, and the unused arguments. This is done based
+ % on the arg_info annotations of the arguments, which means that this
+ % predicate should only be called after the arg_info pass has been
+ % run.
+:- pred arg_info__partition_proc_args(proc_info::in, module_info::in,
+ set(prog_var)::out, set(prog_var)::out, set(prog_var)::out) is det.
+
+ % Like arg_info__partition_proc_args, but partitions the actual
+ % arguments of a call (given in the fourth argument) instead of the
+ % head variables. Since the first (proc_info) argument is now the
+ % proc_info of the callee, we need to pass the types of the arguments
+ % (in the caller) separately.
+:- pred arg_info__partition_proc_call_args(proc_info::in, vartypes::in,
+ module_info::in, list(prog_var)::in, set(prog_var)::out,
+ set(prog_var)::out, set(prog_var)::out) is det.
+
+ % Like arg_info__partition_proc_call_args, but partitions the actual
+ % arguments of a generic call, so instead of looking up the types and
+ % modes of the arguments in the module_info, we get them from the
+ % arguments.
+:- pred arg_info__partition_generic_call_args(module_info::in,
+ list(prog_var)::in, list(type)::in, list(mode)::in,
+ set(prog_var)::out, set(prog_var)::out, set(prog_var)::out) is det.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -180,8 +205,17 @@
%---------------------------------------------------------------------------%
-arg_info__build_input_arg_list([], []).
-arg_info__build_input_arg_list([V - Arg | Rest0], VarArgs) :-
+arg_info__build_input_arg_list(ProcInfo, VarLvals) :-
+ proc_info_headvars(ProcInfo, HeadVars),
+ proc_info_arg_info(ProcInfo, ArgInfos),
+ assoc_list__from_corresponding_lists(HeadVars, ArgInfos, VarArgInfos),
+ arg_info__build_input_arg_list_2(VarArgInfos, VarLvals).
+
+:- pred arg_info__build_input_arg_list_2(assoc_list(prog_var, arg_info)::in,
+ assoc_list(prog_var, lval)::out) is det.
+
+arg_info__build_input_arg_list_2([], []).
+arg_info__build_input_arg_list_2([V - Arg | Rest0], VarArgs) :-
Arg = arg_info(Loc, Mode),
( Mode = top_in ->
code_util__arg_loc_to_register(Loc, Reg),
@@ -189,7 +223,7 @@
;
VarArgs = VarArgs0
),
- arg_info__build_input_arg_list(Rest0, VarArgs0).
+ arg_info__build_input_arg_list_2(Rest0, VarArgs0).
%---------------------------------------------------------------------------%
@@ -273,3 +307,81 @@
).
%---------------------------------------------------------------------------%
+
+arg_info__partition_proc_args(ProcInfo, ModuleInfo, Inputs, Outputs, Unuseds) :-
+ proc_info_headvars(ProcInfo, Vars),
+ proc_info_argmodes(ProcInfo, Modes),
+ proc_info_vartypes(ProcInfo, VarTypes),
+ map__apply_to_list(Vars, VarTypes, Types),
+ (
+ arg_info__partition_proc_args_2(Vars, Modes, Types, ModuleInfo,
+ set__init, Inputs1, set__init, Outputs1,
+ set__init, Unuseds1)
+ ->
+ Inputs = Inputs1,
+ Outputs = Outputs1,
+ Unuseds = Unuseds1
+ ;
+ error("arg_info__partition_proc_args: list length mismatch")
+ ).
+
+arg_info__partition_proc_call_args(ProcInfo, VarTypes, ModuleInfo, Vars,
+ Inputs, Outputs, Unuseds) :-
+ proc_info_argmodes(ProcInfo, Modes),
+ map__apply_to_list(Vars, VarTypes, Types),
+ (
+ arg_info__partition_proc_args_2(Vars, Modes, Types, ModuleInfo,
+ set__init, Inputs1, set__init, Outputs1,
+ set__init, Unuseds1)
+ ->
+ Inputs = Inputs1,
+ Outputs = Outputs1,
+ Unuseds = Unuseds1
+ ;
+ error("arg_info__partition_proc_call_args: list length mismatch")
+ ).
+
+arg_info__partition_generic_call_args(ModuleInfo, Vars, Types, Modes,
+ Inputs, Outputs, Unuseds) :-
+ (
+ arg_info__partition_proc_args_2(Vars, Modes, Types, ModuleInfo,
+ set__init, Inputs1, set__init, Outputs1,
+ set__init, Unuseds1)
+ ->
+ Inputs = Inputs1,
+ Outputs = Outputs1,
+ Unuseds = Unuseds1
+ ;
+ error("arg_info__partition_generic_call_args: list length mismatch")
+ ).
+
+:- pred arg_info__partition_proc_args_2(list(prog_var)::in, list(mode)::in,
+ list(type)::in, module_info::in,
+ set(prog_var)::in, set(prog_var)::out,
+ set(prog_var)::in, set(prog_var)::out,
+ set(prog_var)::in, set(prog_var)::out) is semidet.
+
+arg_info__partition_proc_args_2([], [], [], _ModuleInfo,
+ Inputs, Inputs, Outputs, Outputs, Unuseds, Unuseds).
+arg_info__partition_proc_args_2([Var | Vars], [Mode | Modes], [Type | Types],
+ ModuleInfo,
+ Inputs0, Inputs, Outputs0, Outputs, Unuseds0, Unuseds) :-
+ mode_to_arg_mode(ModuleInfo, Mode, Type, ArgMode),
+ (
+ ArgMode = top_in,
+ set__insert(Inputs0, Var, Inputs1),
+ Outputs1 = Outputs0,
+ Unuseds1 = Unuseds0
+ ;
+ ArgMode = top_out,
+ Inputs1 = Inputs0,
+ set__insert(Outputs0, Var, Outputs1),
+ Unuseds1 = Unuseds0
+ ;
+ ArgMode = top_unused,
+ Inputs1 = Inputs0,
+ Outputs1 = Outputs0,
+ set__insert(Unuseds0, Var, Unuseds1)
+ ),
+ arg_info__partition_proc_args_2(Vars, Modes, Types, ModuleInfo,
+ Inputs1, Inputs, Outputs1, Outputs, Unuseds1, Unuseds).
Index: compiler/assertion.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/assertion.m,v
retrieving revision 1.16
diff -u -b -r1.16 assertion.m
--- compiler/assertion.m 7 Mar 2002 08:29:42 -0000 1.16
+++ compiler/assertion.m 8 Mar 2002 04:04:07 -0000
@@ -535,14 +535,14 @@
equal_goals(generic_call(Type, VarsA, _, _) - _,
generic_call(Type, VarsB, _, _) - _, Subst0, Subst) :-
equal_vars(VarsA, VarsB, Subst0, Subst).
-equal_goals(switch(Var, CanFail, CasesA, _) - _,
- switch(Var, CanFail, CasesB, _) - _, Subst0, Subst) :-
+equal_goals(switch(Var, CanFail, CasesA) - _,
+ switch(Var, CanFail, CasesB) - _, Subst0, Subst) :-
equal_goals_cases(CasesA, CasesB, Subst0, Subst).
equal_goals(unify(VarA, RHSA, _, _, _) - _, unify(VarB, RHSB, _, _, _) - _,
Subst0, Subst) :-
equal_vars([VarA], [VarB], Subst0, Subst1),
equal_unification(RHSA, RHSB, Subst1, Subst).
-equal_goals(disj(GoalAs, _) - _, disj(GoalBs, _) - _, Subst0, Subst) :-
+equal_goals(disj(GoalAs) - _, disj(GoalBs) - _, Subst0, Subst) :-
equal_goals_list(GoalAs, GoalBs, Subst0, Subst).
equal_goals(not(GoalA) - _, not(GoalB) - _, Subst0, Subst) :-
equal_goals(GoalA, GoalB, Subst0, Subst).
@@ -550,8 +550,8 @@
Subst0, Subst) :-
equal_vars(VarsA, VarsB, Subst0, Subst1),
equal_goals(GoalA, GoalB, Subst1, Subst).
-equal_goals(if_then_else(VarsA, IfA, ThenA, ElseA, _) - _,
- if_then_else(VarsB, IfB, ThenB, ElseB, _) - _, Subst0, Subst) :-
+equal_goals(if_then_else(VarsA, IfA, ThenA, ElseA) - _,
+ if_then_else(VarsB, IfB, ThenB, ElseB) - _, Subst0, Subst) :-
equal_vars(VarsA, VarsB, Subst0, Subst1),
equal_goals(IfA, IfB, Subst1, Subst2),
equal_goals(ThenA, ThenB, Subst2, Subst3),
@@ -560,7 +560,7 @@
foreign_proc(Attribs, PredId, _, VarsB, _, _, _) -
_, Subst0, Subst) :-
equal_vars(VarsA, VarsB, Subst0, Subst).
-equal_goals(par_conj(GoalAs, _) - _, par_conj(GoalBs, _) - _, Subst0, Subst) :-
+equal_goals(par_conj(GoalAs) - _, par_conj(GoalBs) - _, Subst0, Subst) :-
equal_goals_list(GoalAs, GoalBs, Subst0, Subst).
equal_goals(shorthand(ShorthandGoalA) - GoalInfoA,
shorthand(ShorthandGoalB) - GoalInfoB, Subst0, Subst) :-
@@ -666,20 +666,20 @@
foreign_proc(A,B,C,D,E,F,G) - GI).
assertion__normalise_goal(conj(Goals0) - GI, conj(Goals) - GI) :-
assertion__normalise_conj(Goals0, Goals).
-assertion__normalise_goal(switch(A,B,Case0s,D) - GI, switch(A,B,Cases,D)-GI) :-
+assertion__normalise_goal(switch(A,B,Case0s) - GI, switch(A,B,Cases)-GI) :-
assertion__normalise_cases(Case0s, Cases).
-assertion__normalise_goal(disj(Goal0s,B) - GI, disj(Goals,B) - GI) :-
+assertion__normalise_goal(disj(Goal0s) - GI, disj(Goals) - GI) :-
assertion__normalise_goals(Goal0s, Goals).
assertion__normalise_goal(not(Goal0) - GI, not(Goal) - GI) :-
assertion__normalise_goal(Goal0, Goal).
assertion__normalise_goal(some(A,B,Goal0) - GI, some(A,B,Goal) - GI) :-
assertion__normalise_goal(Goal0, Goal).
-assertion__normalise_goal(if_then_else(A, If0, Then0, Else0, E) - GI,
- if_then_else(A, If, Then, Else, E) - GI) :-
+assertion__normalise_goal(if_then_else(A, If0, Then0, Else0) - GI,
+ if_then_else(A, If, Then, Else) - GI) :-
assertion__normalise_goal(If0, If),
assertion__normalise_goal(Then0, Then),
assertion__normalise_goal(Else0, Else).
-assertion__normalise_goal(par_conj(Goal0s,B) - GI, par_conj(Goals,B) - GI) :-
+assertion__normalise_goal(par_conj(Goal0s) - GI, par_conj(Goals) - GI) :-
assertion__normalise_goals(Goal0s, Goals).
assertion__normalise_goal(shorthand(ShortHandGoal0) - GI0,
shorthand(ShortHandGoal) - GI) :-
@@ -773,20 +773,20 @@
).
assertion__in_interface_check(conj(Goals) - _, PredInfo, Module0, Module) -->
assertion__in_interface_check_list(Goals, PredInfo, Module0, Module).
-assertion__in_interface_check(switch(_,_,_,_) - _, _, _, _) -->
+assertion__in_interface_check(switch(_,_,_) - _, _, _, _) -->
{ error("assertion__in_interface_check: assertion contains switch.") }.
-assertion__in_interface_check(disj(Goals,_) - _, PredInfo, Module0, Module) -->
+assertion__in_interface_check(disj(Goals) - _, PredInfo, Module0, Module) -->
assertion__in_interface_check_list(Goals, PredInfo, Module0, Module).
assertion__in_interface_check(not(Goal) - _, PredInfo, Module0, Module) -->
assertion__in_interface_check(Goal, PredInfo, Module0, Module).
assertion__in_interface_check(some(_,_,Goal) - _, PredInfo, Module0, Module) -->
assertion__in_interface_check(Goal, PredInfo, Module0, Module).
-assertion__in_interface_check(if_then_else(_, If, Then, Else, _) - _,
+assertion__in_interface_check(if_then_else(_, If, Then, Else) - _,
PredInfo, Module0, Module) -->
assertion__in_interface_check(If, PredInfo, Module0, Module1),
assertion__in_interface_check(Then, PredInfo, Module1, Module2),
assertion__in_interface_check(Else, PredInfo, Module2, Module).
-assertion__in_interface_check(par_conj(Goals,_) - _, PredInfo,
+assertion__in_interface_check(par_conj(Goals) - _, PredInfo,
Module0, Module) -->
assertion__in_interface_check_list(Goals, PredInfo, Module0, Module).
assertion__in_interface_check(shorthand(ShorthandGoal) - _GoalInfo, PredInfo,
Index: compiler/bytecode_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/bytecode_gen.m,v
retrieving revision 1.67
diff -u -b -r1.67 bytecode_gen.m
--- compiler/bytecode_gen.m 7 Mar 2002 08:29:42 -0000 1.67
+++ compiler/bytecode_gen.m 8 Mar 2002 04:04:07 -0000
@@ -231,10 +231,10 @@
GoalExpr = conj(GoalList),
bytecode_gen__conj(GoalList, ByteInfo0, ByteInfo, Code)
;
- GoalExpr = par_conj(_GoalList, _SM),
+ GoalExpr = par_conj(_GoalList),
sorry(this_file, "bytecode_gen of parallel conjunction")
;
- GoalExpr = disj(GoalList, _),
+ GoalExpr = disj(GoalList),
( GoalList = [] ->
Code = node([fail]),
ByteInfo = ByteInfo0
@@ -248,7 +248,7 @@
Code = tree(EnterCode, tree(DisjCode, EndofCode))
)
;
- GoalExpr = switch(Var, _, CasesList, _),
+ GoalExpr = switch(Var, _, CasesList),
bytecode_gen__get_next_label(ByteInfo0, EndLabel, ByteInfo1),
bytecode_gen__switch(CasesList, Var, ByteInfo1, EndLabel,
ByteInfo, SwitchCode),
@@ -257,7 +257,7 @@
EndofCode = node([endof_switch, label(EndLabel)]),
Code = tree(EnterCode, tree(SwitchCode, EndofCode))
;
- GoalExpr = if_then_else(_Vars, Cond, Then, Else, _),
+ GoalExpr = if_then_else(_Vars, Cond, Then, Else),
bytecode_gen__get_next_label(ByteInfo0, EndLabel, ByteInfo1),
bytecode_gen__get_next_label(ByteInfo1, ElseLabel, ByteInfo2),
bytecode_gen__get_next_temp(ByteInfo2, FrameTemp, ByteInfo3),
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.149
diff -u -b -r1.149 call_gen.m
--- compiler/call_gen.m 24 May 2001 05:10:05 -0000 1.149
+++ compiler/call_gen.m 9 Jan 2002 09:36:23 -0000
@@ -53,7 +53,7 @@
:- implementation.
-:- import_module hlds_module, hlds_data.
+:- import_module hlds_module, hlds_data, hlds_llds.
:- import_module polymorphism, type_util, mode_util, unify_proc, instmap.
:- import_module builtin_ops.
:- import_module arg_info, code_util, trace.
@@ -219,12 +219,9 @@
% not stuff up the argument numbers in error messages).
% Here is as good a place as any.
get_state_args_det(Types0, TupleTypes, _, _),
- call_gen__remove_tuple_state_arg(TupleTypes,
- Args0, Args),
- call_gen__remove_tuple_state_arg(TupleTypes,
- Types0, Types),
- call_gen__remove_tuple_state_arg(TupleTypes,
- Modes0, Modes)
+ call_gen__remove_tuple_state_arg(TupleTypes, Args0, Args),
+ call_gen__remove_tuple_state_arg(TupleTypes, Types0, Types),
+ call_gen__remove_tuple_state_arg(TupleTypes, Modes0, Modes)
;
Args = Args0,
Types = Types0,
@@ -592,13 +589,19 @@
hlds_goal_info::in, set(prog_var)::in, instmap::in,
list(liveinfo)::out, code_info::in, code_info::out) is det.
-call_gen__handle_return(ArgsInfos, _GoalInfo, _NonLiveOutputs, ReturnInstMap,
+call_gen__handle_return(ArgsInfos, GoalInfo, _NonLiveOutputs, ReturnInstMap,
ReturnLiveLvalues) -->
- code_info__clear_all_registers,
+ { goal_info_get_instmap_delta(GoalInfo, InstMapDelta) },
+ { instmap_delta_is_reachable(InstMapDelta) ->
+ OkToDeleteAny = no
+ ;
+ OkToDeleteAny = yes
+ },
+ code_info__clear_all_registers(OkToDeleteAny),
code_info__get_forward_live_vars(Liveness),
call_gen__rebuild_registers(ArgsInfos, Liveness, OutputArgLocs),
code_info__generate_return_live_lvalues(OutputArgLocs, ReturnInstMap,
- ReturnLiveLvalues).
+ OkToDeleteAny, ReturnLiveLvalues).
:- pred call_gen__find_nonlive_outputs(assoc_list(prog_var, arg_info)::in,
set(prog_var)::in, set(prog_var)::in, set(prog_var)::out) is det.
Index: compiler/clause_to_proc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/clause_to_proc.m,v
retrieving revision 1.31
diff -u -b -r1.31 clause_to_proc.m
--- compiler/clause_to_proc.m 31 Jul 2001 14:29:29 -0000 1.31
+++ compiler/clause_to_proc.m 31 Jul 2001 23:41:28 -0000
@@ -190,8 +190,7 @@
GoalInfo2 = GoalInfo
),
- map__init(Empty),
- Goal = disj(GoalList, Empty) - GoalInfo
+ Goal = disj(GoalList) - GoalInfo
),
proc_info_set_body(Proc0, VarSet, VarTypes, HeadVars, Goal,
TI_VarMap, TCI_VarMap, Proc).
Index: compiler/code_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_aux.m,v
retrieving revision 1.62
diff -u -b -r1.62 code_aux.m
--- compiler/code_aux.m 3 Apr 2001 03:19:24 -0000 1.62
+++ compiler/code_aux.m 18 Jul 2001 11:38:24 -0000
@@ -1,5 +1,4 @@
-%-----------------------------------------------------------------------------%
-% Copyright (C) 1994-2001 The University of Melbourne.
+%-----------------------------------------------------------------------------% % Copyright (C) 1994-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.
%---------------------------------------------------------------------------%
@@ -15,7 +14,7 @@
:- interface.
-:- import_module code_info, hlds_module, hlds_goal, prog_data.
+:- import_module code_info, hlds_module, hlds_goal, hlds_llds, prog_data.
:- import_module bool.
% code_aux__contains_only_builtins(G) is true if G is a leaf procedure,
@@ -77,15 +76,15 @@
code_aux__contains_only_builtins_2(conj(Goals)) :-
code_aux__contains_only_builtins_list(Goals).
-code_aux__contains_only_builtins_2(disj(Goals, _)) :-
+code_aux__contains_only_builtins_2(disj(Goals)) :-
code_aux__contains_only_builtins_list(Goals).
-code_aux__contains_only_builtins_2(switch(_Var, _Category, Cases, _)) :-
+code_aux__contains_only_builtins_2(switch(_Var, _Category, Cases)) :-
code_aux__contains_only_builtins_cases(Cases).
code_aux__contains_only_builtins_2(not(Goal)) :-
code_aux__contains_only_builtins(Goal).
code_aux__contains_only_builtins_2(some(_Vars, _, Goal)) :-
code_aux__contains_only_builtins(Goal).
-code_aux__contains_only_builtins_2(if_then_else(_Vars, Cond, Then, Else, _)) :-
+code_aux__contains_only_builtins_2(if_then_else(_Vars, Cond, Then, Else)) :-
code_aux__contains_only_builtins(Cond),
code_aux__contains_only_builtins(Then),
code_aux__contains_only_builtins(Else).
@@ -146,11 +145,11 @@
code_aux__goal_cannot_loop_expr(MaybeModuleInfo, conj(Goals)) :-
list__member(Goal, Goals) =>
code_aux__goal_cannot_loop_aux(MaybeModuleInfo, Goal).
-code_aux__goal_cannot_loop_expr(MaybeModuleInfo, disj(Goals, _)) :-
+code_aux__goal_cannot_loop_expr(MaybeModuleInfo, disj(Goals)) :-
list__member(Goal, Goals) =>
code_aux__goal_cannot_loop_aux(MaybeModuleInfo, Goal).
code_aux__goal_cannot_loop_expr(MaybeModuleInfo,
- switch(_Var, _Category, Cases, _)) :-
+ switch(_Var, _Category, Cases)) :-
list__member(Case, Cases) =>
(
Case = case(_, Goal),
@@ -161,7 +160,7 @@
code_aux__goal_cannot_loop_expr(MaybeModuleInfo, some(_Vars, _, Goal)) :-
code_aux__goal_cannot_loop_aux(MaybeModuleInfo, Goal).
code_aux__goal_cannot_loop_expr(MaybeModuleInfo,
- if_then_else(_Vars, Cond, Then, Else, _)) :-
+ if_then_else(_Vars, Cond, Then, Else)) :-
code_aux__goal_cannot_loop_aux(MaybeModuleInfo, Cond),
code_aux__goal_cannot_loop_aux(MaybeModuleInfo, Then),
code_aux__goal_cannot_loop_aux(MaybeModuleInfo, Else).
Index: compiler/code_exprn.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_exprn.m,v
retrieving revision 1.63
diff -u -b -r1.63 code_exprn.m
--- compiler/code_exprn.m 12 Sep 2000 00:13:30 -0000 1.63
+++ compiler/code_exprn.m 18 Jul 2001 11:51:04 -0000
@@ -36,7 +36,7 @@
:- interface.
-:- import_module prog_data, hlds_goal, llds, options.
+:- import_module prog_data, hlds_llds, llds, options.
:- import_module map, set, list, assoc_list.
:- type exprn_info.
Index: compiler/code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.99
diff -u -b -r1.99 code_gen.m
--- compiler/code_gen.m 20 Feb 2002 03:13:52 -0000 1.99
+++ compiler/code_gen.m 8 Mar 2002 04:09:46 -0000
@@ -57,6 +57,10 @@
:- pred code_gen__generate_goal(code_model::in, hlds_goal::in, code_tree::out,
code_info::in, code_info::out) is det.
+ % Return the message that identifies the procedure to pass to
+ % the incr_sp_push_msg macro in the generated C code.
+:- func code_gen__push_msg(module_info, pred_id, proc_id) = string.
+
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
@@ -67,6 +71,7 @@
% HLDS modules
:- import_module hlds_out, instmap, type_util, mode_util, goal_util.
+:- import_module hlds_llds.
% LLDS code generator modules.
:- import_module call_gen, unify_gen, ite_gen, switch_gen, disj_gen.
@@ -728,14 +733,12 @@
;
{ TraceFillCode = empty }
),
+ { module_info_pred_info(ModuleInfo, PredId, PredInfo) },
+ { pred_info_module(PredInfo, ModuleName) },
+ { pred_info_name(PredInfo, PredName) },
+ { pred_info_arity(PredInfo, Arity) },
- { predicate_module(ModuleInfo, PredId, ModuleName) },
- { predicate_name(ModuleInfo, PredId, PredName) },
- { predicate_arity(ModuleInfo, PredId, Arity) },
- { prog_out__sym_name_to_string(ModuleName, ModuleNameString) },
- { string__int_to_string(Arity, ArityStr) },
- { string__append_list([ModuleNameString, ":", PredName, "/", ArityStr],
- PushMsg) },
+ { PushMsg = code_gen__push_msg(ModuleInfo, PredId, ProcId) },
(
{ CodeModel = model_non }
->
@@ -935,7 +938,8 @@
{ PruneTraceTicketCode = node([
prune_ticket - "prune retry ticket"
]) },
- { PruneTraceTicketCodeCopy = PruneTraceTicketCode }
+ { PruneTraceTicketCodeCopy =
+ PruneTraceTicketCode }
)
;
{ PruneTraceTicketCode = empty },
@@ -1123,46 +1127,41 @@
unify_gen__generate_unification(CodeModel, Uni, GoalInfo, Code).
code_gen__generate_goal_2(conj(Goals), _GoalInfo, CodeModel, Code) -->
code_gen__generate_goals(Goals, CodeModel, Code).
-code_gen__generate_goal_2(par_conj(Goals, _SM), GoalInfo, CodeModel, Code) -->
+code_gen__generate_goal_2(par_conj(Goals), GoalInfo, CodeModel, Code) -->
par_conj_gen__generate_par_conj(Goals, GoalInfo, CodeModel, Code).
-code_gen__generate_goal_2(disj(Goals, StoreMap), _, CodeModel, Code) -->
- disj_gen__generate_disj(CodeModel, Goals, StoreMap, Code).
+code_gen__generate_goal_2(disj(Goals), GoalInfo, CodeModel, Code) -->
+ disj_gen__generate_disj(CodeModel, Goals, GoalInfo, Code).
code_gen__generate_goal_2(not(Goal), _GoalInfo, CodeModel, Code) -->
ite_gen__generate_negation(CodeModel, Goal, Code).
-code_gen__generate_goal_2(if_then_else(_Vars, Cond, Then, Else, StoreMap),
- _GoalInfo, CodeModel, Code) -->
- ite_gen__generate_ite(CodeModel, Cond, Then, Else, StoreMap, Code).
-code_gen__generate_goal_2(switch(Var, CanFail, CaseList, StoreMap),
+code_gen__generate_goal_2(if_then_else(_Vars, Cond, Then, Else),
+ GoalInfo, CodeModel, Code) -->
+ ite_gen__generate_ite(CodeModel, Cond, Then, Else, GoalInfo, Code).
+code_gen__generate_goal_2(switch(Var, CanFail, CaseList),
GoalInfo, CodeModel, Code) -->
switch_gen__generate_switch(CodeModel, Var, CanFail, CaseList,
- StoreMap, GoalInfo, Code).
+ GoalInfo, Code).
code_gen__generate_goal_2(some(_Vars, _, Goal), _GoalInfo, CodeModel, Code) -->
commit_gen__generate_commit(CodeModel, Goal, Code).
code_gen__generate_goal_2(generic_call(GenericCall, Args, Modes, Det),
GoalInfo, CodeModel, Code) -->
call_gen__generate_generic_call(CodeModel, GenericCall, Args,
Modes, Det, GoalInfo, Code).
-
-code_gen__generate_goal_2(call(PredId, ProcId, Args, BuiltinState, _, _),
+code_gen__generate_goal_2(call(PredId, ProcId, Args, BuiltinState, _,_),
GoalInfo, CodeModel, Code) -->
- (
- { BuiltinState = not_builtin }
- ->
+ ( { BuiltinState = not_builtin } ->
call_gen__generate_call(CodeModel, PredId, ProcId, Args,
GoalInfo, Code)
;
call_gen__generate_builtin(CodeModel, PredId, ProcId, Args,
Code)
).
-code_gen__generate_goal_2(foreign_proc(Attributes,
- PredId, ModeId, Args, ArgNames, OrigArgTypes, PragmaCode),
- GoalInfo, CodeModel, Instr) -->
- (
- { foreign_language(Attributes, c) }
- ->
+code_gen__generate_goal_2(foreign_proc(Attributes, PredId, ProcId,
+ Args, ArgNames, OrigArgTypes, PragmaCode),
+ GoalInfo, CodeModel, Code) -->
+ ( { foreign_language(Attributes, c) } ->
pragma_c_gen__generate_pragma_c_code(CodeModel, Attributes,
- PredId, ModeId, Args, ArgNames, OrigArgTypes,
- GoalInfo, PragmaCode, Instr)
+ PredId, ProcId, Args, ArgNames, OrigArgTypes,
+ PragmaCode, GoalInfo, Code)
;
{ error("code_gen__generate_goal_2: foreign code other than C unexpected") }
).
@@ -1304,5 +1303,64 @@
may_call_mercury, no, no, no, no, no
) - "Entry stub"
].
+
+%---------------------------------------------------------------------------%
+
+:- type type_giving_arg ---> last_arg ; last_but_one_arg.
+
+code_gen__push_msg(ModuleInfo, PredId, ProcId) = PushMsg :-
+ module_info_pred_info(ModuleInfo, PredId, PredInfo),
+ pred_info_get_is_pred_or_func(PredInfo, PredOrFunc),
+ pred_info_module(PredInfo, ModuleName),
+ pred_info_name(PredInfo, PredName),
+ pred_info_arity(PredInfo, Arity),
+ (
+ ( PredName = "__Unify__", WhichArg = last_arg
+ ; PredName = "__Index__", WhichArg = last_but_one_arg
+ ; PredName = "__Compare__", WhichArg = last_arg
+ )
+ ->
+ pred_info_arg_types(PredInfo, ArgTypes),
+ code_gen__find_arg_type_ctor(WhichArg, ArgTypes, TypeName),
+ string__append_list([PredName, "for_", TypeName],
+ FullPredName)
+ ;
+ FullPredName = PredName
+ ),
+ (
+ PredOrFunc = predicate,
+ PredOrFuncString = "pred "
+ ;
+ PredOrFunc = function,
+ PredOrFuncString = "func "
+ ),
+ prog_out__sym_name_to_string(ModuleName, ModuleNameString),
+ string__int_to_string(Arity, ArityStr),
+ proc_id_to_int(ProcId, ProcNum),
+ string__int_to_string(ProcNum, ProcNumStr),
+ string__append_list([PredOrFuncString, ModuleNameString, ":",
+ FullPredName, "/", ArityStr, "-", ProcNumStr], PushMsg).
+
+:- pred code_gen__find_arg_type_ctor(type_giving_arg::in, list(type)::in,
+ string::out) is det.
+
+code_gen__find_arg_type_ctor(WhichArg, ArgTypes, TypeName) :-
+ list__reverse(ArgTypes, RevArgTypes),
+ (
+ WhichArg = last_arg,
+ ChosenArgType = list__index1_det(RevArgTypes, 1)
+ ;
+ WhichArg = last_but_one_arg,
+ ChosenArgType = list__index1_det(RevArgTypes, 2)
+ ),
+ ( type_to_ctor_and_args(ChosenArgType, TypeCtor, _) ->
+ TypeCtor = TypeCtorSymName - TypeCtorArity,
+ prog_out__sym_name_to_string(TypeCtorSymName, TypeCtorName),
+ string__int_to_string(TypeCtorArity, ArityStr),
+ string__append_list([TypeCtorName, "_", ArityStr], TypeName)
+ ;
+ TypeName = "unknown"
+ ).
+
%---------------------------------------------------------------------------%
Index: compiler/code_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.265
diff -u -b -r1.265 code_info.m
--- compiler/code_info.m 7 Mar 2002 08:29:42 -0000 1.265
+++ compiler/code_info.m 8 Mar 2002 04:04:10 -0000
@@ -30,8 +30,8 @@
:- interface.
:- import_module prog_data.
-:- import_module hlds_module, hlds_pred, hlds_goal, hlds_data, instmap.
-:- import_module code_model.
+:- import_module hlds_module, hlds_pred, hlds_goal, hlds_data, hlds_llds.
+:- import_module instmap, code_model.
:- import_module llds, continuation_info, trace.
:- import_module globals.
@@ -170,6 +170,9 @@
:- pred code_info__set_maybe_trace_info(maybe(trace_info)::in,
code_info::in, code_info::out) is det.
+:- pred code_info__get_opt_no_return_calls(bool::out,
+ code_info::in, code_info::out) is det.
+
:- pred code_info__get_zombies(set(prog_var)::out,
code_info::in, code_info::out) is det.
@@ -271,11 +274,12 @@
% for storing variables.
% (Some extra stack slots are used
% for saving and restoring registers.)
- maybe_trace_info :: maybe(trace_info)
+ maybe_trace_info :: maybe(trace_info),
% Information about which stack slots
% the call sequence number and depth
% are stored in, provided tracing is
% switched on.
+ opt_no_resume_calls :: bool
).
:- type code_info_loc_dep --->
@@ -362,11 +366,8 @@
:-
proc_info_get_initial_instmap(ProcInfo, ModuleInfo, InstMap),
proc_info_liveness_info(ProcInfo, Liveness),
- proc_info_headvars(ProcInfo, HeadVars),
- proc_info_arg_info(ProcInfo, ArgInfos),
proc_info_interface_code_model(ProcInfo, CodeModel),
- assoc_list__from_corresponding_lists(HeadVars, ArgInfos, Args),
- arg_info__build_input_arg_list(Args, ArgList),
+ arg_info__build_input_arg_list(ProcInfo, ArgList),
proc_info_varset(ProcInfo, VarSet),
proc_info_stack_slots(ProcInfo, StackSlots),
globals__lookup_bool_option(Globals, lazy_code, LazyCode),
@@ -411,6 +412,8 @@
code_info__max_var_slot(StackSlots, VarSlotMax),
trace__reserved_slots(ModuleInfo, ProcInfo, Globals, FixedSlots, _),
int__max(VarSlotMax, FixedSlots, SlotMax),
+ globals__lookup_bool_option(Globals, opt_no_return_calls,
+ OptNoReturnCalls),
CodeInfo0 = code_info(
code_info_static(
Globals,
@@ -420,7 +423,8 @@
ProcInfo,
VarSet,
SlotMax,
- no
+ no,
+ OptNoReturnCalls
),
code_info_loc_dep(
Liveness,
@@ -473,6 +477,8 @@
code_info__get_varset(CI^code_info_static^varset, CI, CI).
code_info__get_var_slot_count(CI^code_info_static^var_slot_count, CI, CI).
code_info__get_maybe_trace_info(CI^code_info_static^maybe_trace_info, CI, CI).
+code_info__get_opt_no_return_calls(CI^code_info_static^opt_no_resume_calls,
+ CI, CI).
code_info__get_forward_live_vars(CI^code_info_loc_dep^forward_live_vars,
CI, CI).
code_info__get_instmap(CI^code_info_loc_dep^instmap, CI, CI).
@@ -1018,7 +1024,20 @@
code_info__set_follow_vars(follow_vars(FollowVarsMap,
MaxMentionedReg + 1))
),
- code_info__place_vars(VarLocs, Code),
+ code_info__get_instmap(InstMap),
+ ( { instmap__is_reachable(InstMap) } ->
+ code_info__place_vars(VarLocs, Code)
+ ;
+ % With --opt-no-return-call, the variables that we would have
+ % saved across a call that cannot return have had the last
+ % of their code generation state destroyed, so calling
+ % place_vars would cause a code generator abort. However,
+ % pretending that all the variables are where the store map
+ % says they should be is perfectly fine, since we can never
+ % reach the end of *this* branch anyway.
+ code_info__remake_with_store_map(StoreMap),
+ { Code = empty }
+ ),
=(EndCodeInfo1),
{
MaybeEnd0 = no,
@@ -1242,8 +1261,8 @@
:- pred code_info__set_resume_point_to_unknown(code_info::in, code_info::out)
is det.
- % Call this predicate to say "we have just returned a model_non call;
- % we don't know what address the following code will need to
+ % Call this predicate to say "we have just returned from a model_non
+ % call; we don't know what address the following code will need to
% backtrack to, and there may now be nondet frames on top of ours
% that do not have their redofr slots pointing to our frame".
@@ -2403,19 +2422,15 @@
{ ResumePoint = orig_only(OrigMap, OrigAddr) }
;
{ ResumeLocs = stack_only },
- { map__select(StackSlots, ResumeVars, StackMap0) },
- { map__to_assoc_list(StackMap0, StackList0) },
- { code_info__make_singleton_sets(StackList0, StackList) },
- { map__from_assoc_list(StackList, StackMap) },
+ { code_info__make_stack_resume_map(ResumeVars,
+ StackSlots, StackMap) },
code_info__get_next_label(StackLabel),
{ StackAddr = label(StackLabel) },
{ ResumePoint = stack_only(StackMap, StackAddr) }
;
{ ResumeLocs = orig_and_stack },
- { map__select(StackSlots, ResumeVars, StackMap0) },
- { map__to_assoc_list(StackMap0, StackList0) },
- { code_info__make_singleton_sets(StackList0, StackList) },
- { map__from_assoc_list(StackList, StackMap) },
+ { code_info__make_stack_resume_map(ResumeVars,
+ StackSlots, StackMap) },
code_info__get_next_label(OrigLabel),
{ OrigAddr = label(OrigLabel) },
code_info__get_next_label(StackLabel),
@@ -2424,10 +2439,8 @@
StackMap, StackAddr) }
;
{ ResumeLocs = stack_and_orig },
- { map__select(StackSlots, ResumeVars, StackMap0) },
- { map__to_assoc_list(StackMap0, StackList0) },
- { code_info__make_singleton_sets(StackList0, StackList) },
- { map__from_assoc_list(StackList, StackMap) },
+ { code_info__make_stack_resume_map(ResumeVars,
+ StackSlots, StackMap) },
code_info__get_next_label(StackLabel),
{ StackAddr = label(StackLabel) },
code_info__get_next_label(OrigLabel),
@@ -2436,6 +2449,15 @@
OrigMap, OrigAddr) }
).
+:- pred code_info__make_stack_resume_map(set(prog_var)::in, stack_slots::in,
+ map(prog_var, set(lval))::out) is det.
+
+code_info__make_stack_resume_map(ResumeVars, StackSlots, StackMap) :-
+ map__select(StackSlots, ResumeVars, StackMap0),
+ map__to_assoc_list(StackMap0, StackList0),
+ code_info__make_singleton_sets(StackList0, StackList),
+ map__from_assoc_list(StackList, StackMap).
+
:- pred code_info__make_singleton_sets(assoc_list(prog_var, lval)::in,
assoc_list(prog_var, set(lval))::out) is det.
@@ -3105,7 +3127,7 @@
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
- % Submodule to deal with code_exprn.
+ % Submodule to deal with code_exprn or var_locn.
:- interface.
@@ -3167,6 +3189,11 @@
% - The variables that need to be saved across the call (either because
% they are forward live after the call or because they are protected
% by an enclosing resumption point) will be saved on the stack.
+ % Note that if the call cannot succeed and the trace level is none,
+ % then no variables need to be saved across the call. (If the call
+ % cannot succeed but the trace level is not none, then we still
+ % save the usual variables on the stack to make them available
+ % for up-level printing in the debugger.)
%
% - The input arguments will be moved to their registers.
@@ -3185,7 +3212,12 @@
:- pred code_info__eager_unlock_regs(code_info::in, code_info::out) is det.
-:- pred code_info__clear_all_registers(code_info::in, code_info::out) is det.
+ % Record the fact that all the registers have been clobbered (as by a
+ % call). If the bool argument is true, then the call cannot return, and
+ % thus it is OK for this action to delete the last record of the state
+ % of a variable.
+:- pred code_info__clear_all_registers(bool::in,
+ code_info::in, code_info::out) is det.
:- pred code_info__clobber_regs(list(lval)::in,
code_info::in, code_info::out) is det.
@@ -3546,22 +3578,34 @@
{ partition_args(ArgInfos, InArgInfos, OutArgInfos, _UnusedArgInfos) },
{ assoc_list__keys(OutArgInfos, OutVars) },
{ set__list_to_set(OutVars, OutVarSet) },
- code_info__compute_forward_live_var_saves(OutVarSet, ForwardVarLocs),
-
+ { goal_info_get_determinism(GoalInfo, Detism) },
+ code_info__get_opt_no_return_calls(OptNoReturnCalls),
+ (
+ { Detism = erroneous },
+ { OptNoReturnCalls = yes }
+ ->
+ { StackVarLocs = [] }
+ ;
+ code_info__compute_forward_live_var_saves(OutVarSet,
+ ForwardVarLocs),
{ goal_info_get_code_model(GoalInfo, CodeModel) },
( { CodeModel = model_non } ->
- % Save variables protected by the nearest resumption
- % point on the stack. XXX This should be unnecessary;
- % with the current setup, the code that established
- % the resume point should have saved those variables
- % on the stack already. However, later we should
- % arrange things so that this saving of the resume vars
- % on the stack is delayed until the first call after
- % the setup of the resume point.
+ % Save variables protected by the nearest
+ % resumption point on the stack. XXX This
+ % should be unnecessary; with the current
+ % setup, the code that established the resume
+ % point should have saved those variables
+ % on the stack already. However, later we
+ % should arrange things so that this saving
+ % of the resume vars on the stack is delayed
+ % until the first call after the setup of
+ % the resume point.
code_info__compute_resume_var_stack_locs(ResumeVarLocs),
- { list__append(ResumeVarLocs, ForwardVarLocs, StackVarLocs) }
+ { list__append(ResumeVarLocs, ForwardVarLocs,
+ StackVarLocs) }
;
{ StackVarLocs = ForwardVarLocs }
+ )
),
code_info__get_var_locns_info(VarInfo0),
@@ -3777,7 +3821,7 @@
% As a sanity check, we could test whether any known variable
% has its only value in a register, but we do so only with eager
% code generation.
-code_info__clear_all_registers -->
+code_info__clear_all_registers(OkToDeleteAny) -->
code_info__get_var_locns_info(VarInfo0),
{
VarInfo0 = exprn_info(Exprn0),
@@ -3785,7 +3829,7 @@
VarInfo = exprn_info(Exprn)
;
VarInfo0 = var_locn_info(VarLocn0),
- var_locn__clobber_all_regs(VarLocn0, VarLocn),
+ var_locn__clobber_all_regs(OkToDeleteAny, VarLocn0, VarLocn),
VarInfo = var_locn_info(VarLocn)
},
code_info__set_var_locns_info(VarInfo).
@@ -3865,8 +3909,8 @@
is det.
:- pred code_info__generate_return_live_lvalues(
- assoc_list(prog_var, arg_loc)::in, instmap::in, list(liveinfo)::out,
- code_info::in, code_info::out) is det.
+ assoc_list(prog_var, arg_loc)::in, instmap::in, bool::in,
+ list(liveinfo)::out, code_info::in, code_info::out) is det.
%---------------------------------------------------------------------------%
@@ -3920,7 +3964,7 @@
%---------------------------------------------------------------------------%
code_info__generate_return_live_lvalues(OutputArgLocs, ReturnInstMap,
- LiveLvalues) -->
+ OkToDeleteAny, LiveLvalues) -->
code_info__variable_locations(VarLocs),
code_info__get_known_variables(Vars),
code_info__get_active_temps_data(Temps),
@@ -3929,7 +3973,7 @@
code_info__get_module_info(ModuleInfo),
{ continuation_info__generate_return_live_lvalues(OutputArgLocs,
ReturnInstMap, Vars, VarLocs, Temps, ProcInfo, ModuleInfo,
- Globals, LiveLvalues) }.
+ Globals, OkToDeleteAny, LiveLvalues) }.
:- pred code_info__generate_resume_layout(label::in, resume_map::in,
code_info::in, code_info::out) is det.
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.135
diff -u -b -r1.135 code_util.m
--- compiler/code_util.m 7 Mar 2002 08:29:45 -0000 1.135
+++ compiler/code_util.m 8 Mar 2002 04:04:12 -0000
@@ -154,6 +154,13 @@
:- pred code_util__cannot_stack_flush(hlds_goal).
:- mode code_util__cannot_stack_flush(in) is semidet.
+ % Succeed if the given goal cannot encounter a context
+ % that causes any variable to be flushed to its stack slot or to a
+ % register.
+
+:- pred code_util__cannot_flush(hlds_goal).
+:- mode code_util__cannot_flush(in) is semidet.
+
% Succeed if the given goal cannot fail before encountering a context
% that forces all variables to be flushed to their stack slots.
% If such a goal needs a resume point, the only entry point we need
@@ -487,12 +494,12 @@
code_util__goal_may_allocate_heap(Goal, May).
code_util__goal_may_allocate_heap_2(conj(Goals), May) :-
code_util__goal_list_may_allocate_heap(Goals, May).
-code_util__goal_may_allocate_heap_2(par_conj(_, _), yes).
-code_util__goal_may_allocate_heap_2(disj(Goals, _), May) :-
+code_util__goal_may_allocate_heap_2(par_conj(_), yes).
+code_util__goal_may_allocate_heap_2(disj(Goals), May) :-
code_util__goal_list_may_allocate_heap(Goals, May).
-code_util__goal_may_allocate_heap_2(switch(_Var, _Det, Cases, _), May) :-
+code_util__goal_may_allocate_heap_2(switch(_Var, _Det, Cases), May) :-
code_util__cases_may_allocate_heap(Cases, May).
-code_util__goal_may_allocate_heap_2(if_then_else(_Vars, C, T, E, _), May) :-
+code_util__goal_may_allocate_heap_2(if_then_else(_Vars, C, T, E), May) :-
( code_util__goal_may_allocate_heap(C, yes) ->
May = yes
; code_util__goal_may_allocate_heap(T, yes) ->
@@ -570,13 +577,13 @@
code_util__goal_may_alloc_temp_frame(Goal, May).
code_util__goal_may_alloc_temp_frame_2(conj(Goals), May) :-
code_util__goal_list_may_alloc_temp_frame(Goals, May).
-code_util__goal_may_alloc_temp_frame_2(par_conj(Goals, _), May) :-
+code_util__goal_may_alloc_temp_frame_2(par_conj(Goals), May) :-
code_util__goal_list_may_alloc_temp_frame(Goals, May).
-code_util__goal_may_alloc_temp_frame_2(disj(Goals, _), May) :-
+code_util__goal_may_alloc_temp_frame_2(disj(Goals), May) :-
code_util__goal_list_may_alloc_temp_frame(Goals, May).
-code_util__goal_may_alloc_temp_frame_2(switch(_Var, _Det, Cases, _), May) :-
+code_util__goal_may_alloc_temp_frame_2(switch(_Var, _Det, Cases), May) :-
code_util__cases_may_alloc_temp_frame(Cases, May).
-code_util__goal_may_alloc_temp_frame_2(if_then_else(_Vars, C, T, E, _), May) :-
+code_util__goal_may_alloc_temp_frame_2(if_then_else(_Vars, C, T, E), May) :-
( code_util__goal_may_alloc_temp_frame(C, yes) ->
May = yes
; code_util__goal_may_alloc_temp_frame(T, yes) ->
@@ -598,7 +605,6 @@
code_util__goal_may_alloc_temp_frame(G2, May)
).
-
:- pred code_util__goal_list_may_alloc_temp_frame(list(hlds_goal)::in,
bool::out) is det.
@@ -753,8 +759,10 @@
BuiltinState = inline_builtin.
code_util__cannot_stack_flush_2(conj(Goals)) :-
code_util__cannot_stack_flush_goals(Goals).
-code_util__cannot_stack_flush_2(switch(_, _, Cases, _)) :-
+code_util__cannot_stack_flush_2(switch(_, _, Cases)) :-
code_util__cannot_stack_flush_cases(Cases).
+code_util__cannot_stack_flush_2(not(unify(_, _, _, Unify, _) - _)) :-
+ Unify \= complicated_unify(_, _, _).
:- pred code_util__cannot_stack_flush_goals(list(hlds_goal)).
:- mode code_util__cannot_stack_flush_goals(in) is semidet.
@@ -774,6 +782,29 @@
%-----------------------------------------------------------------------------%
+code_util__cannot_flush(GoalExpr - _) :-
+ code_util__cannot_flush_2(GoalExpr).
+
+:- pred code_util__cannot_flush_2(hlds_goal_expr).
+:- mode code_util__cannot_flush_2(in) is semidet.
+
+code_util__cannot_flush_2(unify(_, _, _, Unify, _)) :-
+ Unify \= complicated_unify(_, _, _).
+code_util__cannot_flush_2(call(_, _, _, BuiltinState, _, _)) :-
+ BuiltinState = inline_builtin.
+code_util__cannot_flush_2(conj(Goals)) :-
+ code_util__cannot_flush_goals(Goals).
+
+:- pred code_util__cannot_flush_goals(list(hlds_goal)).
+:- mode code_util__cannot_flush_goals(in) is semidet.
+
+code_util__cannot_flush_goals([]).
+code_util__cannot_flush_goals([Goal | Goals]) :-
+ code_util__cannot_flush(Goal),
+ code_util__cannot_flush_goals(Goals).
+
+%-----------------------------------------------------------------------------%
+
code_util__cannot_fail_before_stack_flush(GoalExpr - GoalInfo) :-
goal_info_get_determinism(GoalInfo, Detism),
determinism_components(Detism, CanFail, _),
@@ -845,14 +876,16 @@
code_util__count_recursive_calls_2(conj(Goals), PredId, ProcId, Min, Max) :-
code_util__count_recursive_calls_conj(Goals, PredId, ProcId, 0, 0,
Min, Max).
-code_util__count_recursive_calls_2(par_conj(Goals, _), PredId, ProcId, Min, Max) :-
- code_util__count_recursive_calls_conj(Goals, PredId, ProcId, 0, 0, Min, Max).
-code_util__count_recursive_calls_2(disj(Goals, _), PredId, ProcId, Min, Max) :-
+code_util__count_recursive_calls_2(par_conj(Goals), PredId, ProcId,
+ Min, Max) :-
+ code_util__count_recursive_calls_conj(Goals, PredId, ProcId, 0, 0,
+ Min, Max).
+code_util__count_recursive_calls_2(disj(Goals), PredId, ProcId, Min, Max) :-
code_util__count_recursive_calls_disj(Goals, PredId, ProcId, Min, Max).
-code_util__count_recursive_calls_2(switch(_, _, Cases, _), PredId, ProcId,
+code_util__count_recursive_calls_2(switch(_, _, Cases), PredId, ProcId,
Min, Max) :-
code_util__count_recursive_calls_cases(Cases, PredId, ProcId, Min, Max).
-code_util__count_recursive_calls_2(if_then_else(_, Cond, Then, Else, _),
+code_util__count_recursive_calls_2(if_then_else(_, Cond, Then, Else),
PredId, ProcId, Min, Max) :-
code_util__count_recursive_calls(Cond, PredId, ProcId, CMin, CMax),
code_util__count_recursive_calls(Then, PredId, ProcId, TMin, TMax),
Index: compiler/common.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/common.m,v
retrieving revision 1.61
diff -u -b -r1.61 common.m
--- compiler/common.m 7 Mar 2002 08:29:46 -0000 1.61
+++ compiler/common.m 8 Mar 2002 04:04:13 -0000
@@ -180,6 +180,10 @@
Goal = Goal0,
Info = Info0
;
+ % Do not delete deconstruction unifications inserted by
+ % stack_opt.m, which has done a more comprehensive cost
+ % analysis than common.m can do.
+ \+ goal_info_has_feature(GoalInfo, stack_opt),
common__find_matching_cell(Var, ConsId, ArgVars,
deconstruction, Info0, OldStruct)
->
Index: compiler/const_prop.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/const_prop.m,v
retrieving revision 1.13
diff -u -b -r1.13 const_prop.m
--- compiler/const_prop.m 3 Nov 2001 17:34:55 -0000 1.13
+++ compiler/const_prop.m 6 Nov 2001 05:08:05 -0000
@@ -376,7 +376,6 @@
:- mode make_true_or_fail(in, in, out, out) is det.
make_true_or_fail(yes, GoalInfo, conj([]), GoalInfo).
-make_true_or_fail(no, GoalInfo, disj([], SM), GoalInfo) :-
- map__init(SM).
+make_true_or_fail(no, GoalInfo, disj([]), GoalInfo).
%------------------------------------------------------------------------------%
Index: compiler/constraint.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/constraint.m,v
retrieving revision 1.46
diff -u -b -r1.46 constraint.m
--- compiler/constraint.m 20 Aug 2001 17:43:08 -0000 1.46
+++ compiler/constraint.m 21 Aug 2001 02:27:23 -0000
@@ -106,18 +106,18 @@
[conj(Goals) - Info]) -->
constraint__propagate_conj(Goals0, Constraints, Goals).
-constraint__propagate_conj_sub_goal_2(disj(Goals0, SM) - Info, Constraints,
- [disj(Goals, SM) - Info]) -->
+constraint__propagate_conj_sub_goal_2(disj(Goals0) - Info, Constraints,
+ [disj(Goals) - Info]) -->
constraint__propagate_disj(Goals0, Constraints, Goals).
-constraint__propagate_conj_sub_goal_2(switch(Var, CanFail, Cases0, SM) - Info,
- Constraints, [switch(Var, CanFail, Cases, SM) - Info]) -->
+constraint__propagate_conj_sub_goal_2(switch(Var, CanFail, Cases0) - Info,
+ Constraints, [switch(Var, CanFail, Cases) - Info]) -->
constraint__propagate_cases(Var, Cases0, Constraints, Cases).
constraint__propagate_conj_sub_goal_2(
- if_then_else(Vars, Cond0, Then0, Else0, SM) - Info,
+ if_then_else(Vars, Cond0, Then0, Else0) - Info,
Constraints,
- [if_then_else(Vars, Cond, Then, Else, SM) - Info]) -->
+ [if_then_else(Vars, Cond, Then, Else) - Info]) -->
InstMap0 =^ instmap,
% We can't safely propagate constraints into
@@ -132,9 +132,9 @@
% XXX propagate constraints into par_conjs -- this isn't
% possible at the moment because par_conj goals must have
% determinism det.
-constraint__propagate_conj_sub_goal_2(par_conj(Goals0, SM) - GoalInfo,
+constraint__propagate_conj_sub_goal_2(par_conj(Goals0) - GoalInfo,
Constraints0,
- [par_conj(Goals, SM) - GoalInfo | Constraints]) -->
+ [par_conj(Goals) - GoalInfo | Constraints]) -->
% Propagate constraints within the goals of the conjunction.
% constraint__propagate_disj treats its list of goals as
% independent rather than specifically disjoint, so we can
@@ -803,10 +803,10 @@
strip_constraint_markers_expr(conj(Goals)) =
conj(list__map(strip_constraint_markers, Goals)).
-strip_constraint_markers_expr(disj(Goals, SM)) =
- disj(list__map(strip_constraint_markers, Goals), SM).
-strip_constraint_markers_expr(switch(Var, CanFail, Cases0, SM)) =
- switch(Var, CanFail, Cases, SM) :-
+strip_constraint_markers_expr(disj(Goals)) =
+ disj(list__map(strip_constraint_markers, Goals)).
+strip_constraint_markers_expr(switch(Var, CanFail, Cases0)) =
+ switch(Var, CanFail, Cases) :-
Cases = list__map(
(func(case(ConsId, Goal)) =
case(ConsId, strip_constraint_markers(Goal))
@@ -815,12 +815,12 @@
not(strip_constraint_markers(Goal)).
strip_constraint_markers_expr(some(Vars, Remove, Goal)) =
some(Vars, Remove, strip_constraint_markers(Goal)).
-strip_constraint_markers_expr(if_then_else(Vars, If, Then, Else, SM)) =
+strip_constraint_markers_expr(if_then_else(Vars, If, Then, Else)) =
if_then_else(Vars, strip_constraint_markers(If),
strip_constraint_markers(Then),
- strip_constraint_markers(Else), SM).
-strip_constraint_markers_expr(par_conj(Goals, SM)) =
- par_conj(list__map(strip_constraint_markers, Goals), SM).
+ strip_constraint_markers(Else)).
+strip_constraint_markers_expr(par_conj(Goals)) =
+ par_conj(list__map(strip_constraint_markers, Goals)).
strip_constraint_markers_expr(Goal) = Goal :-
Goal = foreign_proc(_, _, _, _, _, _, _).
strip_constraint_markers_expr(Goal) = Goal :-
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.39
diff -u -b -r1.39 continuation_info.m
--- compiler/continuation_info.m 20 Feb 2002 03:13:54 -0000 1.39
+++ compiler/continuation_info.m 20 Feb 2002 04:26:43 -0000
@@ -291,8 +291,8 @@
:- pred continuation_info__generate_return_live_lvalues(
assoc_list(prog_var, arg_loc)::in, instmap::in, list(prog_var)::in,
map(prog_var, set(lval))::in, assoc_list(lval, slot_contents)::in,
- proc_info::in, module_info::in, globals::in, list(liveinfo)::out)
- is det.
+ proc_info::in, module_info::in, globals::in, bool::in,
+ list(liveinfo)::out) is det.
% Generate the layout information we need for a resumption point,
% a label where forward execution can restart after backtracking.
@@ -318,7 +318,8 @@
:- implementation.
-:- import_module hlds_goal, code_util, type_util, inst_match, options.
+:- import_module hlds_goal, hlds_llds.
+:- import_module code_util, type_util, inst_match, options.
:- import_module string, require, term, varset.
%-----------------------------------------------------------------------------%
@@ -511,11 +512,11 @@
continuation_info__generate_return_live_lvalues(OutputArgLocs, ReturnInstMap,
Vars, VarLocs, Temps, ProcInfo, ModuleInfo, Globals,
- LiveLvalues) :-
+ OkToDeleteAny, LiveLvalues) :-
globals__want_return_var_layouts(Globals, WantReturnVarLayout),
proc_info_stack_slots(ProcInfo, StackSlots),
continuation_info__find_return_var_lvals(Vars, StackSlots,
- OutputArgLocs, VarLvals),
+ OkToDeleteAny, OutputArgLocs, VarLvals),
continuation_info__generate_var_live_lvalues(VarLvals, ReturnInstMap,
VarLocs, ProcInfo, ModuleInfo,
WantReturnVarLayout, VarLiveLvalues),
@@ -523,21 +524,26 @@
list__append(VarLiveLvalues, TempLiveLvalues, LiveLvalues).
:- pred continuation_info__find_return_var_lvals(list(prog_var)::in,
- stack_slots::in, assoc_list(prog_var, arg_loc)::in,
+ stack_slots::in, bool::in, assoc_list(prog_var, arg_loc)::in,
assoc_list(prog_var, lval)::out) is det.
-continuation_info__find_return_var_lvals([], _, _, []).
+continuation_info__find_return_var_lvals([], _, _, _, []).
continuation_info__find_return_var_lvals([Var | Vars], StackSlots,
- OutputArgLocs, [Var - Lval | VarLvals]) :-
+ OkToDeleteAny, OutputArgLocs, VarLvals) :-
+ continuation_info__find_return_var_lvals(Vars, StackSlots,
+ OkToDeleteAny, OutputArgLocs, TailVarLvals),
( assoc_list__search(OutputArgLocs, Var, ArgLoc) ->
% On return, output arguments are in their registers.
- code_util__arg_loc_to_register(ArgLoc, Lval)
- ;
+ code_util__arg_loc_to_register(ArgLoc, Lval),
+ VarLvals = [Var - Lval | TailVarLvals]
+ ; map__search(StackSlots, Var, Lval) ->
% On return, other live variables are in their stack slots.
- map__lookup(StackSlots, Var, Lval)
- ),
- continuation_info__find_return_var_lvals(Vars, StackSlots,
- OutputArgLocs, VarLvals).
+ VarLvals = [Var - Lval | TailVarLvals]
+ ; OkToDeleteAny = yes ->
+ VarLvals = TailVarLvals
+ ;
+ error("continuation_info__find_return_var_lvals: no slot")
+ ).
:- pred continuation_info__generate_temp_live_lvalues(
assoc_list(lval, slot_contents)::in, list(liveinfo)::out) is det.
Index: compiler/cse_detection.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/cse_detection.m,v
retrieving revision 1.70
diff -u -b -r1.70 cse_detection.m
--- compiler/cse_detection.m 7 Apr 2001 14:04:33 -0000 1.70
+++ compiler/cse_detection.m 16 Jul 2001 16:57:38 -0000
@@ -253,37 +253,37 @@
Redo, conj(Goals)) :-
detect_cse_in_conj(Goals0, InstMap, CseInfo0, CseInfo, Redo, Goals).
-detect_cse_in_goal_2(par_conj(Goals0, SM), _, InstMap, CseInfo0, CseInfo, Redo,
- par_conj(Goals, SM)) :-
+detect_cse_in_goal_2(par_conj(Goals0), _, InstMap, CseInfo0, CseInfo, Redo,
+ par_conj(Goals)) :-
detect_cse_in_par_conj(Goals0, InstMap, CseInfo0, CseInfo,
Redo, Goals).
-detect_cse_in_goal_2(disj(Goals0, SM), GoalInfo, InstMap, CseInfo0, CseInfo,
+detect_cse_in_goal_2(disj(Goals0), GoalInfo, InstMap, CseInfo0, CseInfo,
Redo, Goal) :-
( Goals0 = [] ->
CseInfo = CseInfo0,
Redo = no,
- Goal = disj([], SM)
+ Goal = disj([])
;
goal_info_get_nonlocals(GoalInfo, NonLocals),
set__to_sorted_list(NonLocals, NonLocalsList),
detect_cse_in_disj(NonLocalsList, Goals0, GoalInfo,
- SM, InstMap, CseInfo0, CseInfo, Redo, Goal)
+ InstMap, CseInfo0, CseInfo, Redo, Goal)
).
-detect_cse_in_goal_2(switch(Var, CanFail, Cases0, SM), GoalInfo, InstMap,
+detect_cse_in_goal_2(switch(Var, CanFail, Cases0), GoalInfo, InstMap,
CseInfo0, CseInfo, Redo, Goal) :-
goal_info_get_nonlocals(GoalInfo, NonLocals),
set__to_sorted_list(NonLocals, NonLocalsList),
detect_cse_in_cases(NonLocalsList, Var, CanFail, Cases0, GoalInfo,
- SM, InstMap, CseInfo0, CseInfo, Redo, Goal).
+ InstMap, CseInfo0, CseInfo, Redo, Goal).
-detect_cse_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, SM), GoalInfo,
+detect_cse_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), GoalInfo,
InstMap, CseInfo0, CseInfo, Redo, Goal) :-
goal_info_get_nonlocals(GoalInfo, NonLocals),
set__to_sorted_list(NonLocals, NonLocalsList),
detect_cse_in_ite(NonLocalsList, Vars, Cond0, Then0, Else0, GoalInfo,
- SM, InstMap, CseInfo0, CseInfo, Redo, Goal).
+ InstMap, CseInfo0, CseInfo, Redo, Goal).
detect_cse_in_goal_2(shorthand(_), _, _, _, _, _, _) :-
% these should have been expanded out by now
@@ -328,13 +328,13 @@
% branch matches that variable against the same functor.
:- pred detect_cse_in_disj(list(prog_var)::in, list(hlds_goal)::in,
- hlds_goal_info::in, store_map::in, instmap::in, cse_info::in,
+ hlds_goal_info::in, instmap::in, cse_info::in,
cse_info::out, bool::out, hlds_goal_expr::out) is det.
-detect_cse_in_disj([], Goals0, _, SM, InstMap, CseInfo0, CseInfo,
- Redo, disj(Goals, SM)) :-
+detect_cse_in_disj([], Goals0, _, InstMap, CseInfo0, CseInfo,
+ Redo, disj(Goals)) :-
detect_cse_in_disj_2(Goals0, InstMap, CseInfo0, CseInfo, Redo, Goals).
-detect_cse_in_disj([Var | Vars], Goals0, GoalInfo0, SM, InstMap,
+detect_cse_in_disj([Var | Vars], Goals0, GoalInfo0, InstMap,
CseInfo0, CseInfo, Redo, Goal) :-
(
instmap__lookup_var(InstMap, Var, VarInst0),
@@ -348,10 +348,10 @@
->
maybe_update_existential_data_structures(Unify,
FirstOldNew, LaterOldNew, CseInfo1, CseInfo),
- Goal = conj([Unify, disj(Goals, SM) - GoalInfo0]),
+ Goal = conj([Unify, disj(Goals) - GoalInfo0]),
Redo = yes
;
- detect_cse_in_disj(Vars, Goals0, GoalInfo0, SM, InstMap,
+ detect_cse_in_disj(Vars, Goals0, GoalInfo0, InstMap,
CseInfo0, CseInfo, Redo, Goal)
).
@@ -367,15 +367,15 @@
bool__or(Redo1, Redo2, Redo).
:- pred detect_cse_in_cases(list(prog_var)::in, prog_var::in, can_fail::in,
- list(case)::in, hlds_goal_info::in, store_map::in, instmap::in,
+ list(case)::in, hlds_goal_info::in, instmap::in,
cse_info::in, cse_info::out, bool::out, hlds_goal_expr::out) is det.
-detect_cse_in_cases([], SwitchVar, CanFail, Cases0, _GoalInfo, SM, InstMap,
+detect_cse_in_cases([], SwitchVar, CanFail, Cases0, _GoalInfo, InstMap,
CseInfo0, CseInfo, Redo,
- switch(SwitchVar, CanFail, Cases, SM)) :-
+ switch(SwitchVar, CanFail, Cases)) :-
detect_cse_in_cases_2(Cases0, InstMap, CseInfo0, CseInfo, Redo, Cases).
detect_cse_in_cases([Var | Vars], SwitchVar, CanFail, Cases0, GoalInfo,
- SM, InstMap, CseInfo0, CseInfo, Redo, Goal) :-
+ InstMap, CseInfo0, CseInfo, Redo, Goal) :-
(
Var \= SwitchVar,
instmap__lookup_var(InstMap, Var, VarInst0),
@@ -389,12 +389,12 @@
->
maybe_update_existential_data_structures(Unify,
FirstOldNew, LaterOldNew, CseInfo1, CseInfo),
- Goal = conj([Unify, switch(SwitchVar, CanFail, Cases, SM)
+ Goal = conj([Unify, switch(SwitchVar, CanFail, Cases)
- GoalInfo]),
Redo = yes
;
detect_cse_in_cases(Vars, SwitchVar, CanFail, Cases0, GoalInfo,
- SM, InstMap, CseInfo0, CseInfo, Redo, Goal)
+ InstMap, CseInfo0, CseInfo, Redo, Goal)
).
:- pred detect_cse_in_cases_2(list(case)::in, instmap::in, cse_info::in,
@@ -412,15 +412,15 @@
:- pred detect_cse_in_ite(list(prog_var)::in, list(prog_var)::in,
hlds_goal::in, hlds_goal::in, hlds_goal::in, hlds_goal_info::in,
- store_map::in, instmap::in, cse_info::in,
- cse_info::out, bool::out, hlds_goal_expr::out) is det.
+ instmap::in, cse_info::in, cse_info::out, bool::out,
+ hlds_goal_expr::out) is det.
-detect_cse_in_ite([], IfVars, Cond0, Then0, Else0, _, SM, InstMap, CseInfo0,
- CseInfo, Redo, if_then_else(IfVars, Cond, Then, Else, SM)) :-
+detect_cse_in_ite([], IfVars, Cond0, Then0, Else0, _, InstMap, CseInfo0,
+ CseInfo, Redo, if_then_else(IfVars, Cond, Then, Else)) :-
detect_cse_in_ite_2(Cond0, Then0, Else0,
InstMap, CseInfo0, CseInfo, Redo, Cond, Then, Else).
detect_cse_in_ite([Var | Vars], IfVars, Cond0, Then0, Else0, GoalInfo,
- SM, InstMap, CseInfo0, CseInfo, Redo, Goal) :-
+ InstMap, CseInfo0, CseInfo, Redo, Goal) :-
(
ModuleInfo = CseInfo0 ^ module_info,
instmap__lookup_var(InstMap, Var, VarInst0),
@@ -434,12 +434,12 @@
->
maybe_update_existential_data_structures(Unify,
FirstOldNew, LaterOldNew, CseInfo1, CseInfo),
- Goal = conj([Unify, if_then_else(IfVars, Cond0, Then, Else, SM)
+ Goal = conj([Unify, if_then_else(IfVars, Cond0, Then, Else)
- GoalInfo]),
Redo = yes
;
detect_cse_in_ite(Vars, IfVars, Cond0, Then0, Else0, GoalInfo,
- SM, InstMap, CseInfo0, CseInfo, Redo, Goal)
+ InstMap, CseInfo0, CseInfo, Redo, Goal)
).
:- pred detect_cse_in_ite_2(hlds_goal::in, hlds_goal::in, hlds_goal::in,
Index: compiler/dead_proc_elim.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.69
diff -u -b -r1.69 dead_proc_elim.m
--- compiler/dead_proc_elim.m 7 Mar 2002 08:29:46 -0000 1.69
+++ compiler/dead_proc_elim.m 8 Mar 2002 04:04:16 -0000
@@ -424,7 +424,7 @@
entity_queue, entity_queue, needed_map, needed_map).
:- mode dead_proc_elim__examine_expr(in, in, in, out, in, out) is det.
-dead_proc_elim__examine_expr(disj(Goals, _), CurrProc, Queue0, Queue,
+dead_proc_elim__examine_expr(disj(Goals), CurrProc, Queue0, Queue,
Needed0, Needed) :-
dead_proc_elim__examine_goals(Goals, CurrProc, Queue0, Queue,
Needed0, Needed).
@@ -432,7 +432,7 @@
Needed0, Needed) :-
dead_proc_elim__examine_goals(Goals, CurrProc, Queue0, Queue,
Needed0, Needed).
-dead_proc_elim__examine_expr(par_conj(Goals, _SM), CurrProc, Queue0, Queue,
+dead_proc_elim__examine_expr(par_conj(Goals), CurrProc, Queue0, Queue,
Needed0, Needed) :-
dead_proc_elim__examine_goals(Goals, CurrProc, Queue0, Queue,
Needed0, Needed).
@@ -444,11 +444,11 @@
Needed0, Needed) :-
dead_proc_elim__examine_goal(Goal, CurrProc, Queue0, Queue,
Needed0, Needed).
-dead_proc_elim__examine_expr(switch(_, _, Cases, _), CurrProc, Queue0, Queue,
+dead_proc_elim__examine_expr(switch(_, _, Cases), CurrProc, Queue0, Queue,
Needed0, Needed) :-
dead_proc_elim__examine_cases(Cases, CurrProc, Queue0, Queue,
Needed0, Needed).
-dead_proc_elim__examine_expr(if_then_else(_, Cond, Then, Else, _),
+dead_proc_elim__examine_expr(if_then_else(_, Cond, Then, Else),
CurrProc, Queue0, Queue, Needed0, Needed) :-
dead_proc_elim__examine_goal(Cond, CurrProc, Queue0, Queue1,
Needed0, Needed1),
@@ -857,13 +857,13 @@
pre_modecheck_examine_goal(conj(Goals) - _) -->
list__foldl(pre_modecheck_examine_goal, Goals).
-pre_modecheck_examine_goal(par_conj(Goals, _) - _) -->
+pre_modecheck_examine_goal(par_conj(Goals) - _) -->
list__foldl(pre_modecheck_examine_goal, Goals).
-pre_modecheck_examine_goal(disj(Goals, _) - _) -->
+pre_modecheck_examine_goal(disj(Goals) - _) -->
list__foldl(pre_modecheck_examine_goal, Goals).
-pre_modecheck_examine_goal(if_then_else(_, If, Then, Else, _) - _) -->
+pre_modecheck_examine_goal(if_then_else(_, If, Then, Else) - _) -->
list__foldl(pre_modecheck_examine_goal, [If, Then, Else]).
-pre_modecheck_examine_goal(switch(_, _, Cases, _) - _) -->
+pre_modecheck_examine_goal(switch(_, _, Cases) - _) -->
{ ExamineCase = lambda([Case::in, Info0::in, Info::out] is det, (
Case = case(_, Goal),
pre_modecheck_examine_goal(Goal, Info0, Info)
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.6
diff -u -b -r1.6 deep_profiling.m
--- compiler/deep_profiling.m 26 Feb 2002 02:52:25 -0000 1.6
+++ compiler/deep_profiling.m 1 Mar 2002 17:11:41 -0000
@@ -233,30 +233,30 @@
GoalExpr = conj(Goals),
Goal = GoalExpr - GoalInfo0
;
- GoalExpr0 = disj(Goals0, SM),
+ GoalExpr0 = disj(Goals0),
apply_tail_recursion_to_disj(Goals0, ApplyInfo,
Goals, FoundTailCall0, FoundTailCall),
- GoalExpr = disj(Goals, SM),
+ GoalExpr = disj(Goals),
Goal = GoalExpr - GoalInfo0,
Continue = no
;
- GoalExpr0 = switch(Var, CanFail, Cases0, SM),
+ GoalExpr0 = switch(Var, CanFail, Cases0),
apply_tail_recursion_to_cases(Cases0, ApplyInfo,
Cases, FoundTailCall0, FoundTailCall),
- GoalExpr = switch(Var, CanFail, Cases, SM),
+ GoalExpr = switch(Var, CanFail, Cases),
Goal = GoalExpr - GoalInfo0,
Continue = no
;
- GoalExpr0 = if_then_else(Vars, Cond, Then0, Else0, SM),
+ GoalExpr0 = if_then_else(Vars, Cond, Then0, Else0),
apply_tail_recursion_to_goal(Then0, ApplyInfo,
Then, FoundTailCall0, FoundTailCall1, _),
apply_tail_recursion_to_goal(Else0, ApplyInfo,
Else, FoundTailCall1, FoundTailCall, _),
- GoalExpr = if_then_else(Vars, Cond, Then, Else, SM),
+ GoalExpr = if_then_else(Vars, Cond, Then, Else),
Goal = GoalExpr - GoalInfo0,
Continue = no
;
- GoalExpr0 = par_conj(_, _),
+ GoalExpr0 = par_conj(_),
Goal = Goal0,
FoundTailCall = FoundTailCall0,
Continue = no
@@ -379,15 +379,15 @@
figure_out_rec_call_numbers_in_goal_list(Goals, N0, N,
TailCallSites0, TailCallSites)
;
- GoalExpr = disj(Goals, _),
+ GoalExpr = disj(Goals),
figure_out_rec_call_numbers_in_goal_list(Goals, N0, N,
TailCallSites0, TailCallSites)
;
- GoalExpr = switch(_, _, Cases, _),
+ GoalExpr = switch(_, _, Cases),
figure_out_rec_call_numbers_in_case_list(Cases, N0, N,
TailCallSites0, TailCallSites)
;
- GoalExpr = if_then_else(_, Cond, Then, Else, _),
+ GoalExpr = if_then_else(_, Cond, Then, Else),
figure_out_rec_call_numbers(Cond, N0, N1,
TailCallSites0, TailCallSites1),
figure_out_rec_call_numbers(Then, N1, N2,
@@ -395,7 +395,7 @@
figure_out_rec_call_numbers(Else, N2, N,
TailCallSites2, TailCallSites)
;
- GoalExpr = par_conj(Goals, _),
+ GoalExpr = par_conj(Goals),
figure_out_rec_call_numbers_in_goal_list(Goals, N0, N,
TailCallSites0, TailCallSites)
;
@@ -722,7 +722,7 @@
ExitPortCode
]) - ExitConjGoalInfo,
FailPortCode
- ], map__init) - ExitConjGoalInfo
+ ]) - ExitConjGoalInfo
]) - GoalInfo,
proc_info_set_varset(Proc0, Vars, Proc1),
proc_info_set_vartypes(Proc1, VarTypes, Proc2),
@@ -852,10 +852,10 @@
disj([
ExitPortCode,
RedoPortCode
- ], map__init) - ExitRedoGoalInfo
+ ]) - ExitRedoGoalInfo
]) - CallExitRedoGoalInfo,
FailPortCode
- ], map__init) - CallExitRedoGoalInfo
+ ]) - CallExitRedoGoalInfo
]) - GoalInfo,
proc_info_set_varset(Proc0, Vars, Proc1),
proc_info_set_vartypes(Proc1, VarTypes, Proc2),
@@ -931,18 +931,18 @@
transform_conj(0, Path, Goals0, Goals, AddedImpurity),
{ add_impurity_if_needed(AddedImpurity, Info0, Info) }.
-transform_goal(Path, par_conj(Goals0, SM) - Info0,
- par_conj(Goals, SM) - Info, AddedImpurity) -->
+transform_goal(Path, par_conj(Goals0) - Info0,
+ par_conj(Goals) - Info, AddedImpurity) -->
transform_conj(0, Path, Goals0, Goals, AddedImpurity),
{ add_impurity_if_needed(AddedImpurity, Info0, Info) }.
-transform_goal(Path, switch(Var, CF, Cases0, SM) - Info0,
- switch(Var, CF, Cases, SM) - Info, AddedImpurity) -->
+transform_goal(Path, switch(Var, CF, Cases0) - Info0,
+ switch(Var, CF, Cases) - Info, AddedImpurity) -->
transform_switch(list__length(Cases0), 0, Path, Cases0, Cases,
AddedImpurity),
{ add_impurity_if_needed(AddedImpurity, Info0, Info) }.
-transform_goal(Path, disj(Goals0, SM) - Info0, disj(Goals, SM) - Info,
+transform_goal(Path, disj(Goals0) - Info0, disj(Goals) - Info,
AddedImpurity) -->
transform_disj(0, Path, Goals0, Goals, AddedImpurity),
{ add_impurity_if_needed(AddedImpurity, Info0, Info) }.
@@ -972,8 +972,8 @@
transform_goal([exist(MaybeCut) | Path], Goal0, Goal, AddedImpurity),
{ add_impurity_if_needed(AddedImpurity, Info1, Info) }.
-transform_goal(Path, if_then_else(IVars, Cond0, Then0, Else0, SM) - Info0,
- if_then_else(IVars, Cond, Then, Else, SM) - Info,
+transform_goal(Path, if_then_else(IVars, Cond0, Then0, Else0) - Info0,
+ if_then_else(IVars, Cond, Then, Else) - Info,
AddedImpurity) -->
transform_goal([ite_cond | Path], Cond0, Cond, AddedImpurityC),
transform_goal([ite_then | Path], Then0, Then, AddedImpurityT),
@@ -1215,7 +1215,7 @@
ExtraVars, failure),
FailGoalInfo = fail_goal_info,
- FailGoal = disj([], init) - FailGoalInfo,
+ FailGoal = disj([]) - FailGoalInfo,
list__append(FailGoals, [FailGoal], FailGoalsAndFail),
@@ -1231,7 +1231,7 @@
conj(
FailGoalsAndFail
) - ReturnFailsGoalInfo
- ], init) - WrappedGoalGoalInfo]
+ ]) - WrappedGoalGoalInfo]
], Goals),
Goal = conj(Goals) - GoalInfo
)
@@ -1309,7 +1309,7 @@
NoBindExtGoalInfo),
FailGoalInfo = fail_goal_info,
- FailGoal = disj([], init) - FailGoalInfo,
+ FailGoal = disj([]) - FailGoalInfo,
RestoreFailGoalInfo = impure_unreachable_init_goal_info(ExtraNonLocals,
failure),
@@ -1338,7 +1338,7 @@
RestoreStuff,
FailGoal
]) - RestoreFailGoalInfo
- ], init) - ExtGoalInfo
+ ]) - ExtGoalInfo
]) - GoalInfo
;
CodeModel = model_non,
@@ -1353,13 +1353,13 @@
ReZeroStuff,
FailGoal
]) - RezeroFailGoalInfo
- ], init) - NoBindExtGoalInfo
+ ]) - NoBindExtGoalInfo
]) - ExtGoalInfo,
conj([
RestoreStuff,
FailGoal
]) - RestoreFailGoalInfo
- ], init) - ExtGoalInfo
+ ]) - ExtGoalInfo
]) - GoalInfo
).
Index: compiler/deforest.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deforest.m,v
retrieving revision 1.24
diff -u -b -r1.24 deforest.m
--- compiler/deforest.m 11 Aug 2001 14:09:37 -0000 1.24
+++ compiler/deforest.m 15 Aug 2001 02:08:32 -0000
@@ -263,13 +263,13 @@
pd_info_set_instmap(InstMap0).
% XXX cannot deforest across parallel_conjunctions!
-deforest__goal(par_conj(Goals, SM) - Info, par_conj(Goals, SM) - Info) --> [].
+deforest__goal(par_conj(Goals) - Info, par_conj(Goals) - Info) --> [].
-deforest__goal(disj(Goals0, SM) - Info, disj(Goals, SM) - Info) -->
+deforest__goal(disj(Goals0) - Info, disj(Goals) - Info) -->
deforest__disj(Goals0, Goals).
-deforest__goal(if_then_else(Vars, Cond0, Then0, Else0, SM) - Info,
- if_then_else(Vars, Cond, Then, Else, SM) - Info) -->
+deforest__goal(if_then_else(Vars, Cond0, Then0, Else0) - Info,
+ if_then_else(Vars, Cond, Then, Else) - Info) -->
pd_info_get_instmap(InstMap0),
deforest__goal(Cond0, Cond),
pd_info_update_goal(Cond),
@@ -278,8 +278,8 @@
deforest__goal(Else0, Else),
pd_info_set_instmap(InstMap0).
-deforest__goal(switch(Var, CanFail, Cases0, SM) - Info,
- switch(Var, CanFail, Cases, SM) - Info) -->
+deforest__goal(switch(Var, CanFail, Cases0) - Info,
+ switch(Var, CanFail, Cases) - Info) -->
deforest__cases(Var, Cases0, Cases).
deforest__goal(Goal, Goal) -->
@@ -1612,12 +1612,12 @@
BetweenGoals, LaterGoal, Goal) -->
pd_info_get_instmap(InstMap0),
{ EarlierGoal = EarlierGoalExpr - _ },
- ( { EarlierGoalExpr = switch(Var1, CanFail1, Cases1, SM) } ->
+ ( { EarlierGoalExpr = switch(Var1, CanFail1, Cases1) } ->
{ set__insert(NonLocals, Var1, CaseNonLocals) },
deforest__append_goal_to_cases(Var1, Cases1, BetweenGoals,
LaterGoal, CaseNonLocals, 1, DeforestInfo, Cases),
- { GoalExpr = switch(Var1, CanFail1, Cases, SM) }
- ; { EarlierGoalExpr = if_then_else(Vars, Cond, Then0, Else0, SM) } ->
+ { GoalExpr = switch(Var1, CanFail1, Cases) }
+ ; { EarlierGoalExpr = if_then_else(Vars, Cond, Then0, Else0) } ->
pd_info_update_goal(Cond),
{ Cond = _ - CondInfo },
{ goal_info_get_nonlocals(CondInfo, CondNonLocals) },
@@ -1627,11 +1627,11 @@
pd_info_set_instmap(InstMap0),
deforest__append_goal(Else0, BetweenGoals,
LaterGoal, NonLocals, 2, DeforestInfo, Else),
- { GoalExpr = if_then_else(Vars, Cond, Then, Else, SM) }
- ; { EarlierGoalExpr = disj(Disjuncts0, SM) } ->
+ { GoalExpr = if_then_else(Vars, Cond, Then, Else) }
+ ; { EarlierGoalExpr = disj(Disjuncts0) } ->
deforest__append_goal_to_disjuncts(Disjuncts0, BetweenGoals,
LaterGoal, NonLocals, 1, DeforestInfo, Disjuncts),
- { GoalExpr = disj(Disjuncts, SM) }
+ { GoalExpr = disj(Disjuncts) }
;
{ error("deforest__push_goal_into_goal") }
),
Index: compiler/delay_construct.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/delay_construct.m,v
retrieving revision 1.1
diff -u -b -r1.1 delay_construct.m
--- compiler/delay_construct.m 24 Apr 2001 03:39:36 -0000 1.1
+++ compiler/delay_construct.m 16 Jul 2001 13:44:30 -0000
@@ -114,23 +114,23 @@
delay_construct_in_goals(Goals1, InstMap0, DelayInfo, Goals),
Goal = conj(Goals) - GoalInfo0
;
- GoalExpr0 = par_conj(Goals0, SM),
+ GoalExpr0 = par_conj(Goals0),
delay_construct_in_goals(Goals0, InstMap0, DelayInfo, Goals),
- Goal = par_conj(Goals, SM) - GoalInfo0
+ Goal = par_conj(Goals) - GoalInfo0
;
- GoalExpr0 = disj(Goals0, SM),
+ GoalExpr0 = disj(Goals0),
delay_construct_in_goals(Goals0, InstMap0, DelayInfo, Goals),
- Goal = disj(Goals, SM) - GoalInfo0
+ Goal = disj(Goals) - GoalInfo0
;
GoalExpr0 = not(NegGoal0),
delay_construct_in_goal(NegGoal0, InstMap0, DelayInfo, NegGoal),
Goal = not(NegGoal) - GoalInfo0
;
- GoalExpr0 = switch(Var, CanFail, Cases0, SM),
+ GoalExpr0 = switch(Var, CanFail, Cases0),
delay_construct_in_cases(Cases0, InstMap0, DelayInfo, Cases),
- Goal = switch(Var, CanFail, Cases, SM) - GoalInfo0
+ Goal = switch(Var, CanFail, Cases) - GoalInfo0
;
- GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0, SM),
+ GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
Cond0 = _ - CondInfo0,
goal_info_get_instmap_delta(CondInfo0, CondInstMapDelta),
instmap__apply_instmap_delta(InstMap0, CondInstMapDelta,
@@ -138,7 +138,7 @@
delay_construct_in_goal(Cond0, InstMap0, DelayInfo, Cond),
delay_construct_in_goal(Then0, InstMapThen, DelayInfo, Then),
delay_construct_in_goal(Else0, InstMap0, DelayInfo, Else),
- Goal = if_then_else(Vars, Cond, Then, Else, SM) - GoalInfo0
+ Goal = if_then_else(Vars, Cond, Then, Else) - GoalInfo0
;
GoalExpr0 = some(Var, CanRemove, SubGoal0),
delay_construct_in_goal(SubGoal0, InstMap0, DelayInfo, SubGoal),
Index: compiler/dense_switch.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dense_switch.m,v
retrieving revision 1.40
diff -u -b -r1.40 dense_switch.m
--- compiler/dense_switch.m 20 Jan 2001 15:42:42 -0000 1.40
+++ compiler/dense_switch.m 18 Jul 2001 12:12:41 -0000
@@ -16,7 +16,7 @@
:- interface.
-:- import_module prog_data, hlds_data, hlds_goal, code_model.
+:- import_module prog_data, hlds_llds, hlds_data, code_model.
:- import_module switch_util, type_util.
:- import_module llds, code_info.
Index: compiler/dependency_graph.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dependency_graph.m,v
retrieving revision 1.55
diff -u -b -r1.55 dependency_graph.m
--- compiler/dependency_graph.m 20 Feb 2002 03:13:55 -0000 1.55
+++ compiler/dependency_graph.m 20 Feb 2002 04:26:44 -0000
@@ -282,19 +282,19 @@
DepGraph0, DepGraph) :-
dependency_graph__add_arcs_in_list(Goals, Caller, DepGraph0, DepGraph).
-dependency_graph__add_arcs_in_goal_2(par_conj(Goals, _SM), Caller,
+dependency_graph__add_arcs_in_goal_2(par_conj(Goals), Caller,
DepGraph0, DepGraph) :-
dependency_graph__add_arcs_in_list(Goals, Caller, DepGraph0, DepGraph).
-dependency_graph__add_arcs_in_goal_2(disj(Goals, _), Caller,
+dependency_graph__add_arcs_in_goal_2(disj(Goals), Caller,
DepGraph0, DepGraph) :-
dependency_graph__add_arcs_in_list(Goals, Caller, DepGraph0, DepGraph).
-dependency_graph__add_arcs_in_goal_2(switch(_Var, _Det, Cases, _),
+dependency_graph__add_arcs_in_goal_2(switch(_Var, _Det, Cases),
Caller, DepGraph0, DepGraph) :-
dependency_graph__add_arcs_in_cases(Cases, Caller, DepGraph0, DepGraph).
-dependency_graph__add_arcs_in_goal_2(if_then_else(_Vars, Cond, Then, Else, _),
+dependency_graph__add_arcs_in_goal_2(if_then_else(_Vars, Cond, Then, Else),
Caller, DepGraph0, DepGraph) :-
dependency_graph__add_arcs_in_goal(Cond, Caller, DepGraph0, DepGraph1),
dependency_graph__add_arcs_in_goal(Then, Caller, DepGraph1, DepGraph2),
@@ -716,18 +716,18 @@
process_aditi_goal(IsNeg, conj(Goals) - _, Map0, Map) -->
list__foldl2(process_aditi_goal(IsNeg), Goals, Map0, Map).
-process_aditi_goal(_IsNeg, par_conj(_, _) - _, _, _) -->
+process_aditi_goal(_IsNeg, par_conj(_) - _, _, _) -->
{ error("process_aditi_goal - par_conj") }.
-process_aditi_goal(IsNeg, disj(Goals, _) - _, Map0, Map) -->
+process_aditi_goal(IsNeg, disj(Goals) - _, Map0, Map) -->
list__foldl2(process_aditi_goal(IsNeg), Goals, Map0, Map).
-process_aditi_goal(IsNeg, switch(_, _, Cases, _) - _, Map0, Map) -->
+process_aditi_goal(IsNeg, switch(_, _, Cases) - _, Map0, Map) -->
{ NegCallsInCases =
lambda([Case::in, M0::in, M::out, AInfo0::in, AInfo::out] is det, (
Case = case(_ConsId, Goal),
process_aditi_goal(IsNeg, Goal, M0, M, AInfo0, AInfo)
)) },
list__foldl2(NegCallsInCases, Cases, Map0, Map).
-process_aditi_goal(IsNeg, if_then_else(_, Cond, Then, Else, _) - _,
+process_aditi_goal(IsNeg, if_then_else(_, Cond, Then, Else) - _,
Map0, Map) -->
process_aditi_goal(yes, Cond, Map0, Map1),
process_aditi_goal(IsNeg, Then, Map1, Map2),
Index: compiler/det_analysis.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/det_analysis.m,v
retrieving revision 1.152
diff -u -b -r1.152 det_analysis.m
--- compiler/det_analysis.m 26 Feb 2002 02:52:25 -0000 1.152
+++ compiler/det_analysis.m 1 Mar 2002 17:11:42 -0000
@@ -384,7 +384,7 @@
% code generator. (Both the MLDS and LLDS
% back-ends rely on this.)
%
- Goal1 = if_then_else(_, _ - CondInfo, _, _, _),
+ Goal1 = if_then_else(_, _ - CondInfo, _, _),
goal_info_get_determinism(CondInfo, CondDetism),
determinism_components(CondDetism, _, at_most_many),
Solns \= at_most_many
@@ -424,7 +424,7 @@
% choice point at all, rather than wrapping a
% some [] around a nondet disj, which would
% create a choice point and then prune it.
- Goal1 \= disj(_, _),
+ Goal1 \= disj(_),
% do we already have a commit?
Goal1 \= some(_, _, _)
@@ -457,8 +457,8 @@
det_infer_conj(Goals0, InstMap0, SolnContext, DetInfo,
Goals, Detism, Msgs).
-det_infer_goal_2(par_conj(Goals0, SM), GoalInfo, InstMap0, SolnContext,
- DetInfo, _, _, par_conj(Goals, SM), Detism, Msgs) :-
+det_infer_goal_2(par_conj(Goals0), GoalInfo, InstMap0, SolnContext,
+ DetInfo, _, _, par_conj(Goals), Detism, Msgs) :-
det_infer_par_conj(Goals0, InstMap0, SolnContext, DetInfo,
Goals, Detism, Msgs0),
(
@@ -474,8 +474,8 @@
Msgs = [Msg|Msgs0]
).
-det_infer_goal_2(disj(Goals0, SM), _, InstMap0, SolnContext, DetInfo, _, _,
- disj(Goals, SM), Detism, Msgs) :-
+det_infer_goal_2(disj(Goals0), _, InstMap0, SolnContext, DetInfo, _, _,
+ disj(Goals), Detism, Msgs) :-
det_infer_disj(Goals0, InstMap0, SolnContext, DetInfo,
can_fail, at_most_zero, Goals, Detism, Msgs).
@@ -484,9 +484,9 @@
% then it is semideterministic or worse - this is determined
% in switch_detection.m and handled via the SwitchCanFail field.
-det_infer_goal_2(switch(Var, SwitchCanFail, Cases0, SM), GoalInfo,
+det_infer_goal_2(switch(Var, SwitchCanFail, Cases0), GoalInfo,
InstMap0, SolnContext, DetInfo, _, _,
- switch(Var, SwitchCanFail, Cases, SM), Detism, Msgs) :-
+ switch(Var, SwitchCanFail, Cases), Detism, Msgs) :-
det_infer_switch(Cases0, InstMap0, SolnContext, DetInfo,
cannot_fail, at_most_zero, Cases, CasesDetism, Msgs0),
determinism_components(CasesDetism, CasesCanFail, CasesSolns),
@@ -514,8 +514,8 @@
% This is the point at which annotations start changing
% when we iterate to fixpoint for global determinism inference.
-det_infer_goal_2(call(PredId, ModeId0, A, B, C, N), GoalInfo, _, SolnContext,
- DetInfo, _, _,
+det_infer_goal_2(call(PredId, ModeId0, A, B, C, N), GoalInfo, _,
+ SolnContext, DetInfo, _, _,
call(PredId, ModeId, A, B, C, N), Detism, Msgs) :-
det_lookup_detism(DetInfo, PredId, ModeId0, Detism0),
%
@@ -611,9 +611,9 @@
UnifyNumSolns, Msgs),
determinism_components(UnifyDet, UnifyCanFail, UnifyNumSolns).
-det_infer_goal_2(if_then_else(Vars, Cond0, Then0, Else0, SM), _GoalInfo0,
+det_infer_goal_2(if_then_else(Vars, Cond0, Then0, Else0), _GoalInfo0,
InstMap0, SolnContext, DetInfo, _NonLocalVars, _DeltaInstMap,
- if_then_else(Vars, Cond, Then, Else, SM), Detism, Msgs) :-
+ if_then_else(Vars, Cond, Then, Else), Detism, Msgs) :-
% We process the goal right-to-left, doing the `then' before
% the condition of the if-then-else, so that we can propagate
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list