diff options
| author | Mike Pall <mike> | 2010-12-08 21:03:45 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-12-08 21:03:45 +0100 |
| commit | 4f0d3e8262506bccbb80a5cf265aea56bb778bb0 (patch) | |
| tree | f21e324728b86958acf1b2e7b2aa3b0c7f867edc | |
| parent | f308e00e03c28227cade61c9429dbf3ac526eb9a (diff) | |
| download | luajit-4f0d3e8262506bccbb80a5cf265aea56bb778bb0.tar.gz luajit-4f0d3e8262506bccbb80a5cf265aea56bb778bb0.tar.bz2 luajit-4f0d3e8262506bccbb80a5cf265aea56bb778bb0.zip | |
Apply narrowing optimization to IR_TOI64, too.
| -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); |
