Author: marek
Date: 2008-01-24 10:30:29 -0500 (Thu, 24 Jan 2008)
New Revision: 93802

Modified:
   trunk/mcs/mcs/ChangeLog
   trunk/mcs/mcs/generic.cs
Log:
2008-01-24  Marek Safar  <[EMAIL PROTECTED]>

        * generic.cs: Do nullable type to null comparison optimization during
        resolve phase.
        


Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog     2008-01-24 15:23:25 UTC (rev 93801)
+++ trunk/mcs/mcs/ChangeLog     2008-01-24 15:30:29 UTC (rev 93802)
@@ -1,5 +1,10 @@
 2008-01-24  Marek Safar  <[EMAIL PROTECTED]>
 
+       * generic.cs: Do nullable type to null comparison optimization during
+       resolve phase.
+       
+2008-01-24  Marek Safar  <[EMAIL PROTECTED]>
+
        A fix for bug #355163
        * generic.cs: Enabled l-value resolve on nullable expressions.
        

Modified: trunk/mcs/mcs/generic.cs
===================================================================
--- trunk/mcs/mcs/generic.cs    2008-01-24 15:23:25 UTC (rev 93801)
+++ trunk/mcs/mcs/generic.cs    2008-01-24 15:30:29 UTC (rev 93802)
@@ -3123,7 +3123,14 @@
 
                        public override void Emit (EmitContext ec)
                        {
-                               ((IMemoryLocation) expr).AddressOf (ec, 
AddressOp.LoadStore);
+                               IMemoryLocation memory_loc = expr as 
IMemoryLocation;
+                               if (memory_loc == null) {
+                                       LocalTemporary temp = new 
LocalTemporary (expr.Type);
+                                       expr.Emit (ec);
+                                       temp.Store (ec);
+                                       memory_loc = temp;
+                               }
+                               memory_loc.AddressOf (ec, AddressOp.LoadStore);
                                ec.ig.EmitCall (OpCodes.Call, info.HasValue, 
null);
                        }
 
@@ -3191,6 +3198,12 @@
                                ec.ig.EmitCall (OpCodes.Call, info.HasValue, 
null);
                        }
 
+                       public override bool IsNull {
+                               get {
+                                       return expr.IsNull;
+                               }
+                       }
+
                        public void Store (EmitContext ec)
                        {
                                create_temp (ec);
@@ -3487,6 +3500,22 @@
                                        Error_OperatorCannotBeApplied ();
                                        return null;
                                }
+
+                               //
+                               // Optimize null comparisons
+                               //
+                               if (Oper == Binary.Operator.Equality) {
+                                       if (left.IsNull)
+                                               return new Unary 
(Unary.Operator.LogicalNot, Nullable.HasValue.Create (right, ec), loc).Resolve 
(ec);
+                                       if (right.IsNull)
+                                               return new Unary 
(Unary.Operator.LogicalNot, Nullable.HasValue.Create (left, ec), loc).Resolve 
(ec);
+                               }
+                               if (Oper == Binary.Operator.Inequality) {
+                                       if (left.IsNull)
+                                               return Nullable.HasValue.Create 
(right, ec);
+                                       if (right.IsNull)
+                                               return Nullable.HasValue.Create 
(left, ec);
+                               }
                                
                                if (TypeManager.IsNullableType (left.Type)) {
                                        left = left_unwrap = Unwrap.Create 
(left, ec);
@@ -3509,12 +3538,9 @@
                                        type = bool_wrap.Type;
                                        is_boolean = true;
                                } else if ((Oper == Binary.Operator.Equality) 
|| (Oper == Binary.Operator.Inequality)) {
-                                       if (!(left is NullLiteral) && !(right 
is NullLiteral)) {
-                                               underlying = new Binary (Oper, 
left, right).Resolve (ec);
-                                               if (underlying == null)
-                                                       return null;
-                                       }
-
+                                       underlying = new Binary (Oper, left, 
right).Resolve (ec);
+                                       if (underlying == null)
+                                               return null;
                                        type = TypeManager.bool_type;
                                        is_equality = true;
                                } else if ((Oper == Binary.Operator.LessThan) ||
@@ -3610,31 +3636,11 @@
 
                        void EmitEquality (EmitContext ec)
                        {
+                               if (left.IsNull || right.IsNull)
+                                       throw new InternalErrorException 
("Unoptimized nullable comparison");
+
                                ILGenerator ig = ec.ig;
 
-                               // Given 'X? x;' for any value type X: 'x != 
null' is the same as 'x.HasValue'
-                               if (left is NullLiteral) {
-                                       if (right_unwrap == null)
-                                               throw new 
InternalErrorException ();
-                                       right_unwrap.EmitCheck (ec);
-                                       if (Oper == Binary.Operator.Equality) {
-                                               ig.Emit (OpCodes.Ldc_I4_0);
-                                               ig.Emit (OpCodes.Ceq);
-                                       }
-                                       return;
-                               }
-
-                               if (right is NullLiteral) {
-                                       if (left_unwrap == null)
-                                               throw new 
InternalErrorException ();
-                                       left_unwrap.EmitCheck (ec);
-                                       if (Oper == Binary.Operator.Equality) {
-                                               ig.Emit (OpCodes.Ldc_I4_0);
-                                               ig.Emit (OpCodes.Ceq);
-                                       }
-                                       return;
-                               }
-
                                Label both_have_value_label = ig.DefineLabel ();
                                Label end_label = ig.DefineLabel ();
 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to