[m-dev.] for review: polymorphic ground insts
David Overton
dmo at ender.cs.mu.oz.au
Mon Feb 21 17:22:12 AEDT 2000
On Thu, 10 Feb, 2000 at 06:35:09PM EST, Fergus Henderson wrote:
> On 09-Feb-2000, David Overton <dmo at ender.cs.mu.oz.au> wrote:
> hlds_pred.m:
> > :- type proc_info
> > ---> procedure(
> > - maybe(determinism),
> > + declared_determinism :: maybe(determinism),
> > % _declared_ determinism
> > % or `no' if there was no detism decl
> [... 20 lines later ...]
> > - stack_slots, % stack allocations
> > - determinism, % _inferred_ determinism
> > - bool, % no if we must not process this
> > + stack_slots :: stack_slots, % stack allocations
> > + inferred_determinism :: determinism,
> > + % _inferred_ determinism
> > + can_process :: bool,
> > + % no if we must not process this
>
> It would be a good idea to move the declaration
> of the `declared_determinism' field next to the declaration
> of the `inferred_determinism' field.
Done.
> You might want to consider
> rearranging the order of the other fields too.
> Some of these fields occur in "historical order", because
> previously it was very tedious to reorder fields.
> Now that we're using records, we should make sure to declare
> the fields in the order that makes things easiest to read.
>
> > +proc_info_get_rl_exprn_id(ProcInfo, ProcInfo^rl_exprn_id).
> > +
> > % :- type proc_info
> > % ---> procedure(
> > % A maybe(determinism),
>
> You should probably delete that comment now.
> (It just duplicates the type declaration,
> annotating each field with a letter for use
> in the definitions of access predicates.)
Done.
>
> > +++ compiler/inst.m 2000/02/04 00:04:23
> > @@ -1,5 +1,5 @@
> > %-----------------------------------------------------------------------------%
> > -% Copyright (C) 1997, 1999 The University of Melbourne.
> > +% Copyright (C) 1997, 2000 The University of Melbourne.
>
> That should be
>
> % Copyright (C) 1997, 1999-2000 The University of Melbourne.
Done.
>
> > @@ -34,7 +34,7 @@
> > ; free(type)
> > ; bound(uniqueness, list(bound_inst))
> > % The list(bound_inst) must be sorted
> > - ; ground(uniqueness, maybe(pred_inst_info))
> > + ; ground(uniqueness, ground_inst_info)
> > % The pred_inst_info is used for
> > % higher-order pred modes
>
> That comment is unclear now. You should update it to reflect
> your change.
Done.
>
> > +:- type ground_inst_info
> > + ---> higher_order(pred_inst_info)
> > + ; constrained_inst_var(inst_var)
> > + ; none.
>
> Some comments here would also be helpful.
Done.
>
> > +++ compiler/inst_match.m 2000/02/08 04:57:39
> > @@ -1,5 +1,5 @@
> > %-----------------------------------------------------------------------------%
> > -% Copyright (C) 1995-1998 The University of Melbourne.
> > +% Copyright (C) 1995-2000 The University of Melbourne.
>
> That should probably be "1995-1998, 2000".
Done.
>
> > +inst_matches_initial_3(bound(UniqA, ListA),
> > + ground(UniqB, constrained_inst_var(V)), _, _,
> > + ModuleInfo0, ModuleInfo, Sub0, Sub) :-
> > + unique_matches_initial(UniqA, UniqB),
> > + bound_inst_list_is_ground(ListA, ModuleInfo0),
> > + bound_inst_list_matches_uniq(ListA, UniqB, ModuleInfo0),
> > + abstractly_unify_inst(live, bound(UniqA, ListA), ground(UniqB, none),
> > + fake_unify, ModuleInfo0, Inst, _Det, ModuleInfo1),
> > + update_inst_var_sub(V, Inst, ModuleInfo1, ModuleInfo, Sub0, Sub).
>
> Hmm... it might be helpful to have a comment explaining
> what the call to update_inst_var_sub does... either that,
> or the definition of update_inst_var_sub should have some
> detailed comments.
Done.
>
> > +inst_matches_initial_3(ground(UniqA, GII), bound(UniqB, List), MaybeType,
> > + Expansions, ModuleInfo0, ModuleInfo, Sub0, Sub) :-
>
> I found it easiest if each variable from the insts was suffixed with
> `A' (for the LHS) or `B' (for the RHS). So I suggest s/GII/GII_A/
> and s/List/ListA/g. Similarly in a few other spots, e.g. you use
> `V' in a number of places where I think `InstVarA' or `InstVarB'
> would be clearer.
Done.
>
> > +:- pred ground_matches_initial_bound_inst_list(uniqueness, list(bound_inst),
> > + maybe(type), expansions, module_info, module_info,
> > + inst_var_sub, inst_var_sub).
> > +:- mode ground_matches_initial_bound_inst_list(in, in, in, in, in, out,
> > + in, out) is semidet.
>
> I think you should add a comment here saying that this predicate assumes that
> the check of `bound_inst_list_is_complete_for_type' is done by the caller.
> Otherwise, the definition of `matches_initial' would lead the reader to
> expect that this predicate should perform that check.
Done.
>
> > +:- pred bound_inst_list_is_complete_for_type(set(inst_name), module_info,
> > + list(bound_inst), type).
> > +:- mode bound_inst_list_is_complete_for_type(in, in, in, in) is semidet.
>
> It would be helpful to have a comment here explaining what it means for a
> inst or a bound_inst_list to be "complete" for a type.
Done.
>
> > +inst_is_complete_for_type(Expansions, ModuleInfo, Inst, Type) :-
> > + ( Inst = defined_inst(InstName) ->
> > + ( set__member(InstName, Expansions) ->
> > + true
> > + ;
> > + inst_lookup(ModuleInfo, InstName, ExpandedInst),
> > + inst_is_complete_for_type(Expansions `insert` InstName,
> > + ModuleInfo, ExpandedInst, Type)
>
> I think it would be best to keep the module qualifier, i.e.
> make that "`set__insert`" rather than just "`insert`".
Done.
>
> > + )
> > + ; Inst = bound(_, List) ->
> > + bound_inst_list_is_complete_for_type(Expansions, ModuleInfo,
> > + List, Type)
> > + ;
> > + true
> > + ).
>
> I think that logically speaking, if Inst = not_reached, then
> this predicate should fail. After all, not_reached is basically
> equivalent to a special representation of `bound(_, [])', and
> this predicate fails for `bound(_, [])'.
Done.
>
> (I think this doesn't affect the behaviour of your changes, since you
> check for not_reached elsewhere anyway. But still...)
>
> > +:- pred equivalent_cons_ids(cons_id, cons_id).
> > +:- mode equivalent_cons_ids(in, in) is semidet.
>
> It might be nice to have a comment here explaining what kind of equivalence
> this computes.
>
Done.
> > +%-----------------------------------------------------------------------------%
> > +
> > +:- pred update_inst_var_sub(inst_var, inst, module_info, module_info,
> > + inst_var_sub, inst_var_sub).
> > +:- mode update_inst_var_sub(in, in, in, out, in, out) is semidet.
> > +
> > +update_inst_var_sub(V, InstA, ModuleInfo0, ModuleInfo, Sub0, Sub) :-
> > + ( map__search(Sub0, V, InstB) ->
> > + inst_merge(InstA, InstB, ModuleInfo0, Inst, ModuleInfo),
> > + map__det_update(Sub0, V, Inst, Sub)
> > + ;
> > + ModuleInfo = ModuleInfo0,
> > + map__det_insert(Sub0, V, InstA, Sub)
> > + ).
>
> It would be a good idea to document this predicate better.
> For example, what is it's purpose? And why does it use `inst_merge'?
Done.
>
> > +%-----------------------------------------------------------------------------%
> > +
> > +:- pred ground_inst_info_matches_initial(ground_inst_info, ground_inst_info,
> > + uniqueness, uniqueness, maybe(type), expansions,
> > + module_info, module_info, inst_var_sub, inst_var_sub).
> > +:- mode ground_inst_info_matches_initial(in, in, in, in, in, in, in, out, in,
> > + out) is semidet.
> > +
> > +ground_inst_info_matches_initial(_, none, _, _, _, _, M, M) --> [].
> > +ground_inst_info_matches_initial(higher_order(PredInstA),
> > + higher_order(PredInstB), _, _, Type, Expansions,
> > + ModuleInfo0, ModuleInfo) -->
> > + pred_inst_matches_initial(PredInstA, PredInstB, Type, Expansions,
> > + ModuleInfo0, ModuleInfo).
>
> Why do you ignore the uniquenesses here?
This predicate is not supposed to check uniqueness.
> If this predicate is not supposed to check the uniquenesses,
> that should be documented.
Ok.
>
> > +ground_inst_info_matches_initial(GroundInstInfoA, constrained_inst_var(V),
> > + UniqA, UniqB, _, _, ModuleInfo0, ModuleInfo) -->
> > + { GroundInstInfoA = constrained_inst_var(_) ->
> > + Inst = ground(UniqA, GroundInstInfoA),
> > + ModuleInfo1 = ModuleInfo0
> > + ;
> > + abstractly_unify_inst(live, ground(UniqA, GroundInstInfoA),
> > + ground(UniqB, none), fake_unify, ModuleInfo0, Inst,
> > + _Det, ModuleInfo1)
> > + },
>
> Why is the if-then-else there needed?
> Hmm, you ignore the uniqueness in the "then" case, but you check
> the uniqueness in the "else" case... why?
> Is there any other difference between the two cases?
Ok, this bit was wrong. The uniqueness of Inst should be UniqB. We
have already checked that UniqA matches_initial UniqB.
>
> > +:- pred maybe_get_arg_types(module_info, maybe(type), cons_id,
> > + list(maybe(type))).
> > +:- mode maybe_get_arg_types(in, in, in, out) is det.
> > +
> > +maybe_get_arg_types(ModuleInfo, MaybeType, ConsId0, MaybeTypes) :-
> > + ( ConsId0 = cons(SymName, Arity) ->
> > + ( SymName = qualified(_, Name) ->
> > + % type_util__get_cons_id_arg_types expects an
> > + % unqualified cons_id.
>
> It would be a good idea to add that comment to type_util.m too.
Done.
> > @@ -551,9 +804,9 @@
> > % insts in ListB, or if ListB does not contain a complete list
> > % of all the constructors for the type in question.
> > %%% error("not implemented: `ground' matches_final `bound(...)'").
>
> Did you consider fixing this bug in the same way as you fixed
> the similar one in inst_matches_initial?
The only reason I didn't do it is because it didn't seem quite as
important as for inst_matches_initial. I've have now tried to fix
the similar bugs in inst_matches_final and inst_matches_binding.
Unfortunately, without alias tracking, this fix causes lots of code to
break. E.g., the following code, which occurs in several places in
the compiler:
:- pred p is semidet.
:- pred q(list(int)::out) is det.
p :- q([_]).
q([1,2,3,4]).
creates a unification proc for list(T) where the second argument has
mode `ground -> bound([ground | bound([])))'. When mode checking this
proc, because there is no alias tracking, the final inst inferred is
`bound([ground | ground])' which does not match_final with the expected
final inst.
So at the moment I have disabled the test in inst_matches_final and
inst_matches_binding. Do you have a better (short-term) solution
until alias tracking is ready for the main branch?
> > +ground_inst_info_matches_final(constrained_inst_var(I),
> > + constrained_inst_var(I), _, _).
>
> Hmm...
What is the problem with this?
>
> > +ground_inst_info_matches_binding(constrained_inst_var(_),
> > + constrained_inst_var(_), _). % AAA
>
> Hmm again... what's the "AAA" comment for?
The "AAA" comment was to remind me to go back and look at this again,
which I forgot to do. I think this should actually be:
ground_inst_info_matches_binding(constrained_inst_var(InstVar),
constrained_inst_var(InstVar), _, _).
So I've changed it to that. There were several other "AAA" comments
in the code which I've also fixed up.
On Thu, Feb 17, 2000 at 07:50:27PM +1100, Fergus Henderson wrote:
>
> > -:- pred inst_name_apply_substitution(inst_name, inst_subst, inst_name).
> > -:- mode inst_name_apply_substitution(in, in, out) is det.
> > +:- pred inst_name_apply_substitution(inst_name, inst_var_sub, inst_name).
> > +:- mode inst_name_apply_substitution(in, in, out) is semidet.
>
> It would be helpful to document when/why this predicate fails.
>
> > inst_name_apply_substitution(user_inst(Name, Args0), Subst,
> > user_inst(Name, Args)) :-
> > inst_list_apply_substitution(Args0, Subst, Args).
> > -inst_name_apply_substitution(unify_inst(Live, InstA0, InstB0, Real), Subst,
> > - unify_inst(Live, InstA, InstB, Real)) :-
> > - inst_apply_substitution(InstA0, Subst, InstA),
> > - inst_apply_substitution(InstB0, Subst, InstB).
>
> Hmm... why don't you apply the substitution to the insts in the inst_name?
> I think it would be worth adding a comment explaining that.
Done.
> > -recompute_instmap_delta(RecomputeAtomic, Goal0 - GoalInfo0, Goal - GoalInfo,
> > - VarTypes, InstMap0, InstMapDelta) -->
> > +recompute_instmap_delta_1(RecomputeAtomic, Goal0 - GoalInfo0, Goal - GoalInfo,
> > + VarTypes, InstMap0, InstMapDelta, RI0, RI) :-
> > (
> > - { RecomputeAtomic = no },
> > - (
> > - { goal_is_atomic(Goal0) }
> > - ;
> > + RecomputeAtomic = no,
> > + goal_is_atomic(Goal0),
> > + Goal0 \= unify(_,lambda_goal(_,_,_,_,_,_,_,_),_,_,_)
> > % Lambda expressions always need to be processed.
> > - { Goal0 = unify(_, Rhs, _, _, _) },
> > - { Rhs \= lambda_goal(_, _, _, _, _, _, _, _) }
> > - )
>
> Hmm... you seem to have changed the semantics there:
> you changed a disjunction into a conjunction.
> I don't think that was mentioned in the log message.
> What's the purpose of that change?
The purpose is to make sure that lambda goals are not skipped when
RecomputeAtomic = no.
I have added this to the log message.
> > +:- pred lift(pred(T, module_info, module_info), T, recompute_info,
> > + recompute_info).
> > +:- mode lift(pred(out, in, out) is det, out, in, out) is det.
> > +
> > +lift(P, R) -->
> > + ModuleInfo0 =^ module_info,
> > + { P(R, ModuleInfo0, ModuleInfo) },
> > + ^module_info := ModuleInfo.
>
> Hmm, "lift" is a rather generic name... a brief comment
> explaining what this predicate does would be helpful, I think.
Done.
>
> > +recompute_instmap_delta_call(PredId, ProcId, Args, VarTypes, InstMap,
> > + InstMapDelta) -->
> > + ModuleInfo =^ module_info,
> > + { module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo) },
> > + { proc_info_interface_determinism(ProcInfo, Detism) },
> > + ( { determinism_components(Detism, _, at_most_zero) } ->
> > + { instmap_delta_init_unreachable(InstMapDelta) }
> > + ;
> > + { proc_info_argmodes(ProcInfo, ArgModes0) },
> > + { proc_info_inst_varset(ProcInfo, ProcInstVarSet) },
> > + InstVarSet =^ inst_varset,
> > + { rename_apart_inst_vars(InstVarSet, ProcInstVarSet,
> > + ArgModes0, ArgModes1) },
> > + { mode_list_get_initial_insts(ArgModes1, ModuleInfo,
> > + InitialInsts) },
> > + { map__init(InstVarSub0) },
> > + lift(recompute_instmap_delta_call_1(Args, VarTypes, InstMap,
> > + InitialInsts, InstVarSub0), InstVarSub),
> > +
> > + { mode_list_apply_substitution(ArgModes1, InstVarSub,
> > + ArgModes2) },
> > + lift(recompute_instmap_delta_call_2(Args, InstMap,
> > + ArgModes2), ArgModes),
> > + { instmap_delta_from_mode_list(Args, ArgModes,
> > + ModuleInfo, InstMapDelta) }
> > + ).
>
> Hmm, that's a moderately complicated bit of code... some
> comments here might help.
Done.
>
> > +:- pred recompute_instmap_delta_call_1(list(prog_var), vartypes, instmap,
> > + list(inst), inst_var_sub, inst_var_sub, module_info, module_info).
> > +:- mode recompute_instmap_delta_call_1(in, in, in, in, in, out, in, out) is det.
>
> This predicate seems poorly named to me...
> I don't think it is actually recomputing any instmap deltas,
> instead I think it is just computing a substitution?
I have renamed it to `compute_inst_var_sub'.
>
> > +recompute_instmap_delta_call_1([Arg | Args], VarTypes, InstMap, [Inst | Insts],
> > + Sub0, Sub, ModuleInfo0, ModuleInfo) :-
> > + % This is similar to modecheck_var_has_inst.
> > + ( instmap__is_reachable(InstMap) ->
> > + instmap__lookup_var(InstMap, Arg, ArgInst),
> > + map__lookup(VarTypes, Arg, Type),
> > + (
> > + inst_matches_initial(ArgInst, Inst, Type, ModuleInfo0,
> > + ModuleInfo1, Sub0, Sub1)
> > + ->
> > + ModuleInfo2 = ModuleInfo1,
> > + Sub2 = Sub1
> > + ;
> > + % AAA error("recompute_instmap_delta_call_1: inst_matches_initial failed")
> > + ModuleInfo2 = ModuleInfo0,
> > + Sub2 = Sub0
>
> I think you need some comments here.
> Why do you ignore the failure if inst_matches_initial fails?
The call to error should not be commented out. I have fixed this.
> > -compare_inst_list_2([], [], _, same, _).
> > +compare_inst_list_2([], [], _, [], same, _).
> > compare_inst_list_2([InstA | InstsA], [InstB | InstsB],
> > - no, Result, ModuleInfo) :-
> > - compare_inst(InstA, InstB, no, Result0, ModuleInfo),
> > - compare_inst_list_2(InstsA, InstsB, no, Result1, ModuleInfo),
> > + std_util:no, [Type | Types], Result, ModuleInfo) :-
>
> Please use `__' rather than `:' for the module qualifier.
> But I would advise not using the module qualifier here,
> just write `no' rather than `std_util__no'.
Done.
On Thu, Feb 17, 2000 at 09:01:37PM +1100, Fergus Henderson wrote:
> On 09-Feb-2000, David Overton <dmo at ender.cs.mu.oz.au> wrote:
> > Index: compiler/modes.m
> > @@ -607,11 +607,27 @@
> > { pred_info_procedures(PredInfo0, Procs0) },
> > { map__keys(Procs0, ProcIds) },
> > ( { WhatToCheck = check_modes } ->
> > - ( { ProcIds = [] } ->
> > + (
> > + { ProcIds = [] }
> > + ->
> > maybe_report_error_no_modes(PredId, PredInfo0,
> > ModuleInfo0),
> > { NumErrors0 = 0 }
> > ;
> > + { module_info_get_special_pred_map(ModuleInfo0,
> > + SpecialPredMap) },
> > + { map__member(SpecialPredMap, unify - _, PredId) }
> > + ->
> > + % Don't check for indistinguishable modes in unification
> > + % predicates.
>
> Calling map__member on the special_pred_map is likely to be quite
> inefficient. If you want to check whether a predicate is a unification
> predicate, it would be more efficient to just check the name and arity,
> e.g. via
>
> special_pred_name_arity(unify, _, PredName, Arity),
> pred_info_name(PredInfo0, PredName),
> pred_info_arity(PredInfo0, PredArity)
>
Done.
> > +++ compiler/prog_data.m 2000/02/03 03:44:26
> > @@ -698,7 +698,7 @@
> > ; abstract_inst(sym_name, list(inst_param)).
> >
> > % probably inst parameters should be variables not terms
> > -:- type inst_param == inst_term.
> > +:- type inst_param == inst_var.
>
> You can delete that comment now.
>
> It would probably be best to do a global s/inst_param/inst_var/g
> and then just delete the inst_param type.
Done.
>
> > +++ compiler/special_pred.m 2000/02/07 04:02:01
> > @@ -67,6 +67,11 @@
> > % mode num for special procs is always 0 (the first mode)
> > special_pred_mode_num(_, 0).
> >
> > + % XXX If the type has only one value, the determinism should be `det'.
> > + % However, this predicate is called by make_hlds before all the type
> > + % information is available, so we can't check that here.
> > + % There is a pass over the unify preds at the end of make_hlds to
> > + % fix up the determinism.
> > special_pred_info(unify, Type, "__Unify__", [Type, Type], [In, In], semidet) :-
> > in_mode(In).
>
> I don't think that comment deserves an XXX.
> An XXX should mark something that is or at least might be wrong,
> and which thus deserves revisiting. But in this case the comment
> in the last sentence says that the problem is already solved,
> so it doesn't need revisiting, right?
>
> But that information about what special_pred_info returns is needed
> to understand how to use that predicate, so a comment like that one
> should go in the interface section of the module.
This comment is actually incorrect because I realised that the mode 0
(in, in) unification procedure needs to be semidet so that it can be
called from the polymorphic unify. I have removed this comment and
placed a more accurate comment in the interface.
>
> > Index: compiler/type_util.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/compiler/type_util.m,v
> > retrieving revision 1.79
> > diff -u -r1.79 type_util.m
> > --- compiler/type_util.m 2000/02/08 06:59:28 1.79
> > +++ compiler/type_util.m 2000/02/09 00:19:41
> > @@ -171,6 +171,11 @@
> > :- pred type_util__get_cons_id_arg_types(module_info::in, (type)::in,
> > cons_id::in, list(type)::out) is det.
> >
> > + % The same as type_util__get_cons_id_arg_types except that the
> > + % cons_id is output non-deterministically.
> > +:- pred type_util__cons_id_arg_types(module_info::in, (type)::in,
> > + cons_id::out, list(type)::out) is nondet.
>
> Why not just call type_util__get_cons_id_arg_types
> and then list__member?
In type_util__get_cons_id_arg_types, the cons_id is input, not output.
>
> > % Given a type and a cons_id, look up the definitions of that
> > % type and constructor. Aborts if the cons_id is not user-defined.
> > :- pred type_util__get_type_and_cons_defn(module_info, (type), cons_id,
> > @@ -664,20 +669,39 @@
> > ConsId, TypeDefn, ConsDefn),
> > ConsDefn = hlds_cons_defn(ExistQVars0, _Constraints0,
> > ArgTypes0, _, _),
> > - ArgTypes0 \= []
> > + ArgTypes0 \= [],
> > +
> > + % XXX handle ExistQVars
> > + ExistQVars0 = []
> > ->
> > hlds_data__get_type_defn_tparams(TypeDefn, TypeDefnParams),
> > term__term_list_to_var_list(TypeDefnParams, TypeDefnVars),
> >
> > - % XXX handle ExistQVars
> > - require(unify(ExistQVars0, []),
> > - "type_util__get_cons_id_arg_types: existentially typed cons_id"),
> > -
> > map__from_corresponding_lists(TypeDefnVars, TypeArgs, TSubst),
> > term__apply_substitution_to_list(ArgTypes0, TSubst, ArgTypes)
> > ;
> > ArgTypes = []
> > ).
>
> That change is not documented in your log message.
> The change breaks the documentation for that predicate.
> And I don't understand the rationale for it.
I've undone that change. It slipped in accidentally.
>
> > Index: library/array.m
> > ===================================================================
> e RCS file: /home/mercury1/repository/mercury/library/array.m,v
> > retrieving revision 1.67
> > diff -u -r1.67 array.m
> > --- library/array.m 2000/01/19 09:45:16 1.67
> > +++ library/array.m 2000/02/04 02:15:56
> > @@ -93,30 +93,30 @@
> > % Note: in this implementation, the lower bound is always zero.
> > :- pred array__min(array(_T), int).
> > :- mode array__min(array_ui, out) is det.
> > -:- mode array__min(in, out) is det.
> > +%:- mode array__min(in, out) is det.
> >
> > % array__max returns the upper bound of the array.
> > :- pred array__max(array(_T), int).
> > :- mode array__max(array_ui, out) is det.
> > -:- mode array__max(in, out) is det.
> > +%:- mode array__max(in, out) is det.
>
> You should explain why all those modes are commented out.
>
> In fact, I don't understand why those modes need to be commented out.
Actually, it turns out that they don't. I'll remove those changes to
the library.
> Anyway, that completes my review.
> Apart from the issues I've raised so far,
> and the couple of things that you yourself listed
> as still do be done, this looks good.
> This change will need another round of reviewing, IMHO.
> I'd like to see a relative diff next time.
Here's the first part of the relative diff. The rest follows in a
second post.
--- ./cvslog Thu Feb 17 11:52:04 2000
+++ .././cvslog Mon Feb 21 17:07:03 2000
@@ -1,6 +1,6 @@
-Estimated hours taken: 40
+Estimated hours taken: 50
Allow polymorphic ground insts. This change assumes that all inst
parameters in the mode declaration for a predicate or function are
@@ -28,10 +28,19 @@
- handles inst_matches_initial(ground(...), bound(...), ...)
properly (this requires knowing the type of the variable).
+ The last change has also been made for inst_matches_final
+ and inst_matches_binding. However, the check is disabled for
+ now because, without alias tracking, the mode checker
+ becomes too conservative.
+
compiler/hlds_pred.m:
compiler/mode_info.m:
compiler/simplify.m:
+compiler/det_util.m:
Include the inst_varset in the proc_info, mode_info and simplify_info.
+ Add a vartypes field to the det_info.
+ Remove the vartypes field from the simplify_info since it is
+ now in the det_info.
Use record syntax for these data structures and their access predicates
to make future changes easier.
@@ -40,7 +49,10 @@
insts to ground(shared, constrained_inst_var(V)).
compiler/prog_data.m:
- Use inst_vars instead of inst_terms for inst_params.
+compiler/hlds_data.m:
+compiler/make_hlds.m:
+compiler/mode_util.m:
+ Use inst_vars instead of inst_params.
compiler/modes.m:
compiler/modecheck_call.m:
@@ -51,6 +63,10 @@
inst_matches_initial) and apply this to the final insts of the
called procedure before checking/recomputing them.
+compiler/mode_util.m:
+ Make sure that recompute_instmap_delta recomputes the
+ instmap_deltas for lambda_goals even when RecomputeAtomic = no.
+
compiler/type_util.m:
Add a new predicate, type_util__cons_id_arg_types which
nondeterministically returns the cons_ids and argument types for a
@@ -59,15 +75,20 @@
compiler/accumulator.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
+compiler/common.m:
compiler/deforest.m:
+compiler/det_analysis.m:
+compiler/det_report.m:
+compiler/det_util.m:
compiler/dnf.m:
compiler/follow_code.m:
+compiler/goal_util.m:
compiler/higher_order.m:
compiler/inst_util.m:
+compiler/instmap.m:
compiler/lambda.m:
compiler/magic.m:
compiler/magic_util.m:
-compiler/make_hlds.m:
compiler/mercury_to_mercury.m:
compiler/modecheck_unify.m:
compiler/module_qual.m:
@@ -79,21 +100,6 @@
compiler/saved_vars.m:
compiler/table_gen.m:
compiler/unify_proc.m:
- Pass inst_varsets where needed.
+compiler/unused_args.m:
+ Pass inst_varsets and types where needed.
Changes to reflect change in definition of the inst data type.
-
-library/array.m:
-library/term.m:
-library/io.m:
- Temporarily remove the (in, out) versions of some predicates
- in the array module since they now match_initial with the
- (array_di, array_uo) versions and cause a `duplicate mode
- declaration' error. (`array_di' and `array_uo' are not
- currently defined as unique modes since unique mode checking
- has not been fully implemented yet. Once it has, the (in, out)
- modes will need to be put back).
-
- Insert `inst_casts' from `ground' to `uniq_array' in various
- places to allow bootstrapping of the library without the
- (in, out) modes. These casts can be removed once this change
- has bootstrapped.
--- ./mercury/compiler/accumulator.m Fri Feb 11 10:44:32 2000
+++ .././mercury/compiler/accumulator.m Wed Feb 16 16:34:08 2000
@@ -324,18 +324,20 @@
proc_info_goal(ProcInfo0, Goal0),
proc_info_headvars(ProcInfo0, HeadVars),
proc_info_get_initial_instmap(ProcInfo0, ModuleInfo0, InitialInstMap),
+ proc_info_vartypes(ProcInfo0, VarTypes),
accumulator__simplify(Goal0, Goal),
accumulator__rearrange_goal(PredId, ProcId, Goal, InitialInstMap,
- ModuleInfo0, FullyStrict, GoalType, Base, Rec),
+ ModuleInfo0, VarTypes, FullyStrict, GoalType, Base, Rec),
accumulator__create_accumulator_pred(Rec, PredInfo0, ProcInfo0,
HstoAs_Subst, NewPredId, NewProcId, NewPredName,
ModuleInfo0, ModuleInfo1),
accumulator__transform(GoalType, Base, Rec, Goal, DoLCO, FullyStrict,
- ModuleInfo1, HeadVars, HstoAs_Subst, NewPredId,
- NewProcId, NewPredName, OrigGoal, Warnings, AccGoal),
+ ModuleInfo1, HeadVars, VarTypes, HstoAs_Subst,
+ NewPredId, NewProcId, NewPredName, OrigGoal, Warnings,
+ AccGoal),
accumulator__update_accumulator_pred(NewPredId, NewProcId, AccGoal,
ModuleInfo1, ModuleInfo),
@@ -411,11 +413,11 @@
% of module.
%
:- pred accumulator__rearrange_goal(pred_id::in, proc_id::in,
- hlds_goal::in, instmap::in, module_info::in, bool::in,
- top_level::out, base_goal::out, rec_goal::out) is semidet.
+ hlds_goal::in, instmap::in, module_info::in, vartypes::in,
+ bool::in, top_level::out, base_goal::out, rec_goal::out) is semidet.
accumulator__rearrange_goal(PredId, ProcId, Goal, InitialInstMap, ModuleInfo,
- FullyStrict, Type, Base, Rec) :-
+ VarTypes, FullyStrict, Type, Base, Rec) :-
(
Goal = switch(_Var, _CanFail, Cases, _StoreMap) - _GoalInfo,
Cases = [case(_IdA, GoalA), case(_IdB, GoalB)],
@@ -425,15 +427,15 @@
(
accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- GoalAList, Rec0),
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, GoalAList, Rec0),
% Make sure that the base case doesn't
% contain a recursive call.
\+ accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- GoalBList, _)
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, GoalBList, _)
->
Type = switch_rec_base,
Base = base(GoalBList),
@@ -441,15 +443,15 @@
;
accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- GoalBList, Rec0),
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, GoalBList, Rec0),
% Make sure that the base case doesn't
% contain a recursive call.
\+ accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- GoalAList, _)
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, GoalAList, _)
->
Type = switch_base_rec,
Base = base(GoalAList),
@@ -466,15 +468,15 @@
(
accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- GoalAList, Rec0),
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, GoalAList, Rec0),
% Make sure that the base case doesn't
% contain a recursive call.
\+ accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- GoalBList, _)
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, GoalBList, _)
->
Type = disj_rec_base,
Base = base(GoalBList),
@@ -482,15 +484,15 @@
;
accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- GoalBList, Rec0),
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, GoalBList, Rec0),
% Make sure that the base case doesn't
% contain a recursive call.
\+ accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- GoalAList, _)
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, GoalAList, _)
->
Type = disj_base_rec,
Base = base(GoalAList),
@@ -514,14 +516,14 @@
accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, IfList,
BeforeThenInstMap, ModuleInfo,
- FullyStrict, ThenList, Rec0),
+ VarTypes, FullyStrict, ThenList, Rec0),
% Make sure that the base case doesn't
% contain a recursive call.
\+ accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- ElseList, _)
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, ElseList, _)
->
Type = ite_rec_base,
Base = base(ElseList),
@@ -529,15 +531,15 @@
;
accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- ElseList, Rec0),
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, ElseList, Rec0),
% Make sure that the base case doesn't
% contain a recursive call.
\+ accumulator__split_recursive_case(PredId, ProcId,
InitialInstMap, [],
- InitialInstMap, ModuleInfo, FullyStrict,
- ThenList, _)
+ InitialInstMap, ModuleInfo, VarTypes,
+ FullyStrict, ThenList, _)
->
Type = ite_base_rec,
Base = base(ThenList),
@@ -718,16 +720,16 @@
%
:- pred accumulator__transform(top_level::in, base_goal::in, rec_goal::in,
hlds_goal::in, bool::in, bool::in, module_info::in,
- prog_vars::in, subst::in, pred_id::in,
+ prog_vars::in, vartypes::in, subst::in, pred_id::in,
proc_id::in, sym_name::in,
hlds_goal::out, warnings::out, hlds_goal::out) is semidet.
accumulator__transform(TopLevel, base(BaseGoalList), recursive(PreDP, DP, R, C),
- Goal, DoLCO, FullyStrict, ModuleInfo, HeadVars,
+ Goal, DoLCO, FullyStrict, ModuleInfo, HeadVars, VarTypes,
HstoAs_Subst, NewPredId, NewProcId, NewPredName,
OrigGoal, Warnings, NewGoal) :-
- accumulator__Ys_descended_from_Y0s(HeadVars, DP, ModuleInfo),
+ accumulator__Ys_descended_from_Y0s(HeadVars, DP, VarTypes, ModuleInfo),
accumulator__orig_base_case(BaseGoalList, OrigBaseGoal),
@@ -739,7 +741,7 @@
Y0stoYs_Subst, HstoAs_Subst, NewBaseGoal),
accumulator__new_recursive_case(DP, C, R, DoLCO, FullyStrict,
ModuleInfo, NewPredId, NewProcId, NewPredName,
- Vars, HeadVars, Y0stoYs_Subst, HstoAs_Subst,
+ Vars, HeadVars, VarTypes, Y0stoYs_Subst, HstoAs_Subst,
Warnings, NewRecGoal),
accumulator__top_level(TopLevel, Goal, OrigBaseGoal, OrigRecGoal,
@@ -866,12 +868,12 @@
%
:- pred accumulator__split_recursive_case(pred_id::in, proc_id::in,
instmap::in, hlds_goals::in,
- instmap::in, module_info::in, bool::in,
+ instmap::in, module_info::in, vartypes::in, bool::in,
hlds_goals::in, rec_goal::out) is semidet.
-accumulator__split_recursive_case(PredId, ProcId,
- PreInstMap, PreGoals,
- InitialInstMap, ModuleInfo, FullyStrict, Goals, RecGoal) :-
+accumulator__split_recursive_case(PredId, ProcId, PreInstMap, PreGoals,
+ InitialInstMap, ModuleInfo, VarTypes, FullyStrict, Goals,
+ RecGoal) :-
solutions(accumulator__split_goals(Goals, PredId, ProcId), Solns),
Solns = [recursive(DP0, R, C0)],
calculate_instmap(DP0, InitialInstMap, InitialInstMapBeforeR),
@@ -881,7 +883,7 @@
% that only goals which contain dynamic variables are
% left after the recursive call, simplifying the latter
% stages.
- move_goals(R, InitialInstMapBeforeR, ModuleInfo, FullyStrict,
+ move_goals(R, InitialInstMapBeforeR, ModuleInfo, VarTypes, FullyStrict,
C0, PreC0, PostC0),
list__append(DP0, PreC0, DP),
C = PostC0,
@@ -934,31 +936,30 @@
% recursive form, much harder to do though. Look into this
% later. NB you need LCO for the else case.
%
-:- pred move_goals(hlds_goal::in, instmap::in, module_info::in, bool::in,
- hlds_goals::in, hlds_goals::out, hlds_goals::out) is det.
+:- pred move_goals(hlds_goal::in, instmap::in, module_info::in, vartypes::in, bool::in, hlds_goals::in, hlds_goals::out, hlds_goals::out) is det.
-move_goals(_StartGoal, _IMBeforeStartGoal, _MI, _FullyStrict, [], [], []).
-move_goals(StartGoal, InstMapBeforeStartGoal, ModuleInfo, FullyStrict,
- [Goal|Goals], PreGoals, PostGoals) :-
+move_goals(_StartGoal, _IMBeforeStartGoal, _MI, _VT, _FullyStrict, [], [], []).
+move_goals(StartGoal, InstMapBeforeStartGoal, ModuleInfo, VarTypes,
+ FullyStrict, [Goal|Goals], PreGoals, PostGoals) :-
StartGoal = _GoalExpr - GoalInfo,
goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
instmap__apply_instmap_delta(InstMapBeforeStartGoal,
InstMapDelta, InstMapBeforeGoal),
(
- goal_util__can_reorder_goals(ModuleInfo, FullyStrict,
+ goal_util__can_reorder_goals(ModuleInfo, VarTypes, FullyStrict,
InstMapBeforeStartGoal, StartGoal,
InstMapBeforeGoal, Goal)
->
move_goals(StartGoal, InstMapBeforeStartGoal, ModuleInfo,
- FullyStrict, Goals, PreGoals0, PostGoals),
+ VarTypes, FullyStrict, Goals, PreGoals0, PostGoals),
PreGoals = [Goal | PreGoals0]
;
- move_goals(Goal, InstMapBeforeGoal, ModuleInfo, FullyStrict,
- Goals, PreGoalsForGoal, PostGoalsForGoal),
- move_goals(StartGoal, InstMapBeforeStartGoal,
- ModuleInfo, FullyStrict, PreGoalsForGoal,
- PreGoals, PostGoalsForStartGoal),
+ move_goals(Goal, InstMapBeforeGoal, ModuleInfo, VarTypes,
+ FullyStrict, Goals, PreGoalsForGoal, PostGoalsForGoal),
+ move_goals(StartGoal, InstMapBeforeStartGoal, ModuleInfo,
+ VarTypes, FullyStrict, PreGoalsForGoal, PreGoals,
+ PostGoalsForStartGoal),
list__append(PostGoalsForStartGoal, [Goal | PostGoalsForGoal],
PostGoals)
@@ -975,11 +976,12 @@
% DP, list of goals then it cannot be descended from the Y0s.
%
:- pred accumulator__Ys_descended_from_Y0s(prog_vars::in,
- a_goals::in, module_info::in) is semidet.
+ a_goals::in, vartypes::in, module_info::in) is semidet.
-accumulator__Ys_descended_from_Y0s(HeadVars, DecomposeProcess, ModuleInfo) :-
+accumulator__Ys_descended_from_Y0s(HeadVars, DecomposeProcess, VarTypes,
+ ModuleInfo) :-
accumulator__vars_to_accumulate(HeadVars, DecomposeProcess,
- ModuleInfo, ChangedHeadVars),
+ VarTypes, ModuleInfo, ChangedHeadVars),
ChangedHeadVars = [].
@@ -998,17 +1000,18 @@
% that are headvars.
%
:- pred accumulator__vars_to_accumulate(prog_vars::in, a_goals::in,
- module_info::in, prog_vars::out) is det.
+ vartypes::in, module_info::in, prog_vars::out) is det.
-accumulator__vars_to_accumulate(HeadVars, C, ModuleInfo, VarsToAccumulate) :-
+accumulator__vars_to_accumulate(HeadVars, C, VarTypes, ModuleInfo,
+ VarsToAccumulate) :-
C = goal(ComposeGoals, InstMapBeforeCompose),
goal_list_instmap_delta(ComposeGoals, InstMapDelta),
instmap__apply_instmap_delta(InstMapBeforeCompose,
InstMapDelta,InstMapAfterCompose),
- instmap_changed_vars(InstMapBeforeCompose,
- InstMapAfterCompose, ModuleInfo, ChangedVars),
+ instmap_changed_vars(InstMapBeforeCompose, InstMapAfterCompose,
+ VarTypes, ModuleInfo, ChangedVars),
Member = (pred(M::in) is semidet :- set__member(M, ChangedVars)),
list__filter(Member, HeadVars, VarsToAccumulate).
@@ -1052,11 +1055,11 @@
%
% This predicate is currently unused.
%
-:- pred accumulator__static_vars_in_recursive_call(a_goal::in,
- a_goals::in, module_info::in, prog_vars::out) is det.
+:- pred accumulator__static_vars_in_recursive_call(a_goal::in, a_goals::in,
+ vartypes::in, module_info::in, prog_vars::out) is det.
accumulator__static_vars_in_recursive_call(Recursive, Compose,
- ModuleInfo, Vars) :-
+ VarTypes, ModuleInfo, Vars) :-
Recursive = goal(_RecGoalExpr - RecGoalInfo, InstMapBeforeRec),
Compose = goal(ComposeGoals, _InstMapBeforeCompose),
@@ -1066,7 +1069,7 @@
instmap__apply_instmap_delta(InstMapBeforeRec, RecInstMapDelta,
InstMapAfterRec),
instmap_changed_vars(InstMapBeforeRec, InstMapAfterRec,
- ModuleInfo, ChangedVars),
+ VarTypes, ModuleInfo, ChangedVars),
set__difference(RecNonLocals, ChangedVars, PossibleStaticVars),
@@ -1188,20 +1191,20 @@
:- pred accumulator__new_recursive_case(a_goals::in, a_goals::in,
a_goal::in, bool::in, bool::in,
module_info::in, pred_id::in, proc_id::in,
- sym_name::in, prog_vars::in, prog_vars::in, subst::in,
- subst::in, warnings::out, hlds_goal::out) is semidet.
+ sym_name::in, prog_vars::in, prog_vars::in, vartypes::in,
+ subst::in, subst::in, warnings::out, hlds_goal::out) is semidet.
accumulator__new_recursive_case(DP, C, R0, DoLCO, FullyStrict,
- ModuleInfo, PredId, ProcId, Name, Hs, HeadVars,
+ ModuleInfo, PredId, ProcId, Name, Hs, HeadVars, VarTypes,
Y0stoYs_Subst, HstoAs_Subst, Warnings, Goal) :-
DP = goal(DecomposeProcess, _InstMapBeforeDecomposeProcess),
C = goal(Compose, InstMapBeforeCompose),
R0 = goal(Recursive0, _InstMapBeforeRecursive0),
- assoc_info_init(ModuleInfo, HeadVars, DP, C, R0,
+ assoc_info_init(ModuleInfo, HeadVars, VarTypes, DP, C, R0,
Y0stoYs_Subst, HstoAs_Subst, AssocInfo0),
accumulator__check_assoc(Compose, InstMapBeforeCompose, ModuleInfo,
- FullyStrict, PreRecGoal0, PostRecGoal0,
+ VarTypes, FullyStrict, PreRecGoal0, PostRecGoal0,
AssocInfo0, AssocInfo),
(
@@ -1374,19 +1377,19 @@
% that goal into AGs.
%
:- pred accumulator__check_assoc(hlds_goals::in, instmap::in,
- module_info::in, bool::in, hlds_goals::out,
+ module_info::in, vartypes::in, bool::in, hlds_goals::out,
hlds_goals::out, assoc_info::in, assoc_info::out) is semidet.
-accumulator__check_assoc([], _InstMap, _MI, _FullyStrict, [], []) --> [].
+accumulator__check_assoc([], _InstMap, _MI, _VT, _FullyStrict, [], []) --> [].
accumulator__check_assoc([Goal0 | Goal0s], InstMapBeforeGoal0,
- ModuleInfo, FullyStrict, MovedGoals, AfterGoals) -->
+ ModuleInfo, VarTypes, FullyStrict, MovedGoals, AfterGoals) -->
(
{ goal_is_construction_unification(Goal0) }
->
- { move_goals(Goal0, InstMapBeforeGoal0, ModuleInfo, FullyStrict,
- Goal0s, PreGoal0s, PostGoal0s) },
+ { move_goals(Goal0, InstMapBeforeGoal0, ModuleInfo, VarTypes,
+ FullyStrict, Goal0s, PreGoal0s, PostGoal0s) },
accumulator__check_assoc(PreGoal0s, InstMapBeforeGoal0,
- ModuleInfo, FullyStrict,
+ ModuleInfo, VarTypes, FullyStrict,
MovedGoals, AfterGoal0s),
{ list__append(AfterGoal0s, [Goal0 | PostGoal0s], AfterGoals) }
;
@@ -1398,7 +1401,7 @@
accumulator__check_goal(Goal0, Goal),
accumulator__check_assoc(Goal0s, InstMapBeforeGoal0s,
- ModuleInfo, FullyStrict,
+ ModuleInfo, VarTypes, FullyStrict,
MovedGoal0s, AfterGoals),
{ MovedGoals = [Goal | MovedGoal0s] }
).
@@ -1749,12 +1752,14 @@
proc_info_argmodes(ProcInfo, Modes),
pred_info_get_assertions(PredInfo, Assertions),
+ proc_info_vartypes(ProcInfo, VarTypes),
(
commutativity_assertion(set__to_sorted_list(Assertions),
ModuleInfo, Args0, PossibleStaticVars0)
->
- check_modes(Args0, PossibleStaticVars0, Modes, ModuleInfo),
+ check_modes(Args0, PossibleStaticVars0, Modes, VarTypes,
+ ModuleInfo),
Args = Args0,
PossibleStaticVars = PossibleStaticVars0,
AssocInfo = AssocInfo0,
@@ -1780,7 +1785,8 @@
)
), Args0, Args),
- check_modes(Args, PossibleStaticVars, Modes, ModuleInfo),
+ check_modes(Args, PossibleStaticVars, Modes, VarTypes,
+ ModuleInfo),
% Determine what variables can be static
pred_info_module(PredInfo, ModuleName),
@@ -1897,29 +1903,30 @@
% doesn't change (ie an in mode).
%
:- pred check_modes(prog_vars::in, set(prog_var)::in,
- list(mode)::in, module_info::in) is semidet.
+ list(mode)::in, vartypes::in, module_info::in) is semidet.
-check_modes([], _, _, _).
-check_modes([V | Vs], PossibleStaticVars, [M | Ms], ModuleInfo) :-
+check_modes([], _, _, _, _).
+check_modes([V | Vs], PossibleStaticVars, [M | Ms], VarTypes, ModuleInfo) :-
(
set__member(V, PossibleStaticVars)
->
mode_get_insts(ModuleInfo, M, InitialInst, FinalInst),
- inst_matches_final(InitialInst, FinalInst, ModuleInfo)
+ map__lookup(VarTypes, V, Type),
+ inst_matches_final(InitialInst, FinalInst, Type, ModuleInfo)
;
true
),
- check_modes(Vs, PossibleStaticVars, Ms, ModuleInfo).
+ check_modes(Vs, PossibleStaticVars, Ms, VarTypes, ModuleInfo).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
-:- pred assoc_info_init(module_info::in, prog_vars::in, a_goals::in,
- a_goals::in, a_goal::in,
+:- pred assoc_info_init(module_info::in, prog_vars::in, vartypes::in,
+ a_goals::in, a_goals::in, a_goal::in,
subst::in, subst::in, assoc_info::out) is det.
-assoc_info_init(ModuleInfo, HeadVars, DP, Compose, R, Y0stoYs_Subst,
+assoc_info_init(ModuleInfo, HeadVars, VarTypes, DP, Compose, R, Y0stoYs_Subst,
HstoAs_Subst, AssocInfo) :-
DP = goal(Decompose, _InstMapBeforeDecomposeProcess),
R = goal(_RecGoalExpr - RecGoalInfo, _InstMapBeforeRecursive),
@@ -1930,7 +1937,8 @@
% Set up the OrigDynVarMap
%
reverse_subst(Y0stoYs_Subst, YstoY0s_Subst),
- accumulator__vars_to_accumulate(HeadVars, Compose, ModuleInfo, Ys),
+ accumulator__vars_to_accumulate(HeadVars, Compose, VarTypes,
+ ModuleInfo, Ys),
list__map(map__lookup(YstoY0s_Subst), Ys, Y0s),
assoc_list__from_corresponding_lists(Y0s, Y0s, AssocDynamicList),
--- ./mercury/compiler/common.m Fri Feb 11 10:44:41 2000
+++ .././mercury/compiler/common.m Wed Feb 16 15:07:36 2000
@@ -402,12 +402,13 @@
(
goal_info_get_determinism(GoalInfo, Det),
common__check_call_detism(Det),
+ simplify_info_get_var_types(Info0, VarTypes),
simplify_info_get_module_info(Info0, ModuleInfo),
module_info_pred_proc_info(ModuleInfo, PredId,
ProcId, _, ProcInfo),
proc_info_argmodes(ProcInfo, ArgModes),
- common__partition_call_args(ModuleInfo, ArgModes, Args,
- InputArgs, OutputArgs, OutputModes)
+ common__partition_call_args(VarTypes, ModuleInfo, ArgModes,
+ Args, InputArgs, OutputArgs, OutputModes)
->
common__optimise_call_2(seen_call(PredId, ProcId), InputArgs,
OutputArgs, OutputModes, Goal0, GoalInfo, Goal,
@@ -421,8 +422,9 @@
GoalInfo, Goal, Info0, Info) :-
(
common__check_call_detism(Det),
+ simplify_info_get_var_types(Info0, VarTypes),
simplify_info_get_module_info(Info0, ModuleInfo),
- common__partition_call_args(ModuleInfo, Modes, Args,
+ common__partition_call_args(VarTypes, ModuleInfo, Modes, Args,
InputArgs, OutputArgs, OutputModes)
->
common__optimise_call_2(higher_order_call,
@@ -516,21 +518,22 @@
% Partition the arguments of a call into inputs and outputs,
% failing if any of the outputs have a unique component
% or if any of the outputs contain any `any' insts.
-:- pred common__partition_call_args(module_info::in, list(mode)::in,
- list(prog_var)::in, list(prog_var)::out,
+:- pred common__partition_call_args(vartypes::in, module_info::in,
+ list(mode)::in, list(prog_var)::in, list(prog_var)::out,
list(prog_var)::out, list(mode)::out) is semidet.
-common__partition_call_args(_, [], [_ | _], _, _, _) :-
+common__partition_call_args(_, _, [], [_ | _], _, _, _) :-
error("common__partition_call_args").
-common__partition_call_args(_, [_ | _], [], _, _, _) :-
+common__partition_call_args(_, _, [_ | _], [], _, _, _) :-
error("common__partition_call_args").
-common__partition_call_args(_, [], [], [], [], []).
-common__partition_call_args(ModuleInfo, [ArgMode | ArgModes], [Arg | Args],
- InputArgs, OutputArgs, OutputModes) :-
- common__partition_call_args(ModuleInfo, ArgModes, Args,
+common__partition_call_args(_, _, [], [], [], [], []).
+common__partition_call_args(VarTypes, ModuleInfo, [ArgMode | ArgModes],
+ [Arg | Args], InputArgs, OutputArgs, OutputModes) :-
+ common__partition_call_args(VarTypes, ModuleInfo, ArgModes, Args,
InputArgs1, OutputArgs1, OutputModes1),
mode_get_insts(ModuleInfo, ArgMode, InitialInst, FinalInst),
- ( inst_matches_binding(InitialInst, FinalInst, ModuleInfo) ->
+ map__lookup(VarTypes, Arg, Type),
+ ( inst_matches_binding(InitialInst, FinalInst, Type, ModuleInfo) ->
InputArgs = [Arg | InputArgs1],
OutputArgs = OutputArgs1,
OutputModes = OutputModes1
@@ -544,7 +547,7 @@
% between the different variables.
% (inst_matches_binding applied to identical insts
% fails only for `any' insts.)
- inst_matches_binding(FinalInst, FinalInst, ModuleInfo),
+ inst_matches_binding(FinalInst, FinalInst, Type, ModuleInfo),
% Don't optimize calls where a partially instantiated
% variable is further instantiated. That case is difficult
--- ./mercury/compiler/det_analysis.m Fri Feb 11 10:44:46 2000
+++ .././mercury/compiler/det_analysis.m Thu Feb 17 14:48:56 2000
@@ -257,7 +257,8 @@
% Infer the determinism of the goal
proc_info_goal(Proc0, Goal0),
proc_info_get_initial_instmap(Proc0, ModuleInfo0, InstMap0),
- det_info_init(ModuleInfo0, PredId, ProcId, Globals, DetInfo),
+ proc_info_vartypes(Proc0, VarTypes),
+ det_info_init(ModuleInfo0, VarTypes, PredId, ProcId, Globals, DetInfo),
det_infer_goal(Goal0, InstMap0, SolnContext, DetInfo,
Goal, Detism1, Msgs),
--- ./mercury/compiler/det_report.m Fri Feb 11 10:44:47 2000
+++ .././mercury/compiler/det_report.m Thu Feb 17 15:04:48 2000
@@ -179,9 +179,10 @@
ProcId, ModuleInfo1, Message,
DeclaredDetism, InferredDetism),
{ proc_info_goal(ProcInfo0, Goal) },
+ { proc_info_vartypes(ProcInfo0, VarTypes) },
globals__io_get_globals(Globals),
- { det_info_init(ModuleInfo1, PredId, ProcId, Globals,
- DetInfo) },
+ { det_info_init(ModuleInfo1, VarTypes, PredId, ProcId,
+ Globals, DetInfo) },
det_diagnose_goal(Goal, DeclaredDetism, [], DetInfo, _)
% XXX with the right verbosity options, we want to
% call report_determinism_problem only if diagnose
@@ -1262,7 +1263,10 @@
hlds_out__write_determinism(InferredDetism),
io__write_string("'.\n"),
globals__io_get_globals(Globals),
- { det_info_init(ModuleInfo, PredId, ProcId, Globals, DetInfo) },
+ { module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo) },
+ { proc_info_vartypes(ProcInfo, VarTypes) },
+ { det_info_init(ModuleInfo, VarTypes, PredId, ProcId, Globals,
+ DetInfo) },
det_diagnose_goal(Goal, DeclaredDetism, [], DetInfo, _),
io__set_exit_status(1).
det_report_msg(par_conj_not_det(InferredDetism, PredId,
@@ -1289,7 +1293,10 @@
prog_out__write_context(Context),
io__write_string(" non-failing parallel conjunctions.\n"),
globals__io_get_globals(Globals),
- { det_info_init(ModuleInfo, PredId, ProcId, Globals, DetInfo) },
+ { module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo) },
+ { proc_info_vartypes(ProcInfo, VarTypes) },
+ { det_info_init(ModuleInfo, VarTypes, PredId, ProcId, Globals,
+ DetInfo) },
det_diagnose_conj(Goals, det, [], DetInfo, _),
io__set_exit_status(1).
det_report_msg(pragma_c_code_without_det_decl(PredId, ProcId),
--- ./mercury/compiler/det_util.m Fri Feb 11 10:44:47 2000
+++ .././mercury/compiler/det_util.m Thu Feb 17 14:54:48 2000
@@ -61,8 +61,9 @@
:- pred det_no_output_vars(set(prog_var), instmap, instmap_delta, det_info).
:- mode det_no_output_vars(in, in, in, in) is semidet.
-:- pred det_info_init(module_info, pred_id, proc_id, globals, det_info).
-:- mode det_info_init(in, in, in, in, out) is det.
+:- pred det_info_init(module_info, vartypes, pred_id, proc_id, globals,
+ det_info).
+:- mode det_info_init(in, in, in, in, in, out) is det.
:- pred det_info_get_module_info(det_info, module_info).
:- mode det_info_get_module_info(in, out) is det.
@@ -85,6 +86,9 @@
:- pred det_info_set_module_info(det_info, module_info, det_info).
:- mode det_info_set_module_info(in, in, out) is det.
+:- func vartypes(det_info) = vartypes.
+:- func 'vartypes:='(det_info, vartypes) = det_info.
+
%-----------------------------------------------------------------------------%
:- implementation.
@@ -152,32 +156,35 @@
det_no_output_vars(Vars, InstMap, InstMapDelta, DetInfo) :-
det_info_get_module_info(DetInfo, ModuleInfo),
- instmap__no_output_vars(InstMap, InstMapDelta, Vars, ModuleInfo).
+ instmap__no_output_vars(InstMap, InstMapDelta, Vars, DetInfo^vartypes,
+ ModuleInfo).
%-----------------------------------------------------------------------------%
-:- type det_info ---> det_info(
- module_info,
- pred_id, % the id of the proc
- proc_id, % currently processed
- bool, % --reorder-conj
- bool, % --reorder-disj
- bool % --fully-strict
- ).
+:- type det_info
+ ---> det_info(
+ module_info :: module_info,
+ vartypes :: vartypes,
+ pred_id :: pred_id, % the id of the proc
+ proc_id :: proc_id, % currently processed
+ reorder_conj :: bool, % --reorder-conj
+ reorder_disj :: bool, % --reorder-disj
+ fully_strict :: bool % --fully-strict
+ ).
-det_info_init(ModuleInfo, PredId, ProcId, Globals, DetInfo) :-
+det_info_init(ModuleInfo, VarTypes, PredId, ProcId, Globals, DetInfo) :-
globals__lookup_bool_option(Globals, reorder_conj, ReorderConj),
globals__lookup_bool_option(Globals, reorder_disj, ReorderDisj),
globals__lookup_bool_option(Globals, fully_strict, FullyStrict),
- DetInfo = det_info(ModuleInfo, PredId, ProcId,
+ DetInfo = det_info(ModuleInfo, VarTypes, PredId, ProcId,
ReorderConj, ReorderDisj, FullyStrict).
-det_info_get_module_info(det_info(ModuleInfo, _, _, _, _, _), ModuleInfo).
-det_info_get_pred_id(det_info(_, PredId, _, _, _, _), PredId).
-det_info_get_proc_id(det_info(_, _, ProcId, _, _, _), ProcId).
-det_info_get_reorder_conj(det_info(_, _, _, ReorderConj, _, _), ReorderConj).
-det_info_get_reorder_disj(det_info(_, _, _, _, ReorderDisj, _), ReorderDisj).
-det_info_get_fully_strict(det_info(_, _, _, _, _, FullyStrict), FullyStrict).
+det_info_get_module_info(DetInfo, DetInfo^module_info).
+det_info_get_pred_id(DetInfo, DetInfo^pred_id).
+det_info_get_proc_id(DetInfo, DetInfo^proc_id).
+det_info_get_reorder_conj(DetInfo, DetInfo^reorder_conj).
+det_info_get_reorder_disj(DetInfo, DetInfo^reorder_disj).
+det_info_get_fully_strict(DetInfo, DetInfo^fully_strict).
-det_info_set_module_info(det_info(_, B, C, D, E, F), ModuleInfo,
- det_info(ModuleInfo, B, C, D, E, F)).
+det_info_set_module_info(DetInfo, ModuleInfo,
+ DetInfo^module_info := ModuleInfo).
--- ./mercury/compiler/goal_util.m Fri Feb 11 10:44:54 2000
+++ .././mercury/compiler/goal_util.m Wed Feb 16 16:30:56 2000
@@ -179,8 +179,8 @@
% - any possible change in termination behaviour is allowed
% according to the semantics options.
%
-:- pred goal_util__can_reorder_goals(module_info::in, bool::in, instmap::in,
- hlds_goal::in, instmap::in, hlds_goal::in) is semidet.
+:- pred goal_util__can_reorder_goals(module_info::in, vartypes::in, bool::in,
+ instmap::in, hlds_goal::in, instmap::in, hlds_goal::in) is semidet.
% goal_util__reordering_maintains_termination(ModuleInfo,
% FullyStrict, Goal1, Goal2)
@@ -1036,8 +1036,9 @@
%-----------------------------------------------------------------------------%
-goal_util__can_reorder_goals(ModuleInfo, FullyStrict, InstmapBeforeEarlierGoal,
- EarlierGoal, InstmapBeforeLaterGoal, LaterGoal) :-
+goal_util__can_reorder_goals(ModuleInfo, VarTypes, FullyStrict,
+ InstmapBeforeEarlierGoal, EarlierGoal, InstmapBeforeLaterGoal,
+ LaterGoal) :-
EarlierGoal = _ - EarlierGoalInfo,
LaterGoal = _ - LaterGoalInfo,
@@ -1054,7 +1055,7 @@
% on the outputs of the current goal.
%
\+ goal_depends_on_earlier_goal(LaterGoal, EarlierGoal,
- InstmapBeforeEarlierGoal, ModuleInfo),
+ InstmapBeforeEarlierGoal, VarTypes, ModuleInfo),
%
% Don't reorder the goals if the later goal changes the
@@ -1064,7 +1065,7 @@
% full mode analysis in other cases.
%
\+ goal_depends_on_earlier_goal(EarlierGoal, LaterGoal,
- InstmapBeforeLaterGoal, ModuleInfo).
+ InstmapBeforeLaterGoal, VarTypes, ModuleInfo).
goal_util__reordering_maintains_termination(ModuleInfo, FullyStrict,
@@ -1103,17 +1104,17 @@
%
% This code does work on the alias branch.
%
-:- pred goal_depends_on_earlier_goal(hlds_goal::in,
- hlds_goal::in, instmap::in, module_info::in) is semidet.
+:- pred goal_depends_on_earlier_goal(hlds_goal::in, hlds_goal::in, instmap::in,
+ vartypes::in, module_info::in) is semidet.
goal_depends_on_earlier_goal(_ - LaterGoalInfo, _ - EarlierGoalInfo,
- InstMapBeforeEarlierGoal, ModuleInfo) :-
+ InstMapBeforeEarlierGoal, VarTypes, ModuleInfo) :-
goal_info_get_instmap_delta(EarlierGoalInfo, EarlierInstMapDelta),
instmap__apply_instmap_delta(InstMapBeforeEarlierGoal,
EarlierInstMapDelta, InstMapAfterEarlierGoal),
instmap_changed_vars(InstMapBeforeEarlierGoal, InstMapAfterEarlierGoal,
- ModuleInfo, EarlierChangedVars),
+ VarTypes, ModuleInfo, EarlierChangedVars),
goal_info_get_nonlocals(LaterGoalInfo, LaterGoalNonLocals),
set__intersect(EarlierChangedVars, LaterGoalNonLocals, Intersection),
--- ./mercury/compiler/hlds_data.m Fri Feb 11 10:44:56 2000
+++ .././mercury/compiler/hlds_data.m Fri Feb 18 16:03:54 2000
@@ -435,7 +435,7 @@
---> hlds_inst_defn(
inst_varset, % The names of the inst
% parameters (if any).
- list(inst_param), % The inst parameters (if any).
+ list(inst_var), % The inst parameters (if any).
% ([I] in the above example.)
hlds_inst_body, % The definition of this inst.
condition, % Unused (reserved for
@@ -632,7 +632,7 @@
---> hlds_mode_defn(
inst_varset, % The names of the inst
% parameters (if any).
- list(inst_param), % The list of the inst
+ list(inst_var), % The list of the inst
% parameters (if any).
% (e.g. [I] for the second
% example above.)
--- ./mercury/compiler/hlds_pred.m Fri Feb 11 10:44:59 2000
+++ .././mercury/compiler/hlds_pred.m Tue Feb 15 14:23:12 2000
@@ -1548,9 +1548,6 @@
:- type proc_info
---> procedure(
- declared_determinism :: maybe(determinism),
- % _declared_ determinism
- % or `no' if there was no detism decl
varset :: prog_varset, % variable names
vartypes :: vartypes, % variable types
headvars :: list(prog_var), % head vars
@@ -1565,6 +1562,9 @@
% (or the context of the first clause,
% if there was no mode declaration).
stack_slots :: stack_slots, % stack allocations
+ declared_determinism :: maybe(determinism),
+ % _declared_ determinism
+ % or `no' if there was no detism decl
inferred_determinism :: determinism,
% _inferred_ determinism
can_process :: bool,
@@ -1646,8 +1646,8 @@
map__init(TCVarsMap),
RLExprn = no,
NewProc = procedure(
- MaybeDet, BodyVarSet, BodyTypes, HeadVars, Modes, InstVarSet,
- MaybeArgLives, ClauseBody, MContext, StackSlots,
+ BodyVarSet, BodyTypes, HeadVars, Modes, InstVarSet,
+ MaybeArgLives, ClauseBody, MContext, StackSlots, MaybeDet,
InferredDet, CanProcess, ArgInfo, InitialLiveness,
TVarsMap, TCVarsMap, eval_normal, no, no, DeclaredModes,
IsAddressTaken, RLExprn
@@ -1660,9 +1660,9 @@
ProcInfo) :-
RLExprn = no,
ProcInfo = procedure(
- DeclaredDetism, BodyVarSet, BodyTypes, HeadVars,
+ BodyVarSet, BodyTypes, HeadVars,
HeadModes, InstVarSet, HeadLives, Goal, Context,
- StackSlots, InferredDetism, CanProcess, ArgInfo,
+ StackSlots, DeclaredDetism, InferredDetism, CanProcess, ArgInfo,
Liveness, TVarMap, TCVarsMap, eval_normal, ArgSizes,
Termination, no, IsAddressTaken, RLExprn).
@@ -1672,9 +1672,9 @@
set__init(Liveness),
MaybeHeadLives = no,
RLExprn = no,
- ProcInfo = procedure(yes(Detism), VarSet, VarTypes, HeadVars, HeadModes,
+ ProcInfo = procedure(VarSet, VarTypes, HeadVars, HeadModes,
InstVarSet, MaybeHeadLives, Goal, Context, StackSlots,
- Detism, yes, [], Liveness, TVarMap, TCVarsMap,
+ yes(Detism), Detism, yes, [], Liveness, TVarMap, TCVarsMap,
eval_normal, no, no, no, IsAddressTaken, RLExprn).
proc_info_set_body(ProcInfo0, VarSet, VarTypes, HeadVars, Goal,
@@ -1784,72 +1784,6 @@
proc_info_is_address_taken(ProcInfo, ProcInfo^is_address_taken).
proc_info_get_rl_exprn_id(ProcInfo, ProcInfo^rl_exprn_id).
-
-% :- type proc_info
-% ---> procedure(
-% A maybe(determinism),
-% % _declared_ determinism
-% % or `no' if there was no detism decl
-% B varset, % variable names
-% C map(var, type), % variable types
-% D list(prog_var), % head vars
-% E list(mode), % modes of args
-% F maybe(list(is_live)),
-% % liveness (in the mode analysis sense)
-% % of the arguments
-% G hlds_goal, % Body
-% H prog_context,
-% % The context of the `:- mode' decl
-% % (or the context of the first clause,
-% % if there was no mode declaration).
-% I stack_slots, % stack allocations
-% J determinism, % _inferred_ determinism
-% K bool, % no if we must not process this
-% % procedure yet (used to delay
-% % mode checking etc. for complicated
-% % modes of unification procs until
-% % the end of the unique_modes pass.)
-% L list(arg_info), % calling convention of each arg:
-% % information computed by arg_info.m
-% % (based on the modes etc.)
-% % and used by code generation
-% % to determine how each argument
-% % should be passed.
-% M liveness_info, % the initial liveness,
-% % for code generation
-% N type_info_varmap,
-% % typeinfo vars for type parameters
-% O typeclass_info_varmap,
-% % typeclass_info vars for class
-% % constraints
-% P eval_method,
-% % info on how the proc sould be
-% % evaluated
-% Q maybe(arg_size_info),
-% % Information about the relative sizes
-% % of the input and output args of the
-% % procedure. Set by termination
-% % analysis.
-% R maybe(termination_info),
-% % The termination properties of the
-% % procedure. Set by termination
-% % analysis.
-% S maybe(list(mode)),
-% % declared modes of arguments.
-% T is_address_taken
-% % Is the address of this procedure
-% % taken? If yes, we will need to use
-% % typeinfo liveness for them, so that
-% % deep_copy and accurate gc have the
-% % RTTI they need for copying closures.
-% U maybe(rl_exprn_id)
-% % For predicates with an
-% % `aditi_top_down' marker, which are
-% % executed top-down on the Aditi side
-% % of the connection, we generate an RL
-% % expression, for which this is an
-% % identifier. See rl_update.m.
-% ).
proc_info_set_varset(ProcInfo, X, ProcInfo^varset := X).
--- ./mercury/compiler/inst.m Fri Feb 11 10:44:59 2000
+++ .././mercury/compiler/inst.m Tue Feb 15 14:29:05 2000
@@ -1,5 +1,5 @@
%-----------------------------------------------------------------------------%
-% Copyright (C) 1997, 2000 The University of Melbourne.
+% Copyright (C) 1997, 1999-2000 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.
%-----------------------------------------------------------------------------%
@@ -35,8 +35,8 @@
; bound(uniqueness, list(bound_inst))
% The list(bound_inst) must be sorted
; ground(uniqueness, ground_inst_info)
- % The pred_inst_info is used for
- % higher-order pred modes
+ % The ground_inst_info holds extra information
+ % about the ground inst.
; not_reached
; inst_var(inst_var)
% A defined_inst is possibly recursive
@@ -65,13 +65,18 @@
% on backtracking, so we will need to
% restore the old value on backtracking
+ % The ground_inst_info type gives extra information about ground insts.
:- type ground_inst_info
---> higher_order(pred_inst_info)
+ % The ground inst is higher-order.
; constrained_inst_var(inst_var)
+ % The ground inst is an inst variable that is
+ % constrained to be ground.
; none.
+ % No extra information is available.
% higher-order predicate terms are given the inst
- % `ground(shared, yes(PredInstInfo))'
+ % `ground(shared, higher_order(PredInstInfo))'
% where the PredInstInfo contains the extra modes and the determinism
% for the predicate. Note that the higher-order predicate term
% itself must be ground.
--
David Overton Department of Computer Science & Software Engineering
PhD Student The University of Melbourne, Australia
+61 3 8344 9159 http://www.cs.mu.oz.au/~dmo
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list