ソースを参照

Fix handling of redundant PHIs.

Mike Pall 12 年 前
コミット
8944e27762
1 ファイル変更15 行追加16 行削除
  1. 15 16
      src/lj_opt_loop.c

+ 15 - 16
src/lj_opt_loop.c

@@ -105,20 +105,24 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi,
 			  SnapNo onsnap)
 			  SnapNo onsnap)
 {
 {
   int passx = 0;
   int passx = 0;
-  IRRef i, nslots;
+  IRRef i, j, nslots;
   IRRef invar = J->chain[IR_LOOP];
   IRRef invar = J->chain[IR_LOOP];
   /* Pass #1: mark redundant and potentially redundant PHIs. */
   /* Pass #1: mark redundant and potentially redundant PHIs. */
-  for (i = 0; i < nphi; i++) {
+  for (i = 0, j = 0; i < nphi; i++) {
     IRRef lref = phi[i];
     IRRef lref = phi[i];
     IRRef rref = subst[lref];
     IRRef rref = subst[lref];
     if (lref == rref || rref == REF_DROP) {  /* Invariants are redundant. */
     if (lref == rref || rref == REF_DROP) {  /* Invariants are redundant. */
-      irt_setmark(IR(lref)->t);
-    } else if (!(IR(rref)->op1 == lref || IR(rref)->op2 == lref)) {
-      /* Quick check for simple recurrences failed, need pass2. */
-      irt_setmark(IR(lref)->t);
-      passx = 1;
+      irt_clearphi(IR(lref)->t);
+    } else {
+      phi[j++] = (IRRef1)lref;
+      if (!(IR(rref)->op1 == lref || IR(rref)->op2 == lref)) {
+	/* Quick check for simple recurrences failed, need pass2. */
+	irt_setmark(IR(lref)->t);
+	passx = 1;
+      }
     }
     }
   }
   }
+  nphi = j;
   /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */
   /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */
   if (passx) {
   if (passx) {
     SnapNo s;
     SnapNo s;
@@ -174,15 +178,10 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi,
       IRRef lref = phi[i];
       IRRef lref = phi[i];
       IRIns *ir = IR(lref);
       IRIns *ir = IR(lref);
       if (!irt_ismarked(ir->t)) {  /* Propagate only from unmarked PHIs. */
       if (!irt_ismarked(ir->t)) {  /* Propagate only from unmarked PHIs. */
-	IRRef rref = subst[lref];
-	if (lref == rref) {  /* Mark redundant PHI. */
-	  irt_setmark(ir->t);
-	} else {
-	  IRIns *irr = IR(rref);
-	  if (irt_ismarked(irr->t)) {  /* Right ref points to other PHI? */
-	    irt_clearmark(irr->t);  /* Mark that PHI as non-redundant. */
-	    passx = 1;  /* Retry. */
-	  }
+	IRIns *irr = IR(subst[lref]);
+	if (irt_ismarked(irr->t)) {  /* Right ref points to other PHI? */
+	  irt_clearmark(irr->t);  /* Mark that PHI as non-redundant. */
+	  passx = 1;  /* Retry. */
 	}
 	}
       }
       }
     }
     }