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