OSDN Git Service

Fix CopyRegInfo to keep live/dirty flags of new registers.
authorChao-ying Fu <chao-ying.fu@intel.com>
Thu, 27 Mar 2014 21:17:28 +0000 (14:17 -0700)
committerbuzbee <buzbee@google.com>
Thu, 27 Mar 2014 22:55:11 +0000 (15:55 -0700)
CopyRegInfo should not change live/dirty flags of new registgers.
Otherwise, it will lead to incorrectly clobbering these live registers
that are not live actually, and then allocating them to another usage.

Change-Id: Ia9f055b33a11a6d70c0aca1a9fe8639ecfb09464
Signed-off-by: Chao-ying Fu <chao-ying.fu@intel.com>
compiler/dex/quick/ralloc_util.cc
test/083-compiler-regressions/expected.txt
test/083-compiler-regressions/src/Main.java

index 137d5eb..39783a2 100644 (file)
@@ -743,11 +743,15 @@ void Mir2Lir::MarkInUse(RegStorage reg) {
 void Mir2Lir::CopyRegInfo(int new_reg, int old_reg) {
   RegisterInfo* new_info = GetRegInfo(new_reg);
   RegisterInfo* old_info = GetRegInfo(old_reg);
-  // Target temp status must not change
+  // Target temp, live, dirty status must not change
   bool is_temp = new_info->is_temp;
+  bool live = new_info->live;
+  bool dirty = new_info->dirty;
   *new_info = *old_info;
-  // Restore target's temp status
+  // Restore target's temp, live, dirty status
   new_info->is_temp = is_temp;
+  new_info->live = live;
+  new_info->dirty = dirty;
   new_info->reg = new_reg;
 }
 
index f6de0e7..05b1eeb 100644 (file)
@@ -17,3 +17,5 @@ longModTest passes
 testIfCcz passes
 ManyFloatArgs passes
 atomicLong passes
+LiveFlags passes trip 3
+LiveFlags passes trip 1
index 2745c27..007b762 100644 (file)
@@ -49,6 +49,7 @@ public class Main {
         MirOpSelectTests.testIfCcz();
         ManyFloatArgs();
         atomicLong();
+        LiveFlags.test();
     }
 
     public static void atomicLong() {
@@ -8928,3 +8929,34 @@ class MirOpSelectTests {
         }
     }
 }
+
+class LiveFlags {
+  private static void show_results(double a[], double b[], int trip) {
+    if ((a[0]+a[1]+b[0]+b[1]) == 0) {
+      System.out.println("LiveFlags passes trip " + trip);
+    } else {
+      System.out.println("LiveFlags fails trip " + trip);
+      System.out.println("a[0] = " + a[0] + " a[1] = " + a[1]);
+      System.out.println("b[0] = " + b[0] + " b[1] = " + b[1]);
+    }
+  }
+  static void test()
+  {
+    final double A[] = new double[2];
+    final double B[] = new double[2];
+    final double C[] = new double[2];
+    B[0] = B[1] = 0.0;
+    A[0] = A[1] = 0.0;
+    C[0] = C[1] = 0.0;
+    for (int i = 3; i >= 1; i--) {
+      if ( (i & 1) == 0) {
+        continue;
+      }
+      if ( (i & 2) != 0 ) {
+        B[1] = -B[1];
+      }
+      show_results(A, B, i);
+      A[0] = C[0]; A[1] = C[1];
+    }
+  }
+}