[m-rev.] diff: extend existing optimization

Zoltan Somogyi zs at cs.mu.OZ.AU
Thu Sep 22 17:03:29 AEST 2005


compiler/llds_out.m:
	We already have an optimization in llds_out.m which tries to turn
	Mercury abstract machine gotos, whose potential cross-module scope
	results in lots of overheads in none.gc and non-negligible overhead
	even in asm_fast.gc, into gotos that the C compiler knows are local,
	by making them the continue statements of while loops.

	This diff extends this optimization by making it work even when the
	goto being optimized is inside a block instruction introduced as part
	of the --use-local-vars optimization. Previously, that optimization
	and the one in llds_out.m stepped on each other's toes; that is no
	longer the case.

	This diff improves the compiler's speed by about 0.5% with
	-O2 --use-local-vars.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.259
diff -u -b -r1.259 llds_out.m
--- compiler/llds_out.m	22 Sep 2005 06:29:26 -0000	1.259
+++ compiler/llds_out.m	22 Sep 2005 06:29:45 -0000
@@ -197,6 +197,7 @@
 :- import_module ll_backend__layout_out.
 :- import_module ll_backend__pragma_c_gen.
 :- import_module ll_backend__rtti_out.
+:- import_module parse_tree__error_util.
 :- import_module parse_tree__mercury_to_mercury.
 :- import_module parse_tree__modules.
 :- import_module parse_tree__prog_foreign.
@@ -1740,20 +1741,42 @@
     list(instruction)::in, list(instruction)::out, int::in, int::out) is det.
 
 is_while_label(_, [], [], !Count).
-is_while_label(Label, [Instr0 - Comment0 | Instrs0], Instrs,
-        !Count) :-
+is_while_label(Label, [Instr0 - Comment0 | Instrs0], Instrs, !Count) :-
     ( Instr0 = label(_) ->
         Instrs = [Instr0 - Comment0 | Instrs0]
-    ; Instr0 = goto(label(Label)) ->
-        !:Count = !.Count + 1,
-        is_while_label(Label, Instrs0, Instrs, !Count)
+    ;
+        ( Instr0 = goto(label(Label)) ->
+            !:Count = !.Count + 1
     ; Instr0 = if_val(_, label(Label)) ->
-        !:Count = !.Count + 1,
-        is_while_label(Label, Instrs0, Instrs, !Count)
+            !:Count = !.Count + 1
+        ; Instr0 = block(_, _, BlockInstrs) ->
+            count_while_label_in_block(Label, BlockInstrs, !Count)
     ;
+            true
+        ),
         is_while_label(Label, Instrs0, Instrs, !Count)
     ).
 
+:- pred count_while_label_in_block(label::in, list(instruction)::in,
+    int::in, int::out) is det.
+
+count_while_label_in_block(_, [], !Count).
+count_while_label_in_block(Label, [Instr0 - _Comment0 | Instrs0], !Count) :-
+    ( Instr0 = label(_) ->
+        unexpected(this_file, "label in block")
+    ;
+        ( Instr0 = goto(label(Label)) ->
+            !:Count = !.Count + 1
+        ; Instr0 = if_val(_, label(Label)) ->
+            !:Count = !.Count + 1
+        ; Instr0 = block(_, _, _) ->
+            unexpected(this_file, "block in block")
+        ;
+            true
+        ),
+        count_while_label_in_block(Label, Instrs0, !Count)
+    ).
+
 %-----------------------------------------------------------------------------%
 
 :- pred output_instruction_decls(map(label, data_addr)::in, instruction::in,
@@ -1906,6 +1929,9 @@
         io__write_string("\twhile (1) {\n", !IO),
         output_instruction_list_while(Instrs, Label,
             PrintComments, ProfInfo, WhileSet, !IO)
+        % The matching close brace is printed in output_instruction_list
+        % when before the next label, before a goto that closes the loop,
+        % or when we get to the end of Instrs.
     ;
         output_instruction_list(Instrs, PrintComments, ProfInfo,
             WhileSet, !IO)
@@ -1942,6 +1968,13 @@
         ),
         output_instruction_list_while(Instrs, Label,
             PrintComments, ProfInfo, WhileSet, !IO)
+    ; Instr0 = block(TempR, TempF, BlockInstrs) ->
+        output_block_start(TempR, TempF, !IO),
+        output_instruction_list_while_block(BlockInstrs, Label, PrintComments,
+            ProfInfo, !IO),
+        output_block_end(!IO),
+        output_instruction_list_while(Instrs, Label,
+            PrintComments, ProfInfo, WhileSet, !IO)
     ;
         output_instruction_and_comment(Instr0, Comment0,
             PrintComments, ProfInfo, !IO),
@@ -1949,6 +1982,43 @@
             PrintComments, ProfInfo, WhileSet, !IO)
     ).
 
+:- pred output_instruction_list_while_block(list(instruction)::in, label::in,
+    bool::in, pair(label, bintree_set(label))::in, io::di, io::uo) is det.
+
+output_instruction_list_while_block([], _, _, _, !IO).
+output_instruction_list_while_block([Instr0 - Comment0 | Instrs], Label,
+        PrintComments, ProfInfo, !IO) :-
+    ( Instr0 = label(_) ->
+        unexpected(this_file, "label in block")
+    ; Instr0 = goto(label(Label)) ->
+        io__write_string("\tcontinue;\n", !IO),
+        require(unify(Instrs, []),
+            "output_instruction_list_while_block: code after goto")
+    ; Instr0 = if_val(Rval, label(Label)) ->
+        io__write_string("\tif (", !IO),
+        output_test_rval(Rval, !IO),
+        io__write_string(")\n\t\tcontinue;\n", !IO),
+        (
+            PrintComments = yes,
+            Comment0 \= ""
+        ->
+            io__write_string("\t\t/* ", !IO),
+            io__write_string(Comment0, !IO),
+            io__write_string(" */\n", !IO)
+        ;
+            true
+        ),
+        output_instruction_list_while_block(Instrs, Label,
+            PrintComments, ProfInfo, !IO)
+    ; Instr0 = block(_, _, _) ->
+        unexpected(this_file, "block in block")
+    ;
+        output_instruction_and_comment(Instr0, Comment0,
+            PrintComments, ProfInfo, !IO),
+        output_instruction_list_while_block(Instrs, Label,
+            PrintComments, ProfInfo, !IO)
+    ).
+
 :- pred output_instruction_and_comment(instr::in, string::in, bool::in,
     pair(label, bintree_set(label))::in, io::di, io::uo) is det.
 
@@ -2003,19 +2073,9 @@
     ProfInfo = entry(local, ProcLabel) - ContLabelSet,
     output_instruction(Instr, ProfInfo, !IO).
 
-:- pred output_instruction(instr::in, pair(label, bintree_set(label))::in,
-    io::di, io::uo) is det.
-
-output_instruction(comment(Comment), _, !IO) :-
-    io__write_strings(["/*", Comment, "*/\n"], !IO).
+:- pred output_block_start(int::in, int::in, io::di, io::uo) is det.
 
-output_instruction(livevals(LiveVals), _, !IO) :-
-    io__write_string("/*\n* Live lvalues:\n", !IO),
-    set__to_sorted_list(LiveVals, LiveValsList),
-    output_livevals(LiveValsList, !IO),
-    io__write_string("*/\n", !IO).
-
-output_instruction(block(TempR, TempF, Instrs), ProfInfo, !IO) :-
+output_block_start(TempR, TempF, !IO) :-
     io__write_string("\t{\n", !IO),
     ( TempR > 0 ->
         io__write_string("\tMR_Word ", !IO),
@@ -2030,11 +2090,31 @@
         io__write_string(";\n", !IO)
     ;
         true
-    ),
+    ).
+
+:- pred output_block_end(io::di, io::uo) is det.
+
+output_block_end(!IO) :-
+    io__write_string("\t}\n", !IO).
+
+:- pred output_instruction(instr::in, pair(label, bintree_set(label))::in,
+    io::di, io::uo) is det.
+
+output_instruction(comment(Comment), _, !IO) :-
+    io__write_strings(["/*", Comment, "*/\n"], !IO).
+
+output_instruction(livevals(LiveVals), _, !IO) :-
+    io__write_string("/*\n* Live lvalues:\n", !IO),
+    set__to_sorted_list(LiveVals, LiveValsList),
+    output_livevals(LiveValsList, !IO),
+    io__write_string("*/\n", !IO).
+
+output_instruction(block(TempR, TempF, Instrs), ProfInfo, !IO) :-
+    output_block_start(TempR, TempF, !IO),
     globals__io_lookup_bool_option(auto_comments, PrintComments, !IO),
     output_instruction_list(Instrs, PrintComments, ProfInfo,
         bintree_set__init, !IO),
-    io__write_string("\t}\n", !IO).
+    output_block_end(!IO).
 
 output_instruction(assign(Lval, Rval), _, !IO) :-
     io__write_string("\t", !IO),
@@ -5191,5 +5271,11 @@
     varset__lookup_name(VarSet, Var, VarName),
     string__append_list([VarName, "\t ->\t", StackStr, SlotStr, "\n",
         !.Explanation], !:Explanation).
+
+%---------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "llds_out.m".
 
 %---------------------------------------------------------------------------%
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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