[m-rev.] for review: build HLDS by item kind
Julien Fischer
jfischer at opturion.com
Thu Oct 29 14:38:28 AEDT 2015
Hi Zoltan,
On Thu, 29 Oct 2015, Zoltan Somogyi wrote:
> scripts/mtags.in
Delete that.
> Add items to the HLDS by kinds, not in passes.
>
> There are several reasons for this change.
>
> First, it is more flexible than the previous arrangement of adding items
> to the HLDS in three passes. Since adding a fourth pass would have had
> significant performance implications, we refrained from making changes
> that would have required a fourth pass in a pass-based algorithm.
> With the new structure, such changes do not lead to any detectable slowdown,
> so there is no reason why we should avoid making them.
>
> In fact, the immediate motivation for this diff is to make such a change.
> This is a fix for Mantis bug 318, which requires adding abstract and/or
> non-foreign definitions for types because foreign definitions for those types
> *regardless* of their relative order in the source code.
That last sentence doesn't make sense.
> This diff also has the side effect that e.g. the mode declarations for
> a predicate don't have to follow the declaration of the (type of) the predicate
> itself. Pred and mode declarations used to be processed in the same pass,
> but now, all pred declaration are processed before all mode declarations.
>
> Second, as identified earlier, the new structure is conceptually cleaner than
> the old one, and the constraints on when different kinds of items have to be
> added to the HLDS can documented next to the code that does the adding,
> since that code is no longer mixed with code that adds other kinds of items
> at the same time.
>
> Third, the code we used to use to detect invalid type definitions
> was only a crude approximation. With the new setup, it is trivial to use
> an exact computation. We now proceed to later compiler passes in many cases
> that previously led us to stop before type checking because we (erroneously)
> believed that the program had an invalid type definition.
>
> Fourth, my benchmarking shows a speedup on tools/speedtest -l -m of about
> 1.2% to 1.5%. The new approach does allocate a bit more memory (a pair
> and a cons cell per item), but it traverses most items just once, not
> three times. A few kinds of items (e.g. pred declarations) do have to be
> processed more than once, e.g. both before and after some other kinds
> of items are added to the HLDS, but four of the five most frequently items
s/frequently/frequent/
> in bootchecks (the pragmas recording the results of the termination and
> exception analyses, mode declarations, and clauses) are processed just once.
> Evidently, the speedup from traversing fewer items, and avoiding the
> switches on item kinds that those traversals involve, is greater than
> the extra cost of the additional memory allocations, including their effect
> on garbage collectin times.
s/collectin/collection/
...
> compiler/check_typeclass.m:
> Improve an error message. We now get this error message even for modules
> on which the compiler previously stopped before getting to typechecking.
>
> compiler/modes.m:
> compiler/prog_item_stats.m:
The description of the changes to these files is missing.
...
> diff --git a/compiler/add_pragma.m b/compiler/add_pragma.m
> index e871b09..1c23133 100644
> --- a/compiler/add_pragma.m
> +++ b/compiler/add_pragma.m
> @@ -20,13 +20,59 @@
>
> %-----------------------------------------------------------------------------%
>
> -:- pred add_pass_2_pragma(item_pragma_info::in,
> - item_mercury_status::in, module_info::in, module_info::out,
> +:- inst item_pragma_info(I) for item_pragma_info/0
> + ---> item_pragma_info(I, ground, ground, ground).
> +
> +:- inst pragma_pass_2 for pragma_type/0
If you are going to start using typed insts in the compiler, then you should
update the configure script's up-to-date check to ensure that they are supported
by a bootstrap compiler.
...
> diff --git a/compiler/add_type.m b/compiler/add_type.m
> index 3fe91aa..a239524 100644
> --- a/compiler/add_type.m
> +++ b/compiler/add_type.m
> @@ -439,6 +439,17 @@ process_type_defn(TypeCtor, TypeDefn, !FoundInvalidType, !ModuleInfo,
> ),
> (
> !.FoundInvalidType = found_invalid_type
> + % If there is an error in this type definition, we may not
> + % be able to add the special speds for it correctly.
s/speds/preds/
> + % Even errors occurred only in other types, adding the special
s/Even errors/Even if the errors/
> + % predicates for this error-free type wouldn't help us, because
> + % the presence of an invalid type anywhere will prevent the compiler
> + % from going on to process those special predicates. It won't even
> + % look at them to find errors, such as user-defined unify and compare
> + % predicates being not found or having the wrong signature.
> + % XXX If this ever changes, we *should* add the special preds
> + % for error-free type definitions regardless of the presence
> + % of any previous type errors.
> ;
> !.FoundInvalidType = did_not_find_invalid_type,
> % XXX kind inference:
...
> diff --git a/compiler/make_hlds_passes.m b/compiler/make_hlds_passes.m
> index f5fcf50..3c2d91e 100644
> --- a/compiler/make_hlds_passes.m
> +++ b/compiler/make_hlds_passes.m
...
> + % The second part of the old pass 1.
> +
> + % We process inst definitions after all type definitions because
> + % the processing of type-specific insts may require access to the
> + % definition of any type constructor.
> + list.foldl3(add_inst_defn, ItemInstDefns,
> + !ModuleInfo, !FoundInvalidInstOrMode, !Specs),
> +
> + % Mode definitions may refer to user defined insts. We don't yet
> + % exploit the availability of all inst definitions when we process
> + % a mode definition, but in the future, we could.
> + list.foldl3(add_mode_defn, ItemModeDefns,
> + !ModuleInfo, !FoundInvalidInstOrMode, !Specs),
> +
> + % A predicate declaration defines the type of the arguments of a predicate,
> + % and may give the modes of those arguments. We don't yet exploit
> + % the availability of all type and mode definitions when we process
> + % a pred declaration (e.g. for error checking), but in the future,
> + % we could.
> + list.foldl2(add_pred_decl, ItemPredDecls,
> + !ModuleInfo, !Specs),
> +
> + % We need to process the mode declaration of a predicate
> + % after we have seen the (type) declaration of the predicate.
> + % In the past, this required the predicate declaration to precede
> + % the mode declaration in the source code.
> + list.foldl2(add_mode_decl, ItemModeDecls,
> + !ModuleInfo, !Specs),
> + list.foldl2(add_solver_type_aux_pred_decls, SolverAuxPredInfos,
> + !ModuleInfo, !Specs),
> +
> + % Every mutable has its own set of access predicates. Declare them,
> + % whether the mutable definition was a standalone item or part of
> + % the definition of a solver type.
> + list.foldl2(add_aux_pred_decls_for_mutable_if_local, ItemMutables,
> + !ModuleInfo, !Specs),
> + list.foldl2(add_aux_pred_decls_for_mutable_if_local, SolverItemMutables,
> + !ModuleInfo, !Specs),
> +
> + % Record typeclass definitions.
> + list.foldl2(add_typeclass_defn, ItemTypeclasses,
> + !ModuleInfo, !Specs),
> +
> + % The old pass 2.
> +
> + % Now that we have processed all mode declarations, we have a reliable
> + % record of which declarated predicates and functions have NO mode
s/declarated/declared/
> + % declaration. For functions, this is not an error, since Mercury
> + % specifies a implicit mode declaration for them. maybe_add_default_mode
> + % add that implicit mode declaration.
> + % XXX It should also generat error messages for PREDICATES that have
s/generat/generate/
The change looks fine otherwise.
Julien.
More information about the reviews
mailing list