[m-rev.] for review: better lookup switches

Julien Fischer juliensf at cs.mu.OZ.AU
Wed Mar 29 16:13:00 AEDT 2006


On Wed, 29 Mar 2006, Zoltan Somogyi wrote:

> Implement a more cache-friendly translation of lookup switches. Previously,
> for a switch such as the one in
>
> 	:- pred p(foo::in, string::out, bar::out, float::out) is semidet.
>
> 	p(d, "four", f1, 4.4).
> 	p(e, "five", f2, 5.5).
> 	p(f, "six", f4("hex"), 6.6).
> 	p(g, "seven", f5(77.7), 7.7).
>
> we generated three static cells, one for each argument, and then indexed
> into each one in turn to get the values of HeadVar__2, HeadVar__3 and
> HeadVar__4. The different static cells each represent a column here.
> Each of the loads accessing the columns will access a different cache block,
> so with this technique we expect to get as many cache misses as there are
> output variables.
>
> This diff changes the code we generate to use a vector of static cells
> where each cell represents a row. The assignments to the output variables
> will now access the different fields of a row, which will be next to each
> other. We thus expect only one cache miss irrespective of the number of output
> variables, at least up to the number of variables that actually fit into one
> cache block.
>
> compiler/global_data.m:
> 	Provide a mechanism for creating not just single (scalar) static cells,
> 	but arrays (vectors) of them.
>
> compiler/lookup_switch.m:
> 	Use the new mechanism to generate code along the lines described above.
>
> 	Put the information passed between the two halves of the lookup switch
> 	implementation (detection and code generation) into an opaque data
> 	structure.
>
> compiler/switch_gen.m:
> 	Conform to the new interface of lookup_switch.m.
>
> compiler/ll_pseudo_type_info.m:
> compiler/stack_layout.m:
> compiler/string_switch.m:
> compiler/unify_gen.m:
> compiler/var_locn.m:
> 	Conform to the change to global_data.m.
>
> compiler/llds.m:
> 	Define the data structures for holding vectors of static cells. Rename
> 	the function symbols we used to use to refer to static cells to make
> 	clear that they apply to scalar cells only. Provide similar mechanisms
> 	for representing static cell vectors and references to them.
>
> 	Generalize heap_ref heap references to allow the index to be computed
> 	at runtime, not compile time. For symmetry's sake, do likewise
> 	for stack references.
>
> compiler/llds_out.m:
> 	Add the code required to write out static cell vectors.
>
> 	Rename decl_ids to increase clarity and avoid ambiguity.
>
> compiler/code_util.m:
> compiler/exprn_aux.m:
> 	Modify code that traverses rvals to now also traverse the new rvals
> 	inside memory references.
>
> compiler/name_mangle.m:
> 	Provide the prefix for static cell vectors.
>
> compiler/layout_out.m:
> compiler/rtti_out.m:
> compiler/opt_debug.m:
> 	Conform to the change to data_addrs and decl_ids.
>
> compiler/code_info.m:
> 	Provide access to the new functionality in global_data.m, and conform
> 	to the change to llds.m.
>
> 	Provide a utility predicate needed by lookup_switch.m.
>
> compiler/hlds_llds.m:
> 	Fix the formatting of some comments.
>
> tests/hard_coded/dense_lookup_switch2.{m,exp}:
> tests/hard_coded/dense_lookup_switch3.{m,exp}:
> 	New test cases to exercise the new algorithm.
>
> tests/hard_coded/Mmakefile:
> 	Enable the new test cases, as well as an old one (from 1997!)
> 	that seems never to have been enabled.
>

You've modified some scripts in the tools directory as well, but this
isn't mentioned in the log message (presumambly it's just indentation
changes?).

...

> Index: compiler/global_data.m
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/compiler/global_data.m,v
> retrieving revision 1.15
> diff -u -b -r1.15 global_data.m
> --- compiler/global_data.m	21 Mar 2006 02:33:34 -0000	1.15
> +++ compiler/global_data.m	27 Mar 2006 15:02:30 -0000

...

> @@ -295,12 +337,210 @@
>                  % be useful when comparing the LLDS and MLDS backends.
>              ),
>              map.set(CellGroupMap0, TypeNum, !.CellGroup, CellGroupMap),
> -            !:Info = !.Info ^ cell_group_map := CellGroupMap
> +            !:Info = !.Info ^ scalar_cell_group_map := CellGroupMap
>          )
>      ),
>      ModuleName = !.Info ^ sub_info ^ module_name,
>      DataAddr = data_addr(ModuleName, DataName).
>
> +:- func init_scalar_cell_group = scalar_cell_group.
> +
> +init_scalar_cell_group = scalar_cell_group(counter.init(0), bimap.init, []).
> +
> +search_scalar_static_cell_offset(Info, DataAddr, Offset, Rval) :-
> +    DataAddr = data_addr(Info ^ sub_info ^ module_name, DataName),
> +    DataName = scalar_common_ref(TypeNum, _CellNum),
> +    CellGroupMap = Info ^ scalar_cell_group_map,
> +    map.lookup(CellGroupMap, TypeNum, CellGroup),
> +    CellGroupMembers = CellGroup ^ scalar_cell_group_members,
> +    bimap.reverse_lookup(CellGroupMembers, Rvals, DataName),
> +    list.index0_det(Rvals, Offset, Rval).
> +
> +%-----------------------------------------------------------------------------%
> +
> +find_general_llds_types(UnboxFloat, Types, [Vector | Vectors], LLDSTypes) :-
> +    list.map(natural_type(UnboxFloat), Vector, LLDSTypes0),
> +    find_general_llds_types_2(UnboxFloat, Types, Vectors,
> +        LLDSTypes0, LLDSTypes).
> +
> +:- pred find_general_llds_types_2(bool::in, list(mer_type)::in,
> +    list(list(rval))::in, list(llds_type)::in, list(llds_type)::out)
> +    is semidet.
> +
> +find_general_llds_types_2(_UnboxFloat, _Types, [], !LLDSTypes).
> +find_general_llds_types_2(UnboxFloat, Types, [Vector | Vectors], !LLDSTypes) :-
> +    find_general_llds_types_in_cell(UnboxFloat, Types, Vector, !LLDSTypes),
> +    find_general_llds_types_2(UnboxFloat, Types, Vectors, !LLDSTypes).
> +
> +:- pred find_general_llds_types_in_cell(bool::in, list(mer_type)::in,
> +    list(rval)::in, list(llds_type)::in, list(llds_type)::out) is semidet.
> +
> +find_general_llds_types_in_cell(_UnboxFloat, [], [], [], []).
> +find_general_llds_types_in_cell(UnboxFloat, [_Type | Types], [Rval | Rvals],
> +        [LLDSType0 | LLDSTypes0], [LLDSType | LLDSTypes]) :-
> +    natural_type(UnboxFloat, Rval, NaturalType),
> +    % For user-defined types, some function symbols may be constants
> +    % (whose representations yield integer rvals) while others may be
> +    % non-constants (whose representations yield data_ptr rvals).
> +    % We need to be able to handle switches in which a variable of such a type
> +    % has a value of one kind in one switch arm and a value of the other kind
> +    % in another switch arm. We can mix the two because it is OK to initialize
> +    % a field declared to be a data_ptr with an integer rval.
> +    %
> +    % If there are any other similar cases, they should be added here.
> +    % The value of Type may be useful in such code.
> +    (
> +        NaturalType = LLDSType0
> +    ->
> +        LLDSType = LLDSType0
> +    ;
> +        NaturalType = integer,
> +        LLDSType0 = data_ptr
> +    ->
> +        LLDSType = data_ptr
> +    ;
> +        NaturalType = data_ptr,
> +        LLDSType0 = integer
> +    ->
> +        LLDSType = data_ptr
> +    ;
> +        fail
> +    ),
> +    find_general_llds_types_in_cell(UnboxFloat, Types, Rvals,
> +        LLDSTypes0, LLDSTypes).
> +
> +%-----------------------------------------------------------------------------%
> +
> +add_vector_static_cell(LLDSTypes, VectorData, DataAddr, !Info) :-
> +    require(list.is_not_empty(LLDSTypes), "add_vector_static_cell: no types"),
> +    require(list.is_not_empty(VectorData), "add_vector_static_cell: no data"),

Use expect/3 instead of require/2 there.

I've had a quick look at the rest and it all seems okay.

Julien.


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