Browse Source

DUALNUM: Narrow unary minus.

Mike Pall 14 năm trước cách đây
mục cha
commit
dcbae09b1d
4 tập tin đã thay đổi với 30 bổ sung3 xóa
  1. 1 0
      src/lj_iropt.h
  2. 13 1
      src/lj_opt_fold.c
  3. 15 0
      src/lj_opt_narrow.c
  4. 1 2
      src/lj_record.c

+ 1 - 0
src/lj_iropt.h

@@ -141,6 +141,7 @@ LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_cindex(jit_State *J, TRef key);
 #endif
 LJ_FUNC TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc,
 				 TValue *vb, TValue *vc, IROp op);
+LJ_FUNC TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc);
 LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc);
 LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc);
 LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase);

+ 13 - 1
src/lj_opt_fold.c

@@ -701,7 +701,7 @@ LJFOLDF(shortcut_dropleft)
 }
 
 /* Note: no safe shortcuts with STRTO and TOSTR ("1e2" ==> +100 ==> "100"). */
-LJFOLD(NEG NEG KNUM)
+LJFOLD(NEG NEG any)
 LJFOLD(BNOT BNOT)
 LJFOLD(BSWAP BSWAP)
 LJFOLDF(shortcut_leftleft)
@@ -1067,6 +1067,18 @@ LJFOLDF(simplify_intsub_k)
   return RETRYFOLD;
 }
 
+LJFOLD(SUB KINT any)
+LJFOLD(SUB KINT64 any)
+LJFOLDF(simplify_intsub_kleft)
+{
+  if (fleft->o == IR_KINT ? (fleft->i == 0) : (ir_kint64(fleft)->u64 == 0)) {
+    fins->o = IR_NEG;  /* 0 - i ==> -i */
+    fins->op1 = fins->op2;
+    return RETRYFOLD;
+  }
+  return NEXTFOLD;
+}
+
 LJFOLD(ADD any KINT64)
 LJFOLDF(simplify_intadd_k64)
 {

+ 15 - 0
src/lj_opt_narrow.c

@@ -535,6 +535,21 @@ TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc,
   return emitir(IRTN(op), rb, rc);
 }
 
+/* Narrowing of unary minus operator. */
+TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc)
+{
+  if (tref_isstr(rc)) {
+    rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0);
+    lj_str_tonum(strV(vc), vc);
+  }
+  if (tref_isinteger(rc)) {
+    if ((uint32_t)numberVint(vc) != 0x80000000u)
+      return emitir(IRTGI(IR_SUBOV), lj_ir_kint(J, 0), rc);
+    rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
+  }
+  return emitir(IRTN(IR_NEG), rc, lj_ir_knum_neg(J));
+}
+
 /* Narrowing of modulo operator. */
 TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc)
 {

+ 1 - 2
src/lj_record.c

@@ -1666,8 +1666,7 @@ void lj_record_ins(jit_State *J)
 
   case BC_UNM:
     if (tref_isnumber_str(rc)) {
-      rc = lj_ir_tonum(J, rc);
-      rc = emitir(IRTN(IR_NEG), rc, lj_ir_knum_neg(J));
+      rc = lj_opt_narrow_unm(J, rc, &ix.tabv);
     } else {
       ix.tab = rc;
       copyTV(J->L, &ix.tabv, &ix.keyv);