[m-rev.] for review: fix missed tail call optimisations in java grade

Peter Wang novalazy at gmail.com
Mon Jun 15 14:57:45 AEST 2009


Branches: main

Fix a problem in MLDS grades using --det-copy-out (java, il) where dummy
arguments in predicates would prevent tail calls being marked as such.

Also make a few predicates tail recursive.

compiler/ml_code_gen.m:
        With the --det-copy-out option, don't list dummy output variables as
        copy out variables.  This led to `return' statements containing dummy
        output variables, but a call prior to a `return' statement wouldn't
        have dummy outputs, so ml_tailcall.m wouldn't recognise the call as a
        tail call.

compiler/mlds_to_java.m:
        Delete a hack that drops dummy variables in return statements.

compiler/mercury_compile.m:
        Make backend_pass_by_preds_2 tail recursive.  Otherwise a compiler
        built in the java grade runs out of stack space compiling some
        larger modules.

library/bag.m:
        Make tail recursion more obvious in a few predicates.

diff --git a/compiler/mercury_compile.m b/compiler/mercury_compile.m
index 99f5ed5..a5f603a 100644
--- a/compiler/mercury_compile.m
+++ b/compiler/mercury_compile.m
@@ -2930,17 +2930,19 @@ backend_pass_by_preds(!HLDS, !GlobalData, LLDS, !IO) :-
         MaybeDupProcMap = yes(map.init)
     ),
     backend_pass_by_preds_2(OrderedPredIds, !HLDS, !GlobalData,
-        MaybeDupProcMap, LLDS, !IO).
+        MaybeDupProcMap, [], RevCodes, !IO),
+    list.reverse(RevCodes, Codes),
+    list.condense(Codes, LLDS).

 :- pred backend_pass_by_preds_2(list(pred_id)::in,
     module_info::in, module_info::out, global_data::in, global_data::out,
-    maybe(map(mdbcomp.prim_data.proc_label,
-        mdbcomp.prim_data.proc_label))::in,
-    list(c_procedure)::out, io::di, io::uo) is det.
+    maybe(map(mdbcomp.prim_data.proc_label, mdbcomp.prim_data.proc_label))::in,
+    list(list(c_procedure))::in, list(list(c_procedure))::out, io::di, io::uo)
+    is det.

-backend_pass_by_preds_2([], !HLDS, !GlobalData, _, [], !IO).
+backend_pass_by_preds_2([], !HLDS, !GlobalData, _, !RevCodes, !IO).
 backend_pass_by_preds_2([PredId | PredIds], !HLDS,
-        !GlobalData, !.MaybeDupProcMap, Code, !IO) :-
+        !GlobalData, !.MaybeDupProcMap, !RevCodes, !IO) :-
     module_info_preds(!.HLDS, PredTable),
     map.lookup(PredTable, PredId, PredInfo),
     ProcIds = pred_info_non_imported_procids(PredInfo),
@@ -2995,9 +2997,9 @@ backend_pass_by_preds_2([PredId | PredIds], !HLDS,
             !:MaybeDupProcMap = yes(DupProcMap)
         )
     ),
+    !:RevCodes = [ProcList | !.RevCodes],
     backend_pass_by_preds_2(PredIds, !HLDS, !GlobalData, !.MaybeDupProcMap,
-        TailPredsCode, !IO),
-    list.append(ProcList, TailPredsCode, Code).
+        !RevCodes, !IO).

 :- pred backend_pass_by_preds_3(list(proc_id)::in, pred_id::in, pred_info::in,
     module_info::in, module_info::out, global_data::in, global_data::out,
diff --git a/compiler/ml_code_gen.m b/compiler/ml_code_gen.m
index dd57ad4..801349a 100644
--- a/compiler/ml_code_gen.m
+++ b/compiler/ml_code_gen.m
@@ -1442,11 +1442,13 @@ ml_det_copy_out_vars(ModuleInfo,
CopiedOutputVars, !Info) :-
     module_info_get_globals(ModuleInfo, Globals),
     globals.lookup_bool_option(Globals, det_copy_out, DetCopyOut),
     (
-        % If --det-copy-out is enabled, all output variables are returned
-        % by value, rather than passing them by reference.
+        % If --det-copy-out is enabled, all non-dummy output variables are
+        % returned by value, rather than passing them by reference.
         DetCopyOut = yes,
         ByRefOutputVars = [],
-        CopiedOutputVars = OutputVars
+        ml_gen_info_get_var_types(!.Info, VarTypes),
+        list.filter(var_is_of_dummy_type(ModuleInfo, VarTypes), OutputVars,
+            _, CopiedOutputVars)
     ;
         DetCopyOut = no,
         (
diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m
index 0d39cdb..b7857de 100644
--- a/compiler/mlds_to_java.m
+++ b/compiler/mlds_to_java.m
@@ -2706,20 +2706,8 @@ output_stmt(Indent, ModuleInfo, CallerFuncInfo,
Call, Context, ExitMethods,
     io.write_string("}\n", !IO),
     ExitMethods = set.make_singleton_set(can_fall_through).

-output_stmt(Indent, ModuleInfo, FuncInfo, ml_stmt_return(Results0), _,
+output_stmt(Indent, ModuleInfo, FuncInfo, ml_stmt_return(Results), _,
         ExitMethods, !IO) :-
-    %
-    % XXX It's not right to just remove the dummy variables like this, but
-    % currently they do not seem to be included in the ReturnTypes of
-    % func_params by the MLDS, so the easiest thing to do here is just remove
-    % them.
-    %
-    % When this is resolved, the right way to handle it would be to check for
-    % `dummy_var' in the `var' clause for output_lval, and output a reference
-    % to a static variable `dummy_var' defined in a fixed class (e.g. some
-    % class in the mercury/java directory, or mercury.private_builtin).
-    %
-    Results = remove_dummy_vars(ModuleInfo, Results0),
     (
         Results = [],
         indent_line(Indent, !IO),
@@ -2861,22 +2849,6 @@ output_boxed_args(ModuleInfo, [CallArg | CallArgs],
         output_boxed_args(ModuleInfo, CallArgs, CallArgTypes, ModuleName, !IO)
     ).

-:- func remove_dummy_vars(module_info, list(mlds_rval)) = list(mlds_rval).
-
-remove_dummy_vars(_, []) = [].
-remove_dummy_vars(ModuleInfo, [Var | Vars0]) = VarList :-
-    Vars = remove_dummy_vars(ModuleInfo, Vars0),
-    (
-        Var = ml_lval(Lval),
-        Lval = ml_var(_VarName, VarType),
-        VarType = mercury_type(ProgDataType, _, _),
-        check_dummy_type(ModuleInfo, ProgDataType) = is_dummy_type
-    ->
-        VarList = Vars
-    ;
-        VarList = [Var | Vars]
-    ).
-
 %-----------------------------------------------------------------------------%
 %
 % Code for handling multiple return values.
diff --git a/library/bag.m b/library/bag.m
index 226462d..0d8a752 100644
--- a/library/bag.m
+++ b/library/bag.m
@@ -420,7 +420,7 @@ bag.count_value(bag(Bag), Item, Count) :-

 %---------------------------------------------------------------------------%

-bag.subtract(bag(Bag0), bag(SubBag), bag(Bag)) :-
+bag.subtract(bag(Bag0), bag(SubBag), Bag) :-
     ( map.remove_smallest(SubBag, SubKey, SubVal, SubBag0) ->
         ( map.search(Bag0, SubKey, Val) ->
             NewVal = Val - SubVal,
@@ -432,12 +432,12 @@ bag.subtract(bag(Bag0), bag(SubBag), bag(Bag)) :-
         ;
             Bag1 = Bag0
         ),
-        bag.subtract(bag(Bag1), bag(SubBag0), bag(Bag))
+        bag.subtract(bag(Bag1), bag(SubBag0), Bag)
     ;
-        Bag = Bag0
+        Bag = bag(Bag0)
     ).

-bag.union(bag(A), bag(B), bag(Out)) :-
+bag.union(bag(A), bag(B), Out) :-
     ( map.remove_smallest(B, Key, BVal, B0) ->
         ( map.search(A, Key, AVal) ->
             NewVal = AVal + BVal,
@@ -445,9 +445,9 @@ bag.union(bag(A), bag(B), bag(Out)) :-
         ;
             map.det_insert(A, Key, BVal, A0)
         ),
-        bag.union(bag(A0), bag(B0), bag(Out))
+        bag.union(bag(A0), bag(B0), Out)
     ;
-        Out = A
+        Out = bag(A)
     ).

 bag.intersect(A, B, Out) :-
@@ -457,7 +457,7 @@ bag.intersect(A, B, Out) :-
 :- pred bag.intersect_2(bag(T)::in, bag(T)::in, bag(T)::in, bag(T)::out)
     is det.

-bag.intersect_2(bag(A), bag(B), bag(Out0), bag(Out)) :-
+bag.intersect_2(bag(A), bag(B), bag(Out0), Out) :-
     ( map.remove_smallest(A, Key, AVal,A0) ->
         ( map.search(B, Key, BVal) ->
             int.min(AVal, BVal, Val),
@@ -465,9 +465,9 @@ bag.intersect_2(bag(A), bag(B), bag(Out0), bag(Out)) :-
         ;
             Out1 = Out0
         ),
-        bag.intersect_2(bag(A0), bag(B), bag(Out1), bag(Out))
+        bag.intersect_2(bag(A0), bag(B), bag(Out1), Out)
     ;
-        Out = Out0
+        Out = bag(Out0)
     ).

 bag.intersect(bag(A), bag(B)) :-
@@ -478,7 +478,7 @@ bag.intersect(bag(A), bag(B)) :-
         bag.intersect(bag(A0), bag(B))
     ).

-bag.least_upper_bound(bag(A), bag(B), bag(Out)) :-
+bag.least_upper_bound(bag(A), bag(B), Out) :-
     ( map.remove_smallest(B, Key, BVal, B0) ->
         ( map.search(A, Key, AVal) ->
             int.max(AVal, BVal, NewVal),
@@ -486,9 +486,9 @@ bag.least_upper_bound(bag(A), bag(B), bag(Out)) :-
         ;
             map.det_insert(A, Key, BVal, A0)
         ),
-        bag.least_upper_bound(bag(A0), bag(B0), bag(Out))
+        bag.least_upper_bound(bag(A0), bag(B0), Out)
     ;
-        Out = A
+        Out = bag(A)
     ).

 %---------------------------------------------------------------------------%
--------------------------------------------------------------------------
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