[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