[m-rev.] diff: fix tail call optimisation bug in MLDS backend

Julien Fischer juliensf at csse.unimelb.edu.au
Wed Aug 29 03:53:36 AEST 2007


Estimated hours taken: 8
Branches: main

Fix a bug reported by Michael Day.

compiler/ml_call_gen.m:
 	Do not introduce assignment statements that perform casts to (un)box
 	arguments of array types when the types of the LHS and RHS of such
 	assignments would be the same.  This avoids situations where
 	tail call optimisation cannot be applied to procedures with array
 	arguments because the introduced assignments are added after the
 	recursive call(s).

tests/hard_coded/.cvsignore:
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/big_array_from_list.{m,exp}:
 	Test case for the above bug.

Julien.

Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.78
diff -u -r1.78 ml_call_gen.m
--- compiler/ml_call_gen.m	21 Aug 2007 15:50:39 -0000	1.78
+++ compiler/ml_call_gen.m	28 Aug 2007 17:43:21 -0000
@@ -779,7 +779,10 @@
          ;
              type_ctor_is_array(DestTypeCtor),
              DestTypeArgs = [type_variable(_, _)]
-        )
+        ),
+        % Don't insert redundant casts if the types are the same, since
+        % the extra assignments introduced can inhibit tail call optimisation.
+        SourceType \= DestType
      ->
          ml_gen_type(!.Info, DestType, MLDS_DestType),
          ArgRval = unop(cast(MLDS_DestType), VarRval)
Index: tests/hard_coded/.cvsignore
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/.cvsignore,v
retrieving revision 1.30
diff -u -r1.30 .cvsignore
--- tests/hard_coded/.cvsignore	20 Aug 2007 03:36:17 -0000	1.30
+++ tests/hard_coded/.cvsignore	28 Aug 2007 17:43:21 -0000
@@ -19,6 +19,7 @@
  address_of_builtins
  agg
  bidirectional
+big_array_from_list
  bigtest
  boyer
  c_write_string
Index: tests/hard_coded/Mercury.options
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mercury.options,v
retrieving revision 1.27
diff -u -r1.27 Mercury.options
--- tests/hard_coded/Mercury.options	20 Aug 2007 03:36:17 -0000	1.27
+++ tests/hard_coded/Mercury.options	28 Aug 2007 17:43:21 -0000
@@ -2,6 +2,7 @@
  MCFLAGS-any_call_hoist_bug = --loop-invariants
  MCFLAGS-checked_nondet_tailcall	= --checked-nondet-tailcalls
  MCFLAGS-checked_nondet_tailcall_noinline = --checked-nondet-tailcalls --no-inlining
+MCFLAGS-big_array_from_list =   --optimize-tailcalls
  MCFLAGS-bigtest		=	--intermodule-optimization -O3
  MCFLAGS-cc_and_non_cc_test = 	--no-inlining
  MCFLAGS-constraint	=	--constraint-propagation --enable-termination
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.331
diff -u -r1.331 Mmakefile
--- tests/hard_coded/Mmakefile	24 Aug 2007 07:56:27 -0000	1.331
+++ tests/hard_coded/Mmakefile	28 Aug 2007 17:43:21 -0000
@@ -13,6 +13,7 @@
  	array_test \
  	backquoted_qualified_ops \
  	bag_various \
+	big_array_from_list \
  	bidirectional \
  	boyer \
  	brace \
Index: tests/hard_coded/big_array_from_list.exp
===================================================================
RCS file: tests/hard_coded/big_array_from_list.exp
diff -N tests/hard_coded/big_array_from_list.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/big_array_from_list.exp	28 Aug 2007 17:43:21 -0000
@@ -0,0 +1 @@
+NumElems = 600001
Index: tests/hard_coded/big_array_from_list.m
===================================================================
RCS file: tests/hard_coded/big_array_from_list.m
diff -N tests/hard_coded/big_array_from_list.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/big_array_from_list.m	28 Aug 2007 17:43:21 -0000
@@ -0,0 +1,51 @@
+% Test case for a bug in the MLDS backend in rotd-2007-08-28 and before.
+% The ml code generator was incorrectly inserting assignment statements to
+% do casts even when the types on the lhs and rhs were identical.  This
+% was inhibiting tail call optimisation in code that used arrays.
+% (The code marked XXX below is one such example.).
+%
+:- module big_array_from_list.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module array.
+:- import_module int.
+:- import_module list.
+:- import_module string.
+
+main(!IO) :-
+    List = 0 .. 600000,
+    array_from_list(List, Array),
+    NumElems = array.foldl(count, Array, 0),
+    io.format("NumElems = %d\n", [i(NumElems)], !IO).
+
+:- pred array_from_list(list(T), array(T)).
+:- mode array_from_list(in, array_uo) is det.
+
+array_from_list([], Array) :-
+    array.make_empty_array(Array).
+array_from_list(List, Array) :-
+    List = [Head | Tail],
+    list.length(List, Len),
+    array.init(Len, Head, Array0),
+    array_insert_items(Tail, 1, Array0, Array).
+
+% XXX Tail call optimisation was not being performed on this
+% predicate in hl* grades.
+:- pred array_insert_items(list(T)::in, int::in,
+    array(T)::array_di, array(T)::array_uo) is det.
+
+array_insert_items([], _N, Array, Array).
+array_insert_items([Head | Tail], N, Array0, Array) :-
+    array.set(Array0, N, Head, Array1),
+    N1 = N + 1,
+    array_insert_items(Tail, N1, Array1, Array).
+
+:- func count(int, int) = int.
+
+count(_, X) = X + 1.

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list