Browse Source

Fix type-based alias analysis for XLOAD/XSTORE.

Mike Pall 14 years ago
parent
commit
9666cf52ce
1 changed files with 10 additions and 10 deletions
  1. 10 10
      src/lj_opt_mem.c

+ 10 - 10
src/lj_opt_mem.c

@@ -526,20 +526,22 @@ doemit:
 /* -- XLOAD forwarding and XSTORE elimination ----------------------------- */
 /* -- XLOAD forwarding and XSTORE elimination ----------------------------- */
 
 
 /* Alias analysis for XLOAD/XSTORE. */
 /* Alias analysis for XLOAD/XSTORE. */
-static AliasRet aa_xref(jit_State *J, IRIns *refa, IRIns *refb)
+static AliasRet aa_xref(jit_State *J, IRIns *xa, IRIns *xb)
 {
 {
   ptrdiff_t ofsa = 0, ofsb = 0;
   ptrdiff_t ofsa = 0, ofsb = 0;
+  IRIns *refa = IR(xa->op1), *refb = IR(xb->op1);
   IRIns *basea = refa, *baseb = refb;
   IRIns *basea = refa, *baseb = refb;
-  if (refa == refb)
-    return ALIAS_MUST;  /* Shortcut for same refs. */
   /* This implements (very) strict aliasing rules.
   /* This implements (very) strict aliasing rules.
   ** Different types do NOT alias, except for differences in signedness.
   ** Different types do NOT alias, except for differences in signedness.
   ** NYI: this also prevents type punning through unions.
   ** NYI: this also prevents type punning through unions.
   */
   */
-  if (!(irt_sametype(refa->t, refb->t) ||
-	(irt_typerange(refa->t, IRT_I8, IRT_INT) &&
-	 ((refa->t.irt - IRT_I8) ^ (refb->t.irt - IRT_I8)) == 1)))
+  if (irt_sametype(xa->t, xb->t)) {
+    if (refa == refb)
+      return ALIAS_MUST;  /* Shortcut for same refs with identical type. */
+  } else if (!(irt_typerange(xa->t, IRT_I8, IRT_INT) &&
+	       ((xa->t.irt - IRT_I8) ^ (xb->t.irt - IRT_I8)) == 1)) {
     return ALIAS_NO;
     return ALIAS_NO;
+  }
   /* Offset-based disambiguation. */
   /* Offset-based disambiguation. */
   if (refa->o == IR_ADD && irref_isk(refa->op2)) {
   if (refa->o == IR_ADD && irref_isk(refa->op2)) {
     IRIns *irk = IR(refa->op2);
     IRIns *irk = IR(refa->op2);
@@ -577,7 +579,6 @@ TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J)
 {
 {
   IRRef xref = fins->op1;
   IRRef xref = fins->op1;
   IRRef lim = xref;  /* Search limit. */
   IRRef lim = xref;  /* Search limit. */
-  IRIns *xr = IR(xref);
   IRRef ref;
   IRRef ref;
 
 
   if ((fins->op2 & IRXLOAD_READONLY))
   if ((fins->op2 & IRXLOAD_READONLY))
@@ -587,7 +588,7 @@ TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J)
   ref = J->chain[IR_XSTORE];
   ref = J->chain[IR_XSTORE];
   while (ref > xref) {
   while (ref > xref) {
     IRIns *store = IR(ref);
     IRIns *store = IR(ref);
-    switch (aa_xref(J, xr, IR(store->op1))) {
+    switch (aa_xref(J, fins, store)) {
     case ALIAS_NO:   break;  /* Continue searching. */
     case ALIAS_NO:   break;  /* Continue searching. */
     case ALIAS_MAY:  lim = ref; goto cselim;  /* Limit search for load. */
     case ALIAS_MAY:  lim = ref; goto cselim;  /* Limit search for load. */
     case ALIAS_MUST: return store->op2;  /* Store forwarding. */
     case ALIAS_MUST: return store->op2;  /* Store forwarding. */
@@ -612,12 +613,11 @@ TRef LJ_FASTCALL lj_opt_dse_xstore(jit_State *J)
 {
 {
   IRRef xref = fins->op1;
   IRRef xref = fins->op1;
   IRRef val = fins->op2;  /* Stored value reference. */
   IRRef val = fins->op2;  /* Stored value reference. */
-  IRIns *xr = IR(xref);
   IRRef1 *refp = &J->chain[IR_XSTORE];
   IRRef1 *refp = &J->chain[IR_XSTORE];
   IRRef ref = *refp;
   IRRef ref = *refp;
   while (ref > xref) {  /* Search for redundant or conflicting stores. */
   while (ref > xref) {  /* Search for redundant or conflicting stores. */
     IRIns *store = IR(ref);
     IRIns *store = IR(ref);
-    switch (aa_xref(J, xr, IR(store->op1))) {
+    switch (aa_xref(J, fins, store)) {
     case ALIAS_NO:
     case ALIAS_NO:
       break;  /* Continue searching. */
       break;  /* Continue searching. */
     case ALIAS_MAY:
     case ALIAS_MAY: