[m-dev.] for review: MLDS switch simplification
Peter Ross
peter.ross at miscrit.be
Tue Nov 21 21:14:34 AEDT 2000
On Sat, Nov 18, 2000 at 12:36:00AM +1100, Fergus Henderson wrote:
> Estimated hours taken: 12
>
> Add an MLDS to MLDS transformation that converts MLDS switches
> into computed gotos or if-then-else chains. (Eventually we
> should make this code also handle binary searches.)
>
> This transformation should allow tag switch optimization to work for
> the IL back-end. It also replaces ml_dense_switch.m and lets us
> simplify ml_string_switch.m.
>
> compiler/mlds.m:
> Add a new `switch_range' field to the `switch' stmt.
>
> compiler/ml_simplify_switch.m:
> The new transformation. This converts MLDS switches into
> computed gotos or if-then-else chains.
> It uses the new `switch_range' field to determine how big
> it would need to make the jump table to cover all cases.
>
> compiler/ml_switch_gen.m:
> compiler/ml_string_switch.m:
> compiler/ml_tag_switch.m:
> compiler/ml_dense_switch.m:
> Generate the new field.
> Change the places that generate switches so that after
> generating the switch they invoke the new transformation.
> Delete ml_dense_switch.m, since it is now redundant,
> and significantly simplify ml_string_switch.m.
>
> compiler/ml_elim_nested.m:
> compiler/ml_optimize.m:
> compiler/ml_tailcall.m:
> compiler/ml_util.m:
> compiler/mlds_to_c.m:
> compiler/mlds_to_il.m:
> Trivial changes to handle the new field.
>
> compiler/switch_util.m:
> compiler/dense_switch.m:
> Move most of the code from the `type_range' procedure from
> dense_switch.m to switch_util.m, so we can use it in
> ml_switch_gen.m for computing the switch range.
>
Apart from the two minor issues this change looks fine.
> Workspace: /home/pgrad/fjh/ws/hg
> Index: compiler/ml_simplify_switch.m
> ===================================================================
> RCS file: ml_simplify_switch.m
> diff -N ml_simplify_switch.m
> --- /dev/null Thu Mar 30 14:06:13 2000
> +++ ml_simplify_switch.m Sat Nov 18 00:02:08 2000
> +
> +:- pred maybe_eliminate_default(mlds__switch_range::in,
> + list(mlds__switch_case)::in, mlds__switch_default::in, int::in,
> + int::out, int::out, bool::out) is det.
> +
> +maybe_eliminate_default(Range, Cases, Default, ReqDensity,
> + FirstVal, LastVal, NeedRangeCheck) :-
> + % For switches with a default, we normally need to check that
> + % the variable is in range before we index into the jump table.
> + % However, if the range of the type is sufficiently small,
> + % we can make the jump table large enough to hold all
> + % of the values for the type.
I would prefer this documentation to go above the pred declaration.
> + (
> + Default \= default_is_unreachable,
> + Range = range(Min, Max),
> + TypeRange = Max - Min + 1,
> + NumCases = list__length(Cases),
> + NoDefaultDensity = calc_density(NumCases, TypeRange),
> + NoDefaultDensity > ReqDensity
> + ->
> + NeedRangeCheck = no,
> + FirstVal = Min,
> + LastVal = Max
> + ;
> + ( Default = default_is_unreachable ->
> + NeedRangeCheck = no
> + ;
> + NeedRangeCheck = yes
> + ),
> + find_first_and_last_case(Cases, FirstCaseVal, LastCaseVal),
> + FirstVal = FirstCaseVal,
> + LastVal = LastCaseVal
> + ).
> +
> +
> + % Generate an rval which will be true iff any of the specified
> + % list of case conditions matches the specified rval.
> +:- func ml_gen_case_match_conds(mlds__case_match_conds, rval) = rval.
> +ml_gen_case_match_conds([], _) = const(false).
> +ml_gen_case_match_conds([Cond], SwitchRval) =
> + ml_gen_case_match_cond(Cond, SwitchRval).
> +ml_gen_case_match_conds([Cond1, Cond2 | Conds], SwitchRval) =
> + binop(or,
> + ml_gen_case_match_cond(Cond1, SwitchRval),
> + ml_gen_case_match_conds([Cond2 | Conds], SwitchRval)).
> +
> + % Generate an rval which will be true iff the specified
> + % case condition matches the specified rval.
> +:- func ml_gen_case_match_cond(mlds__case_match_cond, rval) = rval.
> +ml_gen_case_match_cond(match_value(CaseRval), SwitchRval) =
> + % XXX is `eq' the right operator to use here?
I don't understand this XXX.
What other operator could you be using?
> + binop(eq, CaseRval, SwitchRval).
> +ml_gen_case_match_cond(match_range(MinRval, MaxRval), SwitchRval) =
> + binop(and, binop(>=, SwitchRval, MinRval),
> + binop(<=, SwitchRval, MaxRval)).
> +
> +%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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