[m-dev.] for review: --dead-code

Zoltan Somogyi zs at cs.mu.OZ.AU
Fri Jul 21 08:47:11 AEST 2000


On 20-Jul-2000, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> This transformation is more like a static version of lazy evaluation.
> Perhaps `--semi-lazy-code'?

I don't like that name; in most ways this operation has nothing to do with
lazyness. How about --eliminate-redundancies? Or --redundant-code?

> One potential problem with this optimization as written is that it can
> increase code size, by duplicating the same goal in more than one
> branch.  It would be a good idea to have a version of it which only
> did the transformation if the code was used in at most one branch.
> This would be particularly appropriate in the case when `--opt-space'
> is enabled.

I can handle this by introducing a new integer option, perhaps called
--eliminate-redundancies-copy-limit, and not copying a goal to more places
than the value of this option.

> It might also be useful to have a version which only does the
> transformation if the code is used in zero branches, i.e. only does
> code elimination rather than moving code;

--eliminate-redundancies-copy-limit 0 would achieve this.

> that version could be
> allowed for the case where the user specifies `--no-fully-strict
> --no-reorder-conj', whereas the other versions would require
> both `--no-fully-strict' and `--reorder-conj'.

This can be done by having --no-reorder-conj implying
--eliminate-redundancies-copy-limit 0.

> (If there is some reason why the documentation should not be
> exposed to users yet, the documentation should still be added,
> commented out, together with an explanation of why it is commented out.)

The reason is the slowdown in tree234, as I said at the meeting.

> > +dead_code__process_proc_msg(PredId, ProcId, ProcInfo0, ProcInfo,
> > +		ModuleInfo0, ModuleInfo) -->
> > +	globals__io_lookup_bool_option(very_verbose, VeryVerbose),
> > +	globals__io_lookup_int_option(vn_fudge, Levels),
> 
> This undocumented `vn_fudge' option is very mysterious,
> and the use of it here (rather than in value numbering)
> is even more mysterious.

Sorry, that was left-over debugging code. I used it to find the reason for
infinite recursion, which was that replacing conj([]) with conj([]) does not
get strictly closer to the end of the documented well-founded order. I will
remove it.

> > +		( ReorderConj = yes
> > +		; FullyStrict = yes
> > +		)
> > +	->
> > +		MoveAny = no
> 
> Shouldn't you be checking `ReorderConj = no' there
> rather than `ReorderConj = yes'?

You are right.

> I don't think this is sufficient.
> Here you check that you don't move an impure goal across a pure goal.
> But doing the converse, i.e. moving a pure goal across an impure goal,
> is equally bad, and this test won't prevent that.

I have a proposed solution, which I will discuss with you in person.

> > +:- pred dead_code__cannot_diverge(hlds_goal::in) is semidet.
> 
> There's already a predicate code_aux__goal_cannot_loop
> which does the same thing as this one, so you should
> use that rather than duplicating the logic here.

Actually, code_aux__goal_cannot_loop was only documented to do the same
thing as dead_code__cannot_diverge, but its code did not check for
throwing exceptions. I have now added a new predicate, 
code_aux__goal_cannot_loop_or_throw, that does this check,
and deleted dead_code__cannot_diverge.

> goal_path.m:
> > +fill_expr_slots(switch(Var, B, Cases0, D), Path0, SlotInfo,
> > +		switch(Var, B, Cases, D)) :-
> > +	SlotInfo = slot_info(VarTypes, ModuleInfo),
> > +	module_info_types(ModuleInfo, TypeTable),
> > +	map__lookup(VarTypes, Var, Type),
> > +	(
> > +		type_to_type_id(Type, TypeId, _),
> > +		( map__search(TypeTable, TypeId, TypeDefn) ->
> > +			hlds_data__get_type_defn_body(TypeDefn, Body),
> > +			Body = du_type(_, ConsTable, _, _),
> > +			map__count(ConsTable, Count)
> > +		; TypeId = unqualified("character") - 0 ->
> > +			char__max_char_value(MaxCharValue),
> > +			char__min_char_value(MinCharValue),
> > +			Count = MaxCharValue - MinCharValue + 1
> > +		;
> > +			Count = -1
> > +		)
> 
> There should be an XXX comment here like the one in
> `switch_covers_all_cases' in switch_detection.m.  In fact a lot
> of the code here is doing the same thing as code in
> `switch_covers_all_cases'; it would be much better to factor out
> the common code into a separate subroutine, called e.g.
> `num_alternatives_in_type'.

I have factored out the common code into a new predicate
type_util__switch_type_num_functors.

> > +	proc_info_headvars(ProcInfo, HeadVars),
> > +	proc_info_argmodes(ProcInfo, ArgModes),
> > +	assoc_list__from_corresponding_lists(HeadVars, ArgModes, HeadVarModes),
> > +	IsInstChanged = lambda([VarMode::in, Var::out] is semidet, (
> > +		VarMode = Var - Mode,
> > +		mode_get_insts(ModuleInfo, Mode, Inst1, Inst2),
> > +		\+ inst_matches_binding(Inst1, Inst2, ModuleInfo)
> 
> ... since the implementation uses `inst_matches_binding',
> which ignores uniqueness, and which fails for `any' insts.

What is the correct test then?

Zoltan.
--------------------------------------------------------------------------
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