[m-rev.] for review: fix bug with any insts in inst_merge
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Sep 14 02:50:53 AEST 2001
On 11-Sep-2001, David Overton <dmo at cs.mu.OZ.AU> wrote:
> Fix a bug in inst_merge when merging a ground inst with a bound inst
> containing 'any' insts. Previously,
>
> inst_merge(ground, bound(f(..., any, ...)))
>
> would return a result of 'any' which is not as accurate as we would
> like (e.g. this problem occurs often in Mercury code generated by the
> HAL compiler). To improve this, we pass the type of the variable
> being merged to inst_merge and when this situation arises we expand
> 'ground' to 'bound(<functors of type>)' and use this inst in the
> merge.
That looks fine.
Just a few minor comments:
> An alternative to passing the types through inst_merge would be to
> reinstate the use of 'typed_inst' and 'typed_ground' which are created
> by (currently commented out) code in 'propagate_types_into_insts'.
> However, this has previously been found to cause performance problems
> since it greatly expands the size of all insts and instmaps in the
> program. The approach used here is the same as that adopted for
> inst_matches_{initial,final} some time ago, where it does not appear
> to have a noticeable performance impact on typical programs.
>
> compiler/inst_util.m:
> Pass types through inst_merge and implement the changes to
> inst_merge(ground, bound(...)) described above.
>
> compiler/inst_match.m:
> compiler/instmap.m:
> compiler/mode_util.m:
> compiler/simplify.m:
> Pass types to calls to inst_merge.
>
> compiler/inst_match.m:
> compiler/type_util.m:
> Move 'maybe_get_cons_id_arg_types' and
> 'maybe_get_higher_order_arg_types' from inst_match.m to
> type_util.m and export them.
>
> compiler/mode_util.m:
> Export 'constructors_to_bound_insts'.
>
> tests/valid/Mmakefile:
> tests/valid/merge_ground_any.m :
> Add a regression test.
>
> tests/invalid/Mmakefile:
> tests/invalid/merge_ground_any.err_exp:
> tests/invalid/merge_ground_any.m:
> Add a test to make sure the ground inst is expanded out to the
> full set of functors for the type.
> Index: compiler/inst_match.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/inst_match.m,v
> retrieving revision 1.46
> diff -u -r1.46 inst_match.m
> --- compiler/inst_match.m 13 Oct 2000 13:55:28 -0000 1.46
> +++ compiler/inst_match.m 11 Sep 2001 00:25:08 -0000
> @@ -344,7 +344,7 @@
> bound_inst_list_is_ground(ListA, Info^module_info),
> bound_inst_list_matches_uniq(ListA, UniqB, Info^module_info).
> inst_matches_initial_3(bound(UniqA, ListA),
> - ground(UniqB, constrained_inst_var(InstVarB)), _,
> + ground(UniqB, constrained_inst_var(InstVarB)), MaybeType,
> Info0, Info) :-
> unique_matches_initial(UniqA, UniqB),
> ModuleInfo0 = Info0^module_info,
> @@ -358,7 +358,8 @@
> Live = dead,
> abstractly_unify_inst(Live, bound(UniqA, ListA), ground(UniqB, none),
> fake_unify, ModuleInfo0, Inst, _Det, ModuleInfo1),
> - update_inst_var_sub(InstVarB, Inst, ModuleInfo1, ModuleInfo, Sub0, Sub),
> + update_inst_var_sub(InstVarB, Inst, MaybeType, ModuleInfo1, ModuleInfo,
> + Sub0, Sub),
> Info = (Info0^module_info := ModuleInfo)
> ^sub := Sub.
> inst_matches_initial_3(bound(Uniq, List), abstract_inst(_,_), _, Info, Info) :-
> @@ -506,18 +507,19 @@
> % Update the inst_var_sub that is computed by inst_matches_initial.
> % The inst_var_sub records what inst should be substituted for each
> % inst_var that occurs in the called procedure's argument modes.
> -:- pred update_inst_var_sub(inst_var, inst, module_info, module_info,
> - maybe(inst_var_sub), maybe(inst_var_sub)).
> -:- mode update_inst_var_sub(in, in, in, out, in, out) is semidet.
> +:- pred update_inst_var_sub(inst_var, inst, maybe(type), module_info,
> + module_info, maybe(inst_var_sub), maybe(inst_var_sub)).
> +:- mode update_inst_var_sub(in, in, in, in, out, in, out) is semidet.
>
> -update_inst_var_sub(_, _, ModuleInfo, ModuleInfo, no, no).
> -update_inst_var_sub(InstVar, InstA, ModuleInfo0, ModuleInfo,
> +update_inst_var_sub(_, _, _, ModuleInfo, ModuleInfo, no, no).
> +update_inst_var_sub(InstVar, InstA, MaybeType, ModuleInfo0, ModuleInfo,
> yes(Sub0), yes(Sub)) :-
> ( map__search(Sub0, InstVar, InstB) ->
> % If InstVar already has an inst associated with it,
> % merge the old inst and the new inst. Fail if this merge
> % is not possible.
> - inst_merge(InstA, InstB, ModuleInfo0, Inst, ModuleInfo),
> + inst_merge(InstA, InstB, MaybeType, ModuleInfo0, Inst,
> + ModuleInfo),
> map__det_update(Sub0, InstVar, Inst, Sub)
> ;
> ModuleInfo = ModuleInfo0,
> @@ -534,15 +536,15 @@
>
> ground_inst_info_matches_initial(_, none, _, _) --> [].
> ground_inst_info_matches_initial(higher_order(PredInstA),
> - higher_order(PredInstB), _, Type) -->
> - pred_inst_matches_initial(PredInstA, PredInstB, Type).
> + higher_order(PredInstB), _, MaybeType) -->
> + pred_inst_matches_initial(PredInstA, PredInstB, MaybeType).
> ground_inst_info_matches_initial(GroundInstInfoA,
> - constrained_inst_var(InstVarB), UniqB, _) -->
> + constrained_inst_var(InstVarB), UniqB, MaybeType) -->
> { Inst = ground(UniqB, GroundInstInfoA) },
> ModuleInfo0 =^ module_info,
> Sub0 =^ sub,
> - { update_inst_var_sub(InstVarB, Inst, ModuleInfo0, ModuleInfo,
> - Sub0, Sub) },
> + { update_inst_var_sub(InstVarB, Inst, MaybeType, ModuleInfo0,
> + ModuleInfo, Sub0, Sub) },
> ^module_info := ModuleInfo,
> ^sub := Sub.
>
> @@ -719,56 +721,6 @@
> inst_list_matches_initial([X|Xs], [Y|Ys], [Type | Types]) -->
> inst_matches_initial_2(X, Y, Type),
> inst_list_matches_initial(Xs, Ys, Types).
> -
> - % If possible, get the argument types for the cons_id.
> - % We need to pass in the arity rather than using the arity
> - % from the cons_id because the arity in the cons_id will not
> - % include any extra type_info arguments for existentially
> - % quantified types.
> -:- pred maybe_get_cons_id_arg_types(module_info, maybe(type), cons_id,
> - arity, list(maybe(type))).
> -:- mode maybe_get_cons_id_arg_types(in, in, in, in, out) is det.
> -
> -maybe_get_cons_id_arg_types(ModuleInfo, MaybeType, ConsId0, Arity, MaybeTypes)
> - :-
> - ( ConsId0 = cons(SymName, _) ->
> - ( SymName = qualified(_, Name) ->
> - % get_cons_id_non_existential_arg_types
> - % expects an unqualified cons_id.
> - ConsId = cons(unqualified(Name), Arity)
> - ;
> - ConsId = ConsId0
> - ),
> - (
> - MaybeType = yes(Type),
> -
> - % XXX get_cons_id_non_existential_arg_types will fail
> - % for ConsIds with existentially typed arguments.
> - get_cons_id_non_existential_arg_types(ModuleInfo, Type,
> - ConsId, Types),
> - list__length(Types, Arity)
> - ->
> - list__map(pred(T::in, yes(T)::out) is det, Types,
> - MaybeTypes)
> - ;
> - list__duplicate(Arity, no, MaybeTypes)
> - )
> - ;
> - MaybeTypes = []
> - ).
> -
> -:- pred maybe_get_higher_order_arg_types(maybe(type), arity, list(maybe(type))).
> -:- mode maybe_get_higher_order_arg_types(in, in, out) is det.
> -
> -maybe_get_higher_order_arg_types(MaybeType, Arity, MaybeTypes) :-
> - (
> - MaybeType = yes(Type),
> - type_is_higher_order(Type, _, _, Types)
> - ->
> - list__map(pred(T::in, yes(T)::out) is det, Types, MaybeTypes)
> - ;
> - list__duplicate(Arity, no, MaybeTypes)
> - ).
>
> %-----------------------------------------------------------------------------%
>
> Index: compiler/inst_util.m
> @@ -1425,9 +1419,12 @@
> ),
> merge_uniq(UniqA, UniqB, Uniq).
> inst_merge_3(abstract_inst(Name, ArgsA), abstract_inst(Name, ArgsB),
> - ModuleInfo0, abstract_inst(Name, Args), ModuleInfo) :-
> - inst_list_merge(ArgsA, ArgsB, ModuleInfo0, Args, ModuleInfo).
> -inst_merge_3(not_reached, Inst, M, Inst, M).
> + _, ModuleInfo0, abstract_inst(Name, Args), ModuleInfo) :-
> + MaybeTypes = list__duplicate(list__length(ArgsA), no),
> + % We don't know the arguments types of an abstract inst.
The comment here should precede the code to which it applies,
rather than following it.
> Index: compiler/type_util.m
...
> + ->
> + list__map(pred(T::in, yes(T)::out) is det, Types,
> + MaybeTypes)
I'd write that using the functional form:
MaybeTypes = list__map(func(T) = yes(T), Types)
> +maybe_get_higher_order_arg_types(MaybeType, Arity, MaybeTypes) :-
> + (
> + MaybeType = yes(Type),
> + type_is_higher_order(Type, _, _, Types)
> + ->
> + list__map(pred(T::in, yes(T)::out) is det, Types, MaybeTypes)
> + ;
> + list__duplicate(Arity, no, MaybeTypes)
Likewise here.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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