[m-rev.] diff: C# optimisations

Peter Wang novalazy at gmail.com
Tue Oct 12 16:05:16 AEDT 2010


Branches: main

Optimisations for the C# backend.

compiler/ml_switch_gen.m:
        Allow generating of "direct-mapped" string switches in C#.

        Delete some obsolete lines.

compiler/mlds_to_cs.m:
library/builtin.m:
        Use pre-allocated constants when boxing `comparison_result' values.
        This substantially reduces the number of short-lived objects being
        created.

        String comparisons were changed to use the `String.CompareOrdinal'
        in the library previously; we missed a spot in compiler.

library/io.m:
        Use a cached value of `System.Environment.NewLine' in mercury_getc,
        as it is faster.

runtime/mercury_dotnet.cs.in:
        Keep an instance of a TypeInfo_Struct created from a
        TypeCtorInfo_Struct, so it can be reused if the same
        TypeCtorInfo_Struct needs to be "cast" to TypeInfo_Struct again.

diff --git a/compiler/ml_switch_gen.m b/compiler/ml_switch_gen.m
index 2108815..38341d7 100644
--- a/compiler/ml_switch_gen.m
+++ b/compiler/ml_switch_gen.m
@@ -191,6 +191,12 @@ ml_gen_switch(SwitchVar, CanFail, Cases, CodeModel, Context, GoalInfo,
                 ml_generate_string_switch(TaggedCases, SwitchVar,
                     CodeModel, CanFail, Context, Decls, Statements, !Info)
             ;
+                target_supports_string_switch(Globals)
+            ->
+                ml_switch_generate_mlds_switch(TaggedCases, SwitchVar,
+                    CodeModel, CanFail, Context, Statements, !Info),
+                Decls = []
+            ;
                 ml_switch_generate_if_then_else_chain(TaggedCases,
                     SwitchVar, CodeModel, CanFail, Context, Statements, !Info),
                 Decls = []
@@ -303,7 +309,6 @@ target_supports_int_switch_2(target_asm) = yes.
 target_supports_int_switch_2(target_il) = no.
 target_supports_int_switch_2(target_csharp) = yes.
 target_supports_int_switch_2(target_java) = yes.
-% target_supports_int_switch_2(c_sharp) = yes.
 target_supports_int_switch_2(target_x86_64) =
     unexpected(this_file, "target x86_64 with --high-level code").
 target_supports_int_switch_2(target_erlang) =
@@ -314,7 +319,6 @@ target_supports_string_switch_2(target_asm) = no.
 target_supports_string_switch_2(target_il) = no.
 target_supports_string_switch_2(target_csharp) = yes.
 target_supports_string_switch_2(target_java) = no.
-% target_supports_string_switch_2(c_sharp) = yes.
 target_supports_string_switch_2(target_x86_64) =
     unexpected(this_file, "target x86_64 with --high-level code").
 target_supports_string_switch_2(target_erlang) =
@@ -338,7 +342,6 @@ target_supports_goto_2(target_asm) = yes.
 target_supports_goto_2(target_il) = yes.
 target_supports_goto_2(target_csharp) = yes.
 target_supports_goto_2(target_java) = no.
-% target_supports_goto_2(c_sharp) = yes.
 target_supports_goto_2(target_x86_64) =
     unexpected(this_file, "target x86_64 with --high-level code").
 target_supports_goto_2(target_erlang) =
diff --git a/compiler/mlds_to_cs.m b/compiler/mlds_to_cs.m
index 9cb30fd..6247347 100644
--- a/compiler/mlds_to_cs.m
+++ b/compiler/mlds_to_cs.m
@@ -3220,7 +3220,13 @@ output_unop(Info, Unop, Expr, !IO) :-
         output_cast_rval(Info, Type, Expr, !IO)
     ;
         Unop = box(Type),
-        output_boxed_rval(Info, Type, Expr, !IO)
+        ( Type = mercury_type(comparison_result_type, _, _) ->
+            io.write_string("builtin.comparison_result_object[(int) ", !IO),
+            output_rval(Info, Expr, !IO),
+            io.write_string("]", !IO)
+        ;
+            output_boxed_rval(Info, Type, Expr, !IO)
+        )
     ;
         Unop = unbox(Type),
         output_unboxed_rval(Info, Type, Expr, !IO)
@@ -3372,7 +3378,7 @@ output_binop(Info, Op, X, Y, !IO) :-
         ;
             io.write_string("(", !IO),
             output_rval(Info, X, !IO),
-            io.write_string(".CompareTo(", !IO),
+            io.write_string(".CompareOrdinal(", !IO),
             output_rval(Info, Y, !IO),
             io.write_string(") ", !IO),
             io.write_string(OpStr, !IO),
diff --git a/library/builtin.m b/library/builtin.m
index 9095360..f8923ed 100644
--- a/library/builtin.m
+++ b/library/builtin.m
@@ -616,6 +616,14 @@ get_one_solution_io(Pred, X, !IO) :-
         (>) - "COMPARE_GREATER"
     ]).
 
+:- pragma foreign_code("C#", "
+    public static readonly object[] comparison_result_object = new object[] {
+        (Comparison_result_0) 0,
+        (Comparison_result_0) 1,
+        (Comparison_result_0) 2
+    };
+").
+
 ordering(X, Y) = R :-
     compare(R, X, Y).
 
diff --git a/library/io.m b/library/io.m
index cf312dc..83acd9d 100644
--- a/library/io.m
+++ b/library/io.m
@@ -7108,6 +7108,8 @@ mercury_print_binary_string(MR_MercuryFileStruct mf, string s)
 // converting the bytes from the system's default encoding to Unicode,
 // and possibly converting CR-LF to newline. Returns -1 on error or EOF.
 
+private static readonly string NewLine = System.Environment.NewLine;
+
 public static int
 mercury_getc(MR_MercuryFileStruct mf)
 {
@@ -7140,7 +7142,7 @@ mercury_getc(MR_MercuryFileStruct mf)
         // System.Environment.NewLine.
         // We assume that System.Environment.NewLine is non-null
         // and that System.Environment.NewLine.Length > 0.
-        if (c != System.Environment.NewLine[0]) {
+        if (c != io.NewLine[0]) {
             if (c == '\\n') {
                 // the input file was ill-formed, e.g. it contained only raw
                 // LFs rather than CR-LF. Perhaps we should throw an exception?
@@ -7149,13 +7151,13 @@ mercury_getc(MR_MercuryFileStruct mf)
                 mf.line_number++;
             }
         } else /* c == NewLine[0] */ {
-            switch (System.Environment.NewLine.Length) {
+            switch (io.NewLine.Length) {
             case 1:
                 mf.line_number++;
                 c = '\\n';
                 break;
             case 2:
-                if (mf.reader.Peek() == System.Environment.NewLine[1]) {
+                if (mf.reader.Peek() == io.NewLine[1]) {
                     mf.reader.Read();
                     mf.line_number++;
                     c = '\\n';
diff --git a/runtime/mercury_dotnet.cs.in b/runtime/mercury_dotnet.cs.in
index 45ef6c4..fad20c1 100644
--- a/runtime/mercury_dotnet.cs.in
+++ b/runtime/mercury_dotnet.cs.in
@@ -139,6 +139,7 @@ public class TypeCtorInfo_Struct : PseudoTypeInfo {
     public int              type_ctor_num_functors;
     public short            type_ctor_flags;
     public int[]            type_functor_number_map;
+    private TypeInfo_Struct cached_type_info;
 
     public TypeCtorInfo_Struct() {
     }
@@ -220,6 +221,13 @@ public class TypeCtorInfo_Struct : PseudoTypeInfo {
     public override string ToString() {
         return type_ctor_module_name + "." + type_ctor_name + "/" + arity;
     }
+
+    public TypeInfo_Struct ToTypeInfo() {
+        if (cached_type_info == null) {
+            cached_type_info = new TypeInfo_Struct(this);
+        }
+        return cached_type_info;
+    }
 }
 
 public class TypeInfo_Struct : PseudoTypeInfo {
@@ -247,13 +255,13 @@ public class TypeInfo_Struct : PseudoTypeInfo {
     }
 
     public static TypeInfo_Struct maybe_new(TypeCtorInfo_Struct tc) {
-        return new TypeInfo_Struct(tc);
+        return tc.ToTypeInfo();
     }
 
     public static TypeInfo_Struct maybe_new(PseudoTypeInfo obj) {
         TypeCtorInfo_Struct tc = obj as TypeCtorInfo_Struct;
         if (tc != null) {
-            return new TypeInfo_Struct(tc);
+            return tc.ToTypeInfo();
         }
         return (TypeInfo_Struct) obj;
     }

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