Skip to content

Commit

Permalink
Remove DUALNUM mode
Browse files Browse the repository at this point in the history
DUALNUM mode is a complex optional feature, disabled by default on
x86-64, that allows numbers to be stored on the heap either as doubles
(the usual) or as integers (the extension.)

This requires a _LOT_ of ifdef-style conditional logic throughout the
VM and runtime system. My tests have never found a verifiable benefit
to the dual number mode and since it is already disabled by default on
x86-64 I have simply removed it.

This change is a bit scary because it is large and I have mostly made
it manually. The conditional uses of DUALNUM were not ones that I
could remove automatically with 'unifdef'. I have surely made a
mistake in here somewhere and that will surely bit somebody on the
backside one day... Sorry in advance, but meanwhile, onward!
  • Loading branch information
lukego committed Mar 17, 2017
1 parent 0632142 commit fa02289
Show file tree
Hide file tree
Showing 34 changed files with 91 additions and 862 deletions.
3 changes: 0 additions & 3 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,6 @@ endif
ifneq (,$(findstring LJ_HASFFI 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D FFI
endif
ifneq (,$(findstring LJ_DUALNUM 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D DUALNUM
endif
ifneq (,$(findstring LJ_ARCH_HASFPU 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D FPU
TARGET_ARCH+= -DLJ_ARCH_HASFPU=1
Expand Down
2 changes: 1 addition & 1 deletion src/host/buildvm_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ static void libdef_fixupbc(uint8_t *p)
uint8_t ra = p[libbc_endian ? 2 : 1];
uint8_t rc = p[libbc_endian ? 1 : 2];
uint8_t rb = p[libbc_endian ? 0 : 3];
if (!LJ_DUALNUM && op == BC_ISTYPE && rc == ~LJ_TNUMX+1) {
if (op == BC_ISTYPE && rc == ~LJ_TNUMX+1) {
op = BC_ISNUM; rc++;
}
p[LJ_ENDIAN_SELECT(0, 3)] = op;
Expand Down
2 changes: 2 additions & 0 deletions src/ifdef-defile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define LJ_64 1
#define LJ_ARCH_BITS 64
#define LJ_ARCH_ENDIAN == LUAJIT_LE
#define LJ_DUALNUM 0
#define LJ_FR2 1
#define LJ_NUMMODE LJ_NUMMODE_SINGLE_DUAL
#define LJ_NUMMODE_DUAL 2
Expand Down Expand Up @@ -47,6 +48,7 @@
#define LUAJIT_ARCH_x64 2
#define LUAJIT_ARCH_x86 1
#define LUAJIT_LE 1
#define LUAJIT_NUMMODE=1
#define LUAJIT_OS LUAJIT_OS_LINUX
#define LUAJIT_OS_LINUX 2
#define LUAJIT_OS_WINDOWS 3
Expand Down
12 changes: 1 addition & 11 deletions src/lib_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,6 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
CType *ct = lj_ctype_rawref(cts, cdataV(o)->ctypeid);
if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
if (ctype_isnum(ct->info) || ctype_iscomplex(ct->info)) {
if (LJ_DUALNUM && ctype_isinteger_or_bool(ct->info) &&
ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) {
int32_t i;
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0);
setintV(L->base-1-LJ_FR2, i);
return FFH_RES(1);
}
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
(uint8_t *)&(L->base-1-LJ_FR2)->n, o, 0);
return FFH_RES(1);
Expand All @@ -286,10 +279,7 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
if (p != ep) {
while (lj_char_isspace((unsigned char)(*ep))) ep++;
if (*ep == '\0') {
if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u))
setintV(L->base-1-LJ_FR2, (int32_t)ul);
else
setnumV(L->base-1-LJ_FR2, (lua_Number)ul);
setnumV(L->base-1-LJ_FR2, (lua_Number)ul);
return FFH_RES(1);
}
}
Expand Down
11 changes: 1 addition & 10 deletions src/lib_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,6 @@ static int io_file_readnum(lua_State *L, FILE *fp)
{
lua_Number d;
if (fscanf(fp, LUA_NUMBER_SCAN, &d) == 1) {
if (LJ_DUALNUM) {
int32_t i = lj_num2int(d);
if (d == (lua_Number)i && !tvismzero((cTValue *)&d)) {
setintV(L->top++, i);
return 1;
}
}
setnumV(L->top++, d);
return 1;
} else {
Expand Down Expand Up @@ -311,9 +304,7 @@ LJLIB_CF(io_method_seek)
else if (opt == 2) opt = SEEK_END;
o = L->base+2;
if (o < L->top) {
if (tvisint(o))
ofs = (int64_t)intV(o);
else if (tvisnum(o))
if (tvisnum(o))
ofs = (int64_t)numV(o);
else if (!tvisnil(o))
lj_err_argt(L, 3, LUA_TNUMBER);
Expand Down
29 changes: 0 additions & 29 deletions src/lib_math.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,42 +157,13 @@ LJLIB_CF(math_random) LJLIB_REC(.)
u.u64 = lj_math_random_step(rs);
d = u.d - 1.0;
if (n > 0) {
#if LJ_DUALNUM
int isint = 1;
double r1;
lj_lib_checknumber(L, 1);
if (tvisint(L->base)) {
r1 = (lua_Number)intV(L->base);
} else {
isint = 0;
r1 = numV(L->base);
}
#else
double r1 = lj_lib_checknum(L, 1);
#endif
if (n == 1) {
d = lj_vm_floor(d*r1) + 1.0; /* d is an int in range [1, r1] */
} else {
#if LJ_DUALNUM
double r2;
lj_lib_checknumber(L, 2);
if (tvisint(L->base+1)) {
r2 = (lua_Number)intV(L->base+1);
} else {
isint = 0;
r2 = numV(L->base+1);
}
#else
double r2 = lj_lib_checknum(L, 2);
#endif
d = lj_vm_floor(d*(r2-r1+1.0)) + r1; /* d is an int in range [r1, r2] */
}
#if LJ_DUALNUM
if (isint) {
setintV(L->top-1, lj_num2int(d));
return 1;
}
#endif
} /* else: d is a double in range [0, 1] */
setnumV(L->top++, d);
return 1;
Expand Down
15 changes: 2 additions & 13 deletions src/lib_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,21 +681,10 @@ LJLIB_CF(string_format) LJLIB_REC(.)
luaL_argerror(L, arg, lj_obj_typename[0]);
switch (STRFMT_TYPE(sf)) {
case STRFMT_INT:
if (tvisint(L->base+arg-1)) {
int32_t k = intV(L->base+arg-1);
if (sf == STRFMT_INT)
lj_strfmt_putint(sb, k); /* Shortcut for plain %d. */
else
lj_strfmt_putfxint(sb, sf, k);
} else {
lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg));
}
lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg));
break;
case STRFMT_UINT:
if (tvisint(L->base+arg-1))
lj_strfmt_putfxint(sb, sf, intV(L->base+arg-1));
else
lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg));
lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg));
break;
case STRFMT_NUM:
lj_strfmt_putfnum(sb, sf, lj_lib_checknum(L, arg));
Expand Down
24 changes: 4 additions & 20 deletions src/lj_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,7 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
{
cTValue *o1 = index2adr(L, idx1);
cTValue *o2 = index2adr(L, idx2);
if (tvisint(o1) && tvisint(o2)) {
return intV(o1) == intV(o2);
} else if (tvisnumber(o1) && tvisnumber(o2)) {
if (tvisnumber(o1) && tvisnumber(o2)) {
return numberVnum(o1) == numberVnum(o2);
} else if (itype(o1) != itype(o2)) {
return 0;
Expand Down Expand Up @@ -284,8 +282,6 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
cTValue *o2 = index2adr(L, idx2);
if (o1 == niltv(L) || o2 == niltv(L)) {
return 0;
} else if (tvisint(o1) && tvisint(o2)) {
return intV(o1) < intV(o2);
} else if (tvisnumber(o1) && tvisnumber(o2)) {
return numberVnum(o1) < numberVnum(o2);
} else {
Expand Down Expand Up @@ -342,15 +338,11 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
cTValue *o = index2adr(L, idx);
TValue tmp;
lua_Number n;
if (LJ_LIKELY(tvisint(o))) {
return intV(o);
} else if (LJ_LIKELY(tvisnum(o))) {
if (LJ_LIKELY(tvisnum(o))) {
n = numV(o);
} else {
if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
return 0;
if (tvisint(&tmp))
return (lua_Integer)intV(&tmp);
n = numV(&tmp);
}
return (lua_Integer)n;
Expand All @@ -361,15 +353,11 @@ LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
cTValue *o = index2adr(L, idx);
TValue tmp;
lua_Number n;
if (LJ_LIKELY(tvisint(o))) {
return intV(o);
} else if (LJ_LIKELY(tvisnum(o))) {
if (LJ_LIKELY(tvisnum(o))) {
n = numV(o);
} else {
if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
lj_err_argt(L, idx, LUA_TNUMBER);
if (tvisint(&tmp))
return (lua_Integer)intV(&tmp);
n = numV(&tmp);
}
return (lua_Integer)n;
Expand All @@ -380,17 +368,13 @@ LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
cTValue *o = index2adr(L, idx);
TValue tmp;
lua_Number n;
if (LJ_LIKELY(tvisint(o))) {
return intV(o);
} else if (LJ_LIKELY(tvisnum(o))) {
if (LJ_LIKELY(tvisnum(o))) {
n = numV(o);
} else if (tvisnil(o)) {
return def;
} else {
if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
lj_err_argt(L, idx, LUA_TNUMBER);
if (tvisint(&tmp))
return (lua_Integer)intV(&tmp);
n = numV(&tmp);
}
return (lua_Integer)n;
Expand Down
20 changes: 0 additions & 20 deletions src/lj_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@



#define LJ_NUMMODE_SINGLE 0 /* Single-number mode only. */
#define LJ_NUMMODE_SINGLE_DUAL 1 /* Default to single-number mode. */
#define LJ_NUMMODE_DUAL 2 /* Dual-number mode only. */
#define LJ_NUMMODE_DUAL_SINGLE 3 /* Default to dual-number mode. */

/* Set target architecture properties. */

#define LJ_ARCH_NAME "x64"
Expand All @@ -75,7 +70,6 @@
#define LJ_TARGET_MASKSHIFT 1
#define LJ_TARGET_MASKROT 1
#define LJ_TARGET_UNALIGNED 1
#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE_DUAL
#define LJ_TARGET_GC64 1


Expand All @@ -97,20 +91,6 @@
#endif
#endif

/* Enable or disable the dual-number mode for the VM. */
#if (LJ_ARCH_NUMMODE == LJ_NUMMODE_SINGLE && LUAJIT_NUMMODE == 2) || \
(LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL && LUAJIT_NUMMODE == 1)
#error "No support for this number mode on this architecture"
#endif
#if LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL || \
(LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL_SINGLE && LUAJIT_NUMMODE != 1) || \
(LJ_ARCH_NUMMODE == LJ_NUMMODE_SINGLE_DUAL && LUAJIT_NUMMODE == 2)
#define LJ_DUALNUM 1
#else
#define LJ_DUALNUM 0
#endif


/* 64 bit GC references. */
#define LJ_GC64 1

Expand Down
35 changes: 11 additions & 24 deletions src/lj_asm_x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -1160,8 +1160,7 @@ static void asm_fxstore(ASMState *as, IRIns *ir)
static void asm_ahuvload(ASMState *as, IRIns *ir)
{
Reg tmp = RID_NONE;
lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t) ||
(LJ_DUALNUM && irt_isint(ir->t)));
lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t));
if (ra_used(ir)) {
RegSet allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR;
Reg dest = ra_dest(as, ir, allow);
Expand Down Expand Up @@ -1245,25 +1244,17 @@ static void asm_ahustore(ASMState *as, IRIns *ir)
}
asm_fuseahuref(as, ir->op1, allow);
if (ra_hasreg(src)) {
if (!(LJ_DUALNUM && irt_isinteger(ir->t))) {
/* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */
as->mrm.ofs += 4;
emit_u32(as, irt_toitype(ir->t) << 15);
emit_mrm(as, XO_ARITHi, XOg_OR, RID_MRM);
as->mrm.ofs -= 4;
emit_mrm(as, XO_MOVto, src|REX_64, RID_MRM);
return;
}
emit_mrm(as, XO_MOVto, src, RID_MRM);
} else if (!irt_ispri(irr->t)) {
lua_assert(irt_isaddr(ir->t) || (LJ_DUALNUM && irt_isinteger(ir->t)));
/* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */
as->mrm.ofs += 4;
emit_u32(as, irt_toitype(ir->t) << 15);
emit_mrm(as, XO_ARITHi, XOg_OR, RID_MRM);
as->mrm.ofs -= 4;
emit_mrm(as, XO_MOVto, src|REX_64, RID_MRM);
} else {
lua_assert(!irt_ispri(irr->t) && irt_isaddr(ir->t));
emit_i32(as, irr->i);
emit_mrm(as, XO_MOVmi, 0, RID_MRM);
}
as->mrm.ofs += 4;
lua_assert(LJ_DUALNUM && irt_isinteger(ir->t));
emit_i32(as, LJ_TNUMX << 15);
emit_mrm(as, XO_MOVmi, 0, RID_MRM);
}
}

Expand All @@ -1275,8 +1266,7 @@ static void asm_sload(ASMState *as, IRIns *ir)
Reg base;
lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK));
lua_assert(LJ_DUALNUM ||
!irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));
lua_assert(!irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));
if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
Reg left = ra_scratch(as, RSET_FPR);
asm_tointg(as, ir, left); /* Frees dest reg. Do this before base alloc. */
Expand Down Expand Up @@ -2150,16 +2140,13 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
Reg src = ra_alloc1(as, ref, RSET_FPR);
emit_rmro(as, XO_MOVSDto, src, RID_BASE, ofs);
} else {
lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) ||
(LJ_DUALNUM && irt_isinteger(ir->t)));
lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t));
if (!irref_isk(ref)) {
Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE));
if (irt_is64(ir->t)) {
/* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */
emit_u32(as, irt_toitype(ir->t) << 15);
emit_rmro(as, XO_ARITHi, XOg_OR, RID_BASE, ofs+4);
} else if (LJ_DUALNUM && irt_isinteger(ir->t)) {
emit_movmroi(as, RID_BASE, ofs+4, LJ_TISNUM << 15);
} else {
emit_movmroi(as, RID_BASE, ofs+4, (irt_toitype(ir->t)<<15)|0x7fff);
}
Expand Down
37 changes: 13 additions & 24 deletions src/lj_bcwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,8 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
p = lj_buf_more(&ctx->sb, 5+len);
p = lj_strfmt_wuleb128(p, BCDUMP_KTAB_STR+len);
p = lj_buf_wmem(p, strdata(str), len);
} else if (tvisint(o)) {
*p++ = BCDUMP_KTAB_INT;
p = lj_strfmt_wuleb128(p, intV(o));
} else if (tvisnum(o)) {
if (!LJ_DUALNUM && narrow) { /* Narrow number constants to integers. */
if (narrow) { /* Narrow number constants to integers. */
lua_Number num = numV(o);
int32_t k = lj_num2int(num);
if (num == (lua_Number)k) { /* -0 is never a constant. */
Expand Down Expand Up @@ -165,27 +162,19 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
char *p = lj_buf_more(&ctx->sb, 10*sizekn);
for (i = 0; i < sizekn; i++, o++) {
int32_t k;
if (tvisint(o)) {
k = intV(o);
goto save_int;
} else {
/* Write a 33 bit ULEB128 for the int (lsb=0) or loword (lsb=1). */
if (!LJ_DUALNUM) { /* Narrow number constants to integers. */
lua_Number num = numV(o);
k = lj_num2int(num);
if (num == (lua_Number)k) { /* -0 is never a constant. */
save_int:
p = lj_strfmt_wuleb128(p, 2*(uint32_t)k | ((uint32_t)k&0x80000000u));
if (k < 0)
p[-1] = (p[-1] & 7) | ((k>>27) & 0x18);
continue;
}
}
p = lj_strfmt_wuleb128(p, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u)));
if (o->u32.lo >= 0x80000000u)
p[-1] = (p[-1] & 7) | ((o->u32.lo>>27) & 0x18);
p = lj_strfmt_wuleb128(p, o->u32.hi);
/* Write a 33 bit ULEB128 for the int (lsb=0) or loword (lsb=1). */
lua_Number num = numV(o);
k = lj_num2int(num);
if (num == (lua_Number)k) { /* -0 is never a constant. */
p = lj_strfmt_wuleb128(p, 2*(uint32_t)k | ((uint32_t)k&0x80000000u));
if (k < 0)
p[-1] = (p[-1] & 7) | ((k>>27) & 0x18);
continue;
}
p = lj_strfmt_wuleb128(p, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u)));
if (o->u32.lo >= 0x80000000u)
p[-1] = (p[-1] & 7) | ((o->u32.lo>>27) & 0x18);
p = lj_strfmt_wuleb128(p, o->u32.hi);
}
setsbufP(&ctx->sb, p);
}
Expand Down
Loading

0 comments on commit fa02289

Please sign in to comment.