diff options
| author | Mike Pall <mike> | 2011-05-05 15:49:11 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-05-05 15:49:11 +0200 |
| commit | 693b6297870c2360688509f3276295334a65ee66 (patch) | |
| tree | 0b853d4a75f30aaa9f5992db1ed6753a57d7cf44 /src | |
| parent | b760add618ea98f3b71290ce88d32718401aa67f (diff) | |
| download | luajit-693b6297870c2360688509f3276295334a65ee66.tar.gz luajit-693b6297870c2360688509f3276295334a65ee66.tar.bz2 luajit-693b6297870c2360688509f3276295334a65ee66.zip | |
Improve bytecode optimization of and/or operators.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_parse.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index 81c7c96e..992034eb 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
| @@ -258,8 +258,9 @@ static BCPos jmp_next(FuncState *fs, BCPos pc) | |||
| 258 | static int jmp_novalue(FuncState *fs, BCPos list) | 258 | static int jmp_novalue(FuncState *fs, BCPos list) |
| 259 | { | 259 | { |
| 260 | for (; list != NO_JMP; list = jmp_next(fs, list)) { | 260 | for (; list != NO_JMP; list = jmp_next(fs, list)) { |
| 261 | BCOp op = bc_op(fs->bcbase[list >= 1 ? list-1 : list].ins); | 261 | BCIns p = fs->bcbase[list >= 1 ? list-1 : list].ins; |
| 262 | if (!(op == BC_ISTC || op == BC_ISFC)) return 1; | 262 | if (!(bc_op(p) == BC_ISTC || bc_op(p) == BC_ISFC || bc_a(p) == NO_REG)) |
| 263 | return 1; | ||
| 263 | } | 264 | } |
| 264 | return 0; | 265 | return 0; |
| 265 | } | 266 | } |
| @@ -269,13 +270,20 @@ static int jmp_patchtestreg(FuncState *fs, BCPos pc, BCReg reg) | |||
| 269 | { | 270 | { |
| 270 | BCIns *ip = &fs->bcbase[pc >= 1 ? pc-1 : pc].ins; | 271 | BCIns *ip = &fs->bcbase[pc >= 1 ? pc-1 : pc].ins; |
| 271 | BCOp op = bc_op(*ip); | 272 | BCOp op = bc_op(*ip); |
| 272 | if (!(op == BC_ISTC || op == BC_ISFC)) | 273 | if (op == BC_ISTC || op == BC_ISFC) { |
| 274 | if (reg != NO_REG && reg != bc_d(*ip)) { | ||
| 275 | setbc_a(ip, reg); | ||
| 276 | } else { /* Nothing to store or already in the right register. */ | ||
| 277 | setbc_op(ip, op+(BC_IST-BC_ISTC)); | ||
| 278 | setbc_a(ip, 0); | ||
| 279 | } | ||
| 280 | } else if (bc_a(*ip) == NO_REG) { | ||
| 281 | if (reg == NO_REG) | ||
| 282 | *ip = BCINS_AJ(BC_JMP, bc_a(fs->bcbase[pc].ins), 0); | ||
| 283 | else | ||
| 284 | setbc_a(ip, reg); | ||
| 285 | } else { | ||
| 273 | return 0; /* Cannot patch other instructions. */ | 286 | return 0; /* Cannot patch other instructions. */ |
| 274 | if (reg != NO_REG && reg != bc_d(*ip)) { | ||
| 275 | setbc_a(ip, reg); | ||
| 276 | } else { /* Nothing to store or already in the right register. */ | ||
| 277 | setbc_op(ip, op+(BC_IST-BC_ISTC)); | ||
| 278 | setbc_a(ip, 0); | ||
| 279 | } | 287 | } |
| 280 | return 1; | 288 | return 1; |
| 281 | } | 289 | } |
| @@ -709,6 +717,8 @@ static void bcemit_branch_t(FuncState *fs, ExpDesc *e) | |||
| 709 | pc = NO_JMP; /* Never jump. */ | 717 | pc = NO_JMP; /* Never jump. */ |
| 710 | else if (e->k == VJMP) | 718 | else if (e->k == VJMP) |
| 711 | invertcond(fs, e), pc = e->u.s.info; | 719 | invertcond(fs, e), pc = e->u.s.info; |
| 720 | else if (e->k == VKFALSE || e->k == VKNIL) | ||
| 721 | expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs); | ||
| 712 | else | 722 | else |
| 713 | pc = bcemit_branch(fs, e, 0); | 723 | pc = bcemit_branch(fs, e, 0); |
| 714 | jmp_append(fs, &e->f, pc); | 724 | jmp_append(fs, &e->f, pc); |
| @@ -725,6 +735,8 @@ static void bcemit_branch_f(FuncState *fs, ExpDesc *e) | |||
| 725 | pc = NO_JMP; /* Never jump. */ | 735 | pc = NO_JMP; /* Never jump. */ |
| 726 | else if (e->k == VJMP) | 736 | else if (e->k == VJMP) |
| 727 | pc = e->u.s.info; | 737 | pc = e->u.s.info; |
| 738 | else if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE) | ||
| 739 | expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs); | ||
| 728 | else | 740 | else |
| 729 | pc = bcemit_branch(fs, e, 1); | 741 | pc = bcemit_branch(fs, e, 1); |
| 730 | jmp_append(fs, &e->t, pc); | 742 | jmp_append(fs, &e->t, pc); |
