[m-rev.] for review: cheaper tag test for high-level C

Peter Wang novalazy at gmail.com
Mon May 9 11:49:12 AEST 2011


Surprisingly, this change actually produces a slowdown in the compiler,
so I'm not sure whether it should be applied.  Here is the speed test
on my machine (hlc.gc -O2)

mercury_compile.new average of 6 with ignore=1      9.50
mercury_compile.old average of 6 with ignore=1      9.46


Branches: main

Apply the "reverse tag test optimization" in high-level grades,
i.e. for data types with exactly two alternatives, one of which is a
constant, test against the constant (negating the result of the test),
since a test against a constant is cheaper than a tag test.
This was previously only implemented for low-level grades.

compiler/ml_unify_gen.m:
	As above.

diff --git a/compiler/ml_unify_gen.m b/compiler/ml_unify_gen.m
index 260b156..881a0fb 100644
--- a/compiler/ml_unify_gen.m
+++ b/compiler/ml_unify_gen.m
@@ -1742,9 +1742,6 @@ ml_gen_semi_deconstruct(Var, ConsId, Args, ArgModes, Context, Statements,
 ml_gen_tag_test(Var, ConsId, TagTestExpression, !Info) :-
     % NOTE: Keep in sync with ml_gen_known_tag_test below.
 
-    % TODO: apply the reverse tag test optimization for types with two
-    % functors (see unify_gen.m).
-
     ml_gen_var(!.Info, Var, VarLval),
     ml_variable_type(!.Info, Var, Type),
     ml_cons_id_to_tag(!.Info, ConsId, Tag),
@@ -1755,9 +1752,6 @@ ml_gen_tag_test(Var, ConsId, TagTestExpression, !Info) :-
 ml_gen_known_tag_test(Var, TaggedConsId, TagTestExpression, !Info) :-
     % NOTE: Keep in sync with ml_gen_tag_test above.
 
-    % TODO: apply the reverse tag test optimization for types with two
-    % functors (see unify_gen.m).
-
     ml_gen_var(!.Info, Var, VarLval),
     ml_variable_type(!.Info, Var, Type),
     TaggedConsId = tagged_cons_id(_ConsId, Tag),
@@ -1765,15 +1759,40 @@ ml_gen_known_tag_test(Var, TaggedConsId, TagTestExpression, !Info) :-
     TagTestExpression = ml_gen_tag_test_rval(Tag, Type, ModuleInfo,
         ml_lval(VarLval)).
 
-    % ml_gen_tag_test_rval(Tag, Type, ModuleInfo, VarRval) = TestRval:
+    % ml_gen_tag_test_rval(Tag, Type, ModuleInfo, VarRval) = TagTestRval:
     %
-    % TestRval is an Rval of type bool which evaluates to true if VarRval has
-    % the specified Tag and false otherwise. Type is the type of VarRval.
+    % TagTestRval is an Rval of type bool which evaluates to true if VarRval
+    % has the specified Tag and false otherwise. Type is the type of VarRval.
     %
 :- func ml_gen_tag_test_rval(cons_tag, mer_type, module_info, mlds_rval)
     = mlds_rval.
 
-ml_gen_tag_test_rval(Tag, Type, ModuleInfo, Rval) = TagTestRval :-
+ml_gen_tag_test_rval(Tag, Type, ModuleInfo, VarRval) = TagTestRval :-
+    % As an optimization, for data types with exactly two alternatives,
+    % one of which is a constant, we make sure that we test against the
+    % constant (negating the result of the test, if needed),
+    % since a test against a constant is cheaper than a tag test.
+    (
+        Tag = unshared_tag(_),
+        module_info_get_type_table(ModuleInfo, TypeTable),
+        type_to_ctor_and_args_det(Type, TypeCtor, _),
+        lookup_type_ctor_defn(TypeTable, TypeCtor, TypeDefn),
+        get_type_defn_body(TypeDefn, TypeBody),
+        CheaperTagTest = get_maybe_cheaper_tag_test(TypeBody),
+        CheaperTagTest = cheaper_tag_test(_ExpensiveConsId, Tag,
+            _CheaperConsId, CheapConsTag)
+    ->
+        CheapTagTestRval = ml_gen_tag_test_rval_2(CheapConsTag, Type,
+            ModuleInfo, VarRval),
+        TagTestRval = ml_unop(std_unop(logical_not), CheapTagTestRval)
+    ;
+        TagTestRval = ml_gen_tag_test_rval_2(Tag, Type, ModuleInfo, VarRval)
+    ).
+
+:- func ml_gen_tag_test_rval_2(cons_tag, mer_type, module_info, mlds_rval)
+    = mlds_rval.
+
+ml_gen_tag_test_rval_2(Tag, Type, ModuleInfo, Rval) = TagTestRval :-
     (
         Tag = string_tag(String),
         TagTestRval = ml_binop(str_eq, Rval, ml_const(mlconst_string(String)))

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