[m-rev.] for review: Implement unify/compare of tuples in Mercury.
Julien Fischer
jfischer at opturion.com
Tue Jul 8 16:26:41 AEST 2014
On Mon, 7 Jul 2014, Peter Wang wrote:
> Branches: master
>
> The hand-written C unify and compare predicates for tuples did not preserve
> deep profiler invariants correctly across the recursive unify/compare of
> tuple arguments. I tried to do so, and failed. Instead, implement the
> predicates in Mercury so the compiler can perform the deep profiling
> transformation on them. Bug #3.
>
> A micro-benchmark on my machine is about twice as fast in asm_fast.gc
> after this patch, and equally fast in hlc.gc. The change to the
> high-level C backend is only to reduce code duplication.
I doubt there is much performance critical code about that uses tuples
anyway.
> I seem to have hit an unrelated bug in compare_representation so I did
> not implement the compare_representation predicate for tuples yet.
>
> library/builtin.m:
> Add `unify_tuple' and `compare_tuple' predicates.
>
> Add module initialisation predicate which sets
> `MR_special_pred_hooks' to point to those predicates.
>
> Delete unused predicates `call_rtti_generic_unify',
> `call_rtti_generic_compare'.
>
> runtime/mercury_ho_call.c:
> runtime/mercury_ho_call.h:
> Add a global variable `MR_special_pred_hooks' for the library to
> set up during initialisation.
>
> Add `tailcall' macros for use by `mercury_unify_compare_body.h'.
> Rename `tailcall_user_pred' to `tailcall_tci_pred'.
>
> Call the new unify/compare predicates in the high-level C
> backend via `MR_special_pred_hooks'.
>
> Delete `unify_tuples' and `compare_tuples' for the high-level C
> and call the Mercury predicates set in `MR_special_pred_hooks'.
>
> runtime/mercury_unify_compare_body.h:
> Delete the unify and compare code for tuples in the low-level C
> backend. Jump to the Mercury predicates set in
> `MR_special_pred_hooks' instead.
>
> Add some comments.
>
> tests/hard_coded/Mmakefile:
> tests/hard_coded/tuple_test2.exp
> tests/hard_coded/tuple_test2.m:
> Add test case.
>
> NEWS:
> Announce the change.
> ---
> NEWS | 3 +
> library/builtin.m | 120 ++++++++++++++++++++++++++++++---
> runtime/mercury_ho_call.c | 125 +++++++++++++++--------------------
> runtime/mercury_ho_call.h | 20 ++++++
> runtime/mercury_unify_compare_body.h | 66 ++++++++----------
> tests/hard_coded/Mmakefile | 1 +
> tests/hard_coded/tuple_test2.exp | 11 +++
> tests/hard_coded/tuple_test2.m | 66 ++++++++++++++++++
> 8 files changed, 294 insertions(+), 118 deletions(-)
> create mode 100644 tests/hard_coded/tuple_test2.exp
> create mode 100644 tests/hard_coded/tuple_test2.m
>
> diff --git a/NEWS b/NEWS
> index 4c0a461..a6f5798 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -29,6 +29,9 @@ Changes to the Mercury standard library:
>
> Changes to the Mercury compiler:
>
> +* We have fixed a long-standing bug causing crashes in deep profiling
> + grades, related to unify/compare of tuples. (Bug #3)
s/of tuples/for tuples/
> diff --git a/runtime/mercury_ho_call.c b/runtime/mercury_ho_call.c
> index f528925..3598e8f 100644
> --- a/runtime/mercury_ho_call.c
> +++ b/runtime/mercury_ho_call.c
...
> @@ -163,7 +117,10 @@ mercury__builtin__unify_2_p_0(MR_Mercury_Type_Info ti, MR_Box x, MR_Box y)
> */
> type_ctor_rep = MR_type_ctor_rep(type_ctor_info);
> if (type_ctor_rep == MR_TYPECTOR_REP_TUPLE) {
> - return unify_tuples(ti, (MR_Tuple) x, (MR_Tuple) y);
> + if (MR_special_pred_hooks.MR_unify_tuple_pred != NULL) {
> + return MR_special_pred_hooks.MR_unify_tuple_pred(ti,
> + (MR_Word) x, (MR_Word) y);
> + }
So, if it is NULL we fall through and eventually call MR_fatal_error,
right?
...
> --- a/runtime/mercury_ho_call.h
> +++ b/runtime/mercury_ho_call.h
> @@ -194,4 +194,24 @@ MR_declare_entry(mercury__builtin__compare_representation_3_0);
>
> #endif /* MR_HIGHLEVEL_CODE */
>
> +/*
> +** Special predicates implemented in the standard library
> +**
> +** The library sets the fields in this structure to the actual
> +** implementations of the predicates during initialization.
> +*/
Add a pointer to the relevant section of library/builtins.m that
explains why we do things this way.
> +
> +typedef struct MR_SpecialPredHooks_Struct {
> + #ifdef MR_HIGHLEVEL_CODE
> + MR_bool (*MR_unify_tuple_pred)(MR_Word ti, MR_Word x, MR_Word y);
> + MR_bool (*MR_compare_tuple_pred)(MR_Word ti, MR_Word *res,
> + MR_Word x, MR_Word y);
> + #else
> + MR_ProcAddr MR_unify_tuple_pred;
> + MR_ProcAddr MR_compare_tuple_pred;
> + #endif
> +} MR_SpecialPredHooks;
> +
> +extern MR_SpecialPredHooks MR_special_pred_hooks;
> +
> #endif /* not MERCURY_HO_CALL_H */
> diff --git a/runtime/mercury_unify_compare_body.h b/runtime/mercury_unify_compare_body.h
> index 08c3941..dfbaedb 100644
The change looks fine to me (modulo my remarks elsewhere in this thread
about library initialisation).
Cheers,
Julien.
More information about the reviews
mailing list