diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_opt_fold.c | 2 | ||||
-rw-r--r-- | src/lj_opt_narrow.c | 33 |
2 files changed, 25 insertions, 10 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 8fc646c9..d650f09c 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
@@ -644,6 +644,8 @@ LJFOLD(TOINT ADD any) | |||
644 | LJFOLD(TOINT SUB any) | 644 | LJFOLD(TOINT SUB any) |
645 | LJFOLD(TOBIT ADD KNUM) | 645 | LJFOLD(TOBIT ADD KNUM) |
646 | LJFOLD(TOBIT SUB KNUM) | 646 | LJFOLD(TOBIT SUB KNUM) |
647 | LJFOLD(TOI64 ADD any) | ||
648 | LJFOLD(TOI64 SUB any) | ||
647 | LJFOLDF(narrow_convert) | 649 | LJFOLDF(narrow_convert) |
648 | { | 650 | { |
649 | PHIBARRIER(fleft); | 651 | PHIBARRIER(fleft); |
diff --git a/src/lj_opt_narrow.c b/src/lj_opt_narrow.c index 688cc7b4..b6615f32 100644 --- a/src/lj_opt_narrow.c +++ b/src/lj_opt_narrow.c | |||
@@ -193,15 +193,15 @@ typedef struct NarrowConv { | |||
193 | } NarrowConv; | 193 | } NarrowConv; |
194 | 194 | ||
195 | /* Lookup a reference in the backpropagation cache. */ | 195 | /* Lookup a reference in the backpropagation cache. */ |
196 | static IRRef narrow_bpc_get(jit_State *J, IRRef1 key, IRRef mode) | 196 | static BPropEntry *narrow_bpc_get(jit_State *J, IRRef1 key, IRRef mode) |
197 | { | 197 | { |
198 | ptrdiff_t i; | 198 | ptrdiff_t i; |
199 | for (i = 0; i < BPROP_SLOTS; i++) { | 199 | for (i = 0; i < BPROP_SLOTS; i++) { |
200 | BPropEntry *bp = &J->bpropcache[i]; | 200 | BPropEntry *bp = &J->bpropcache[i]; |
201 | if (bp->key == key && bp->mode <= mode) /* Stronger checks are ok, too. */ | 201 | if (bp->key == key && bp->mode <= mode) /* Stronger checks are ok, too. */ |
202 | return bp->val; | 202 | return bp; |
203 | } | 203 | } |
204 | return 0; | 204 | return NULL; |
205 | } | 205 | } |
206 | 206 | ||
207 | /* Add an entry to the backpropagation cache. */ | 207 | /* Add an entry to the backpropagation cache. */ |
@@ -225,6 +225,10 @@ static int narrow_conv_backprop(NarrowConv *nc, IRRef ref, int depth) | |||
225 | /* Check the easy cases first. */ | 225 | /* Check the easy cases first. */ |
226 | if (ir->o == IR_TONUM) { /* Undo inverse conversion. */ | 226 | if (ir->o == IR_TONUM) { /* Undo inverse conversion. */ |
227 | *nc->sp++ = NARROWINS(NARROW_REF, ir->op1); | 227 | *nc->sp++ = NARROWINS(NARROW_REF, ir->op1); |
228 | if (nc->mode == IRTOINT_TRUNCI64) { | ||
229 | *nc->sp++ = NARROWINS(NARROW_REF, IRTOINT_SEXT64); | ||
230 | *nc->sp++ = NARROWINS(IRT(IR_TOI64, IRT_I64), 0); | ||
231 | } | ||
228 | return 0; | 232 | return 0; |
229 | } else if (ir->o == IR_KNUM) { /* Narrow FP constant. */ | 233 | } else if (ir->o == IR_KNUM) { /* Narrow FP constant. */ |
230 | lua_Number n = ir_knum(ir)->n; | 234 | lua_Number n = ir_knum(ir)->n; |
@@ -257,12 +261,17 @@ static int narrow_conv_backprop(NarrowConv *nc, IRRef ref, int depth) | |||
257 | /* Backpropagate across ADD/SUB. */ | 261 | /* Backpropagate across ADD/SUB. */ |
258 | if (ir->o == IR_ADD || ir->o == IR_SUB) { | 262 | if (ir->o == IR_ADD || ir->o == IR_SUB) { |
259 | /* Try cache lookup first. */ | 263 | /* Try cache lookup first. */ |
260 | IRRef bpref, mode = nc->mode; | 264 | IRRef mode = nc->mode; |
265 | BPropEntry *bp; | ||
261 | if (mode == IRTOINT_INDEX && depth > 0) | 266 | if (mode == IRTOINT_INDEX && depth > 0) |
262 | mode = IRTOINT_CHECK; /* Inner conversions need a stronger check. */ | 267 | mode = IRTOINT_CHECK; /* Inner conversions need a stronger check. */ |
263 | bpref = narrow_bpc_get(nc->J, (IRRef1)ref, mode); | 268 | bp = narrow_bpc_get(nc->J, (IRRef1)ref, mode); |
264 | if (bpref) { | 269 | if (bp) { |
265 | *nc->sp++ = NARROWINS(NARROW_REF, bpref); | 270 | *nc->sp++ = NARROWINS(NARROW_REF, bp->val); |
271 | if (mode == IRTOINT_TRUNCI64 && mode != bp->mode) { | ||
272 | *nc->sp++ = NARROWINS(NARROW_REF, IRTOINT_SEXT64); | ||
273 | *nc->sp++ = NARROWINS(IRT(IR_TOI64, IRT_I64), 0); | ||
274 | } | ||
266 | return 0; | 275 | return 0; |
267 | } | 276 | } |
268 | if (++depth < NARROW_MAX_BACKPROP && nc->sp < nc->maxsp) { | 277 | if (++depth < NARROW_MAX_BACKPROP && nc->sp < nc->maxsp) { |
@@ -270,7 +279,8 @@ static int narrow_conv_backprop(NarrowConv *nc, IRRef ref, int depth) | |||
270 | int count = narrow_conv_backprop(nc, ir->op1, depth); | 279 | int count = narrow_conv_backprop(nc, ir->op1, depth); |
271 | count += narrow_conv_backprop(nc, ir->op2, depth); | 280 | count += narrow_conv_backprop(nc, ir->op2, depth); |
272 | if (count <= nc->lim) { /* Limit total number of conversions. */ | 281 | if (count <= nc->lim) { /* Limit total number of conversions. */ |
273 | *nc->sp++ = NARROWINS(IRTI(ir->o), ref); | 282 | IRType t = mode == IRTOINT_TRUNCI64 ? IRT_I64 : IRT_INT; |
283 | *nc->sp++ = NARROWINS(IRT(ir->o, t), ref); | ||
274 | return count; | 284 | return count; |
275 | } | 285 | } |
276 | nc->sp = savesp; /* Too many conversions, need to backtrack. */ | 286 | nc->sp = savesp; /* Too many conversions, need to backtrack. */ |
@@ -301,7 +311,9 @@ static IRRef narrow_conv_emit(jit_State *J, NarrowConv *nc) | |||
301 | *sp++ = emitir_raw(convot, ref, convop2); /* Raw emit avoids a loop. */ | 311 | *sp++ = emitir_raw(convot, ref, convop2); /* Raw emit avoids a loop. */ |
302 | } else if (op == NARROW_INT) { | 312 | } else if (op == NARROW_INT) { |
303 | lua_assert(next < last); | 313 | lua_assert(next < last); |
304 | *sp++ = lj_ir_kint(J, *next++); | 314 | *sp++ = nc->mode == IRTOINT_TRUNCI64 ? |
315 | lj_ir_kint64(J, (int64_t)(int32_t)*next++) : | ||
316 | lj_ir_kint(J, *next++); | ||
305 | } else { /* Regular IROpT. Pops two operands and pushes one result. */ | 317 | } else { /* Regular IROpT. Pops two operands and pushes one result. */ |
306 | IRRef mode = nc->mode; | 318 | IRRef mode = nc->mode; |
307 | lua_assert(sp >= nc->stack+2); | 319 | lua_assert(sp >= nc->stack+2); |
@@ -316,7 +328,8 @@ static IRRef narrow_conv_emit(jit_State *J, NarrowConv *nc) | |||
316 | } | 328 | } |
317 | sp[-1] = emitir(op+guardot, sp[-1], sp[0]); | 329 | sp[-1] = emitir(op+guardot, sp[-1], sp[0]); |
318 | /* Add to cache. */ | 330 | /* Add to cache. */ |
319 | narrow_bpc_set(J, narrow_ref(ref), narrow_ref(sp[-1]), mode); | 331 | if (narrow_ref(ref)) |
332 | narrow_bpc_set(J, narrow_ref(ref), narrow_ref(sp[-1]), mode); | ||
320 | } | 333 | } |
321 | } | 334 | } |
322 | lua_assert(sp == nc->stack+1); | 335 | lua_assert(sp == nc->stack+1); |