| Newsgroups |
gmane.comp.gnome.mono.patches |
| Message-ID |
<000001428fcfafd9-b3ac906e-5ada-437b-b8fe-e6012ad98f88-000000@email.amazonses.com> |
Branch: refs/heads/master
Home: https://github.com/mono/mono
Compare: https://github.com/mono/mono/compare/8a4e1ca74e65...1d5cefe7ad5e
Commit: 8c6864df1c2175295180599773f296c13372b839
Author: Marek Safar <[email protected]> (marek-safar)
Date: 2013-11-25 15:02:58 GMT
URL: https://github.com/mono/mono/commit/8c6864df1c2175295180599773f296c13372b839
[mcs] Optimize DefiniteAssignmentBitSet
Changed paths:
M mcs/mcs/context.cs
M mcs/mcs/flowanalysis.cs
Modified: mcs/mcs/context.cs
===================================================================
@@ -445,7 +445,9 @@ public FlowAnalysisContext (CompilerContext ctx, ParametersBlock parametersBlock
this.ctx = ctx;
this.ParametersBlock = parametersBlock;
- DefiniteAssignment = new DefiniteAssignmentBitSet (definiteAssignmentLength);
+ DefiniteAssignment = definiteAssignmentLength == 0 ?
+ DefiniteAssignmentBitSet.Empty :
+ new DefiniteAssignmentBitSet (definiteAssignmentLength);
}
public DefiniteAssignmentBitSet DefiniteAssignment { get; set; }
@@ -469,7 +471,8 @@ public FlowAnalysisContext (CompilerContext ctx, ParametersBlock parametersBlock
public DefiniteAssignmentBitSet BranchDefiniteAssignment ()
{
var dat = DefiniteAssignment;
- DefiniteAssignment = new DefiniteAssignmentBitSet (dat);
+ if (dat != DefiniteAssignmentBitSet.Empty)
+ DefiniteAssignment = new DefiniteAssignmentBitSet (dat);
return dat;
}
Modified: mcs/mcs/flowanalysis.cs
===================================================================
@@ -503,46 +503,79 @@ public static Reachability CreateUnreachable ()
}
}
+ //
+ // Special version of bit array. Many operations can be simplified because
+ // we are always dealing with arrays of same sizes
+ //
public class DefiniteAssignmentBitSet
{
- // Make it
- // int bits;
- // int int[] bits_extended; // when bits overflows
+ const uint copy_on_write_flag = 1u << 31;
+
+ uint bits;
+
+ // Used when bits overflows
+ int[] large_bits;
- System.Collections.BitArray bits;
- bool copy_on_write;
+ public static readonly DefiniteAssignmentBitSet Empty = new DefiniteAssignmentBitSet (0);
public DefiniteAssignmentBitSet (int length)
{
- bits = new System.Collections.BitArray (length);
+ if (length > 31)
+ large_bits = new int[(length + 31) / 32];
}
public DefiniteAssignmentBitSet (DefiniteAssignmentBitSet source)
{
- bits = source.bits;
-
- copy_on_write = true;
- }
-
- private DefiniteAssignmentBitSet (System.Collections.BitArray bits)
- {
- this.bits = bits;
+ large_bits = source.large_bits;
+ bits = source.bits | copy_on_write_flag;
}
public static DefiniteAssignmentBitSet operator & (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
{
- if (a.bits == b.bits)
+ if (AreEqual (a, b))
return a;
- return new DefiniteAssignmentBitSet (a.bits.And (b.bits));
+ DefiniteAssignmentBitSet res;
+ if (a.large_bits == null) {
+ res = new DefiniteAssignmentBitSet (a);
+ res.bits &= (b.bits & ~copy_on_write_flag);
+ return res;
+ }
+
+ res = new DefiniteAssignmentBitSet (a);
+ res.Clone ();
+ var dest = res.large_bits;
+ var src = b.large_bits;
+ for (int i = 0; i < dest.Length; ++i) {
+ dest[i] &= src[i];
+ }
+
+ return res;
}
public static DefiniteAssignmentBitSet operator | (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
{
- if (a.bits == b.bits)
+ if (AreEqual (a, b))
return a;
- return new DefiniteAssignmentBitSet (a.bits.Or (b.bits));
+ DefiniteAssignmentBitSet res;
+ if (a.large_bits == null) {
+ res = new DefiniteAssignmentBitSet (a);
+ res.bits |= b.bits;
+ res.bits &= ~copy_on_write_flag;
+ return res;
+ }
+
+ res = new DefiniteAssignmentBitSet (a);
+ res.Clone ();
+ var dest = res.large_bits;
+ var src = b.large_bits;
+
+ for (int i = 0; i < dest.Length; ++i) {
+ dest[i] |= src[i];
+ }
+
+ return res;
}
public static DefiniteAssignmentBitSet And (List<DefiniteAssignmentBitSet> das)
@@ -550,7 +583,7 @@ public static DefiniteAssignmentBitSet And (List<DefiniteAssignmentBitSet> das)
if (das.Count == 0)
throw new ArgumentException ("Empty das");
- DefiniteAssignmentBitSet res = das [0];
+ DefiniteAssignmentBitSet res = das[0];
for (int i = 1; i < das.Count; ++i) {
res &= das[i];
}
@@ -558,45 +591,87 @@ public static DefiniteAssignmentBitSet And (List<DefiniteAssignmentBitSet> das)
return res;
}
+ bool CopyOnWrite {
+ get {
+ return (bits & copy_on_write_flag) != 0;
+ }
+ }
+
+ int Length {
+ get {
+ return large_bits == null ? 31 : large_bits.Length * 32;
+ }
+ }
+
public void Set (int index)
{
- if (copy_on_write && !bits[index])
+ if (CopyOnWrite && !this[index])
Clone ();
- bits[index] = true;
+ SetBit (index);
}
public void Set (int index, int length)
{
for (int i = 0; i < length; ++i) {
- if (copy_on_write && !bits[index + i])
+ if (CopyOnWrite && !this[index + i])
Clone ();
- bits[index + i] = true;
+ SetBit (index + i);
}
- }
+ }
- public bool this [int index] {
+ public bool this[int index] {
get {
- return bits [index];
+ return GetBit (index);
}
}
- void Clone ()
- {
- bits = new System.Collections.BitArray (bits);
- copy_on_write = false;
- }
-
public override string ToString ()
{
- var length = bits.Length;
+ var length = Length;
StringBuilder sb = new StringBuilder (length);
for (int i = 0; i < length; ++i) {
- sb.Append (bits[i] ? '1' : '0');
+ sb.Append (this[i] ? '1' : '0');
}
return sb.ToString ();
}
+
+ void Clone ()
+ {
+ if (large_bits != null)
+ large_bits = (int[]) large_bits.Clone ();
+
+ bits &= ~copy_on_write_flag;
+ }
+
+ bool GetBit (int index)
+ {
+ return large_bits == null ?
+ (bits & (1 << index)) != 0 :
+ (large_bits[index >> 5] & (1 << (index & 31))) != 0;
+ }
+
+ void SetBit (int index)
+ {
+ if (large_bits == null)
+ bits = (uint) ((int) bits | (1 << index));
+ else
+ large_bits[index >> 5] |= (1 << (index & 31));
+ }
+
+ static bool AreEqual (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
+ {
+ if (a.large_bits == null)
+ return (a.bits & ~copy_on_write_flag) == (b.bits & ~copy_on_write_flag);
+
+ for (int i = 0; i < a.large_bits.Length; ++i) {
+ if (a.large_bits[i] != b.large_bits[i])
+ return false;
+ }
+
+ return true;
+ }
}
}
Commit: 1d5cefe7ad5e5253a410ec3dd5c6e825317c7557
Author: Marek Safar <[email protected]> (marek-safar)
Date: 2013-11-25 15:02:58 GMT
URL: https://github.com/mono/mono/commit/1d5cefe7ad5e5253a410ec3dd5c6e825317c7557
[mcs] Arguments flow analysis needs to ignore out modifier.
Changed paths:
M mcs/mcs/argument.cs
Added paths:
A mcs/errors/cs0165-29.cs
A mcs/errors/cs0165-30.cs
A mcs/errors/cs0165-31.cs
A mcs/errors/cs0165-32.cs
Added: mcs/errors/cs0165-29.cs
===================================================================
@@ -0,0 +1,12 @@
+// CS0165: Use of unassigned local variable `j'
+// Line: 10
+
+class Test
+{
+ static void Main ()
+ {
+ int? i;
+ int? j;
+ int? x = (i = 7) ?? j;
+ }
+}
\ No newline at end of file
Added: mcs/errors/cs0165-30.cs
===================================================================
@@ -0,0 +1,11 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 9
+
+using System;
+
+class Test {
+
+ static void Main () {
+ Action a = () => a();
+ }
+}
\ No newline at end of file
Added: mcs/errors/cs0165-31.cs
===================================================================
@@ -0,0 +1,11 @@
+// CS0165: Use of unassigned local variable `i'
+// Line: 9
+
+public class MainClass
+{
+ public void Foo ()
+ {
+ int i;
+ i++;
+ }
+}
Added: mcs/errors/cs0165-32.cs
===================================================================
@@ -0,0 +1,16 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 9
+
+class C
+{
+ static void Main ()
+ {
+ int a;
+ Foo (out a, a);
+ }
+
+ static void Foo (out int a, int b)
+ {
+ a = b;
+ }
+}
\ No newline at end of file
Modified: mcs/mcs/argument.cs
===================================================================
@@ -499,8 +499,25 @@ public virtual Arguments Emit (EmitContext ec, bool dup_args, bool prepareAwait)
public void FlowAnalysis (FlowAnalysisContext fc)
{
- foreach (var arg in args)
+ bool has_out = false;
+ foreach (var arg in args) {
+ if (arg.ArgType == Argument.AType.Out) {
+ has_out = true;
+ continue;
+ }
+
arg.FlowAnalysis (fc);
+ }
+
+ if (!has_out)
+ return;
+
+ foreach (var arg in args) {
+ if (arg.ArgType != Argument.AType.Out)
+ continue;
+
+ arg.FlowAnalysis (fc);
+ }
}
public List<Argument>.Enumerator GetEnumerator ()
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches