[m-rev.] for review: prevent unnecessary recompilations.

Julien Fischer juliensf at cs.mu.OZ.AU
Thu Feb 24 00:06:23 AEDT 2005


On Mon, 21 Feb 2005, Zoltan Somogyi wrote:

> compiler/modules.m:
> 	Reduce the number of unnecessary recompilations by changing the way
> 	we compute the contents of .int and (especially) .int2 files.
> 	Previously, even after Julien's recent change, these files contained
> 	abstract declarations for the types local to the implementation section
> 	of the module concerned. This meant that adding or deleting such
> 	a file caused the recompilation of all the modules that depended
> 	on its .int2 file, which in the case of the compiler is pretty much
> 	everything.
>
> 	We now include an abstract declaration of a type in the implementation
> 	section of a .int{,2} file only if the type constructor occurs on the
> 	right hand side of a type definition in which the type constructor
> 	on the left hand side is (a) abstract exported, (b) it has an
> 	equivalent type or foreign type definition in the implementation
> 	section.
>
> 	If we do have to include any information from the implementation
> 	section of a module in a .int or .int2, sort the items involved,
> 	to prevent reshuffles of these items in the source code from causing
> 	avalanche recompilations.
>
> 	This diff reduces the number of lines in the .int and .int2 files
> 	in the compiler by about 10%.
>

...

>          IntItems = [make_pseudo_decl(interface) | IntItems0],
>
> -        maybe_strip_import_decls(ImplItems1, ImplItems2),
> -        strip_unnecessary_impl_imports(NecessaryImplImports, ImplItems2,
> -            ImplItems3),
> -
> +        maybe_strip_import_decls(!ImplItems),
> +        strip_unnecessary_impl_imports(NecessaryImplImports, !ImplItems),
> +        strip_unnecessary_impl_types(NecessaryTypeCtors, !ImplItems),
>          (
> -            ImplItems3 = [],
> +            !.ImplItems = [],
>              Items = IntItems
>          ;
> -            ImplItems3 = [_ | _],
> -            Items = IntItems ++ [make_pseudo_decl(implementation) | ImplItems3]
> +            !.ImplItems = [_ | _],
> +            standardize_impl_items(!.ImplItems, no, Unexpected,
> +                [], RevRemainderItems, [], ImportItems, [], UseItems,
> +                [], TypeDefnItems),
> +            (
> +                Unexpected = yes,
> +                error("strip_unnecessary_impl_defns_2: " ++
> +                    "unexpected items in implementation section")
> +                % If the above exception is thrown and you need a workaround
> +                % you can replace the exception with this code:
> +                % Items = IntItems ++ [make_pseudo_decl(implementation)]
> +                %    ++ !.ImplItems
I think that throwing an exception here is correct.  I'd put an XXX in
front of the comment if you want to leave it in.

...

> +standardize_impl_items([], !Unexpected, !RevRemainderItems,
> +        !ImportItems, !UseItems, !TypeDefnItems).
> +standardize_impl_items([ItemAndContext | ItemAndContexts], !Unexpected,
> +        !RevRemainderItems, !ImportItems, !UseItems, !TypeDefnItems) :-
> +    ItemAndContext = Item - Context,
> +    ( Item = module_defn(_VarSet, ModuleDefn) ->
> +        (
> +            ModuleDefn = import(ImportModules),
> +            ( ImportModules = module([_ImportModule]) ->
> +                insert_import_module(Context, Item, !ImportItems)
> +            ;
> +                error("standardize_impl_items: non-singleton-module import")
Our coding standard says to use unexpected/2 in the compiler in
preference to error/1. (and eleswhere in a few spots).

> +            )
> +        ;
> +            ModuleDefn = use(UseModules),
> +            ( UseModules = module([_UseModule]) ->
> +                insert_use_module(Context, Item, !UseItems)
> +            ;
> +                error("standardize_impl_items: non-singleton-module use")
> +            )
> +        ;
> +            ModuleDefn = module(_),
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = end_module(_),
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = imported(_),
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = used(_),
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = abstract_imported,
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = opt_imported,
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = transitively_imported,
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = external(_),
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = export(_),
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = include_module(_),
> +            !:RevRemainderItems = [ItemAndContext | !.RevRemainderItems]
> +        ;
> +            ModuleDefn = interface,
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = implementation,
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = private_interface,
> +            !:Unexpected = yes
> +        ;
> +            ModuleDefn = version_numbers(_, _),
> +            !:Unexpected = yes
> +        )
> +    ; Item = type_defn(_, _, _, _, _) ->
> +        insert_type_defn(Context, Item, !TypeDefnItems)
> +    ;
> +        !:RevRemainderItems = [ItemAndContext | !.RevRemainderItems]
> +    ),
> +    standardize_impl_items(ItemAndContexts, !Unexpected,
> +        !RevRemainderItems, !ImportItems, !UseItems, !TypeDefnItems).
> +

...

> -:- pred accumulate_eqv_type_rhs(pair(type_defn, item_and_context)::in,
> -    list(type)::in, list(type)::out) is det.
> +:- pred accumulate_abs_eqv_type_rhs(set(type_ctor)::in,
> +    pair(type_ctor, pair(type_defn, item_and_context))::in,
> +    set(type)::in, set(type)::out) is det.
>
> -accumulate_eqv_type_rhs(TypeDefn - _ItemContext, !Equivs) :-
> -    ( TypeDefn = eqv_type(Type) ->
> -        list.cons(Type, !Equivs)
> +accumulate_abs_eqv_type_rhs(AbsEqvLhsTypeCtors,
> +        TypeCtor - (TypeDefn - _ItemAndContext), !AbsEqvRhsTypes) :-
> +    (
> +        TypeDefn = eqv_type(RhsType),
> +        set.member(TypeCtor, AbsEqvLhsTypeCtors)
> +    ->
> +        svset.insert(RhsType, !AbsEqvRhsTypes)
>      ;
>          true
>      ).
>
> -    % Given a list of types, return the set of modules that define these types.
> +    % Given a list of types, return the set of user-defined type constructors
> +    % occuring those types, and the set of modules that define these type
s/occuring those types/occurring in those types/

...

> -:- pred get_modules_from_types(list(type)::in,
> +:- pred get_user_type_ctors_and_modules_from_types(set(type)::in,
> +    set(type_ctor)::in, set(type_ctor)::out,
>      set(module_name)::in, set(module_name)::out) is det.
>
> -get_modules_from_types(Types, !Modules) :-
> -    list.foldl(get_modules_from_type, Types, !Modules).
> +get_user_type_ctors_and_modules_from_types(Types, !TypeCtors, !Modules) :-
> +    list.foldl2(get_user_type_ctors_and_modules_from_type,
> +        set__to_sorted_list(Types), !TypeCtors, !Modules).
>
> -:- pred get_modules_from_type((type)::in,
> +:- pred get_user_type_ctors_and_modules_from_type((type)::in,
> +    set(type_ctor)::in, set(type_ctor)::out,
>      set(module_name)::in, set(module_name)::out) is det.
>
> -get_modules_from_type(Type, !Modules) :-
> +get_user_type_ctors_and_modules_from_type(Type, !TypeCtors, !Modules) :-
>      ( type_to_ctor_and_args(Type, TypeCtor, Args) ->
>          TypeCtor = SymName - _Arity,
> -        ( sym_name_get_module_name(SymName, ModuleName) ->
> -            svset.insert(ModuleName, !Modules),
> -            get_modules_from_types(Args, !Modules)
> -        ;
>              (
> -                type_ctor_is_higher_order(TypeCtor, _, _, _ )
> +            type_ctor_is_higher_order(TypeCtor, _, _, _)
>              ->
The indentation needs fixing here (assuming that it's not CVS or
my mail reader ;-) )

> -                % Higher-order types are builtin so just get
> -                % the modules required by the arguments.
> -                get_modules_from_types(Args, !Modules)
> +            % Higher-order types are builtin so just get the type_ctors and
> +            % modules required by the arguments.
> +            list.foldl2(get_user_type_ctors_and_modules_from_type, Args,
> +                !TypeCtors, !Modules)
>              ;
>                  type_ctor_is_tuple(TypeCtor)
>              ->
> -                % Tuples are builtin so just get the modules
> +            % Tuples are builtin so just get the type_ctors and modules
>                  % required by the arguments.
Likewise here.

That looks okay otherwise.

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