diff options
| author | Mike Pall <mike> | 2010-12-20 15:26:05 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-12-20 15:26:05 +0100 |
| commit | c9a0b9ea9e78f476cf42bd38543ceb2218fa8670 (patch) | |
| tree | 32b5fedc9bc2ad18acc8dd884acfba2afbfb5edf | |
| parent | 255c6e8c874f4ecc8ff26e67387e1381acb12da8 (diff) | |
| download | luajit-c9a0b9ea9e78f476cf42bd38543ceb2218fa8670.tar.gz luajit-c9a0b9ea9e78f476cf42bd38543ceb2218fa8670.tar.bz2 luajit-c9a0b9ea9e78f476cf42bd38543ceb2218fa8670.zip | |
Improve alias analysis for cdata allocations.
| -rw-r--r-- | src/lj_opt_mem.c | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c index c7e8df60..db0ef21e 100644 --- a/src/lj_opt_mem.c +++ b/src/lj_opt_mem.c | |||
| @@ -37,10 +37,22 @@ typedef enum { | |||
| 37 | 37 | ||
| 38 | /* -- ALOAD/HLOAD forwarding and ASTORE/HSTORE elimination ---------------- */ | 38 | /* -- ALOAD/HLOAD forwarding and ASTORE/HSTORE elimination ---------------- */ |
| 39 | 39 | ||
| 40 | /* Simplified escape analysis: check for intervening stores. */ | ||
| 41 | static AliasRet aa_escape(jit_State *J, IRIns *ir, IRIns *stop) | ||
| 42 | { | ||
| 43 | IRRef ref = ir - J->cur.ir; /* The reference that might be stored. */ | ||
| 44 | for (ir++; ir < stop; ir++) | ||
| 45 | if (ir->op2 == ref && | ||
| 46 | (ir->o == IR_ASTORE || ir->o == IR_HSTORE || | ||
| 47 | ir->o == IR_USTORE || ir->o == IR_FSTORE)) | ||
| 48 | return ALIAS_MAY; /* Reference was stored and might alias. */ | ||
| 49 | return ALIAS_NO; /* Reference was not stored. */ | ||
| 50 | } | ||
| 51 | |||
| 40 | /* Alias analysis for two different table references. */ | 52 | /* Alias analysis for two different table references. */ |
| 41 | static AliasRet aa_table(jit_State *J, IRRef ta, IRRef tb) | 53 | static AliasRet aa_table(jit_State *J, IRRef ta, IRRef tb) |
| 42 | { | 54 | { |
| 43 | IRIns *ir, *taba = IR(ta), *tabb = IR(tb); | 55 | IRIns *taba = IR(ta), *tabb = IR(tb); |
| 44 | int newa, newb; | 56 | int newa, newb; |
| 45 | lua_assert(ta != tb); | 57 | lua_assert(ta != tb); |
| 46 | lua_assert(irt_istab(taba->t) && irt_istab(tabb->t)); | 58 | lua_assert(irt_istab(taba->t) && irt_istab(tabb->t)); |
| @@ -50,21 +62,11 @@ static AliasRet aa_table(jit_State *J, IRRef ta, IRRef tb) | |||
| 50 | if (newa && newb) | 62 | if (newa && newb) |
| 51 | return ALIAS_NO; /* Two different allocations never alias. */ | 63 | return ALIAS_NO; /* Two different allocations never alias. */ |
| 52 | if (newb) { /* At least one allocation? */ | 64 | if (newb) { /* At least one allocation? */ |
| 53 | IRRef tmp = ta; ta = tb; tb = tmp; | 65 | IRIns *tmp = taba; taba = tabb; tabb = tmp; |
| 54 | } else if (!newa) { | 66 | } else if (!newa) { |
| 55 | return ALIAS_MAY; /* Anything else: we just don't know. */ | 67 | return ALIAS_MAY; /* Anything else: we just don't know. */ |
| 56 | } | 68 | } |
| 57 | /* Now ta holds the allocation, tb the other table reference. | 69 | return aa_escape(J, taba, tabb); |
| 58 | ** The allocation might be stored and reloaded as tb. So perform a | ||
| 59 | ** simplified escape analysis: check for intervening stores which have | ||
| 60 | ** the allocation as the right operand. | ||
| 61 | */ | ||
| 62 | for (ir = IR(ta+1); ir < IR(tb); ir++) | ||
| 63 | if (ir->op2 == ta && | ||
| 64 | (ir->o == IR_ASTORE || ir->o == IR_HSTORE || | ||
| 65 | ir->o == IR_USTORE || ir->o == IR_FSTORE)) | ||
| 66 | return ALIAS_MAY; /* Allocation was stored and might alias. */ | ||
| 67 | return ALIAS_NO; /* Allocation doesn't alias the other reference. */ | ||
| 68 | } | 70 | } |
| 69 | 71 | ||
| 70 | /* Alias analysis for array and hash access using key-based disambiguation. */ | 72 | /* Alias analysis for array and hash access using key-based disambiguation. */ |
| @@ -525,6 +527,33 @@ doemit: | |||
| 525 | 527 | ||
| 526 | /* -- XLOAD forwarding and XSTORE elimination ----------------------------- */ | 528 | /* -- XLOAD forwarding and XSTORE elimination ----------------------------- */ |
| 527 | 529 | ||
| 530 | /* Find cdata allocation for a reference (if any). */ | ||
| 531 | static IRIns *aa_findcnew(jit_State *J, IRIns *ir) | ||
| 532 | { | ||
| 533 | while (ir->o == IR_ADD) { | ||
| 534 | if (!irref_isk(ir->op1)) { | ||
| 535 | IRIns *ir1 = aa_findcnew(J, IR(ir->op1)); /* Left-recursion. */ | ||
| 536 | if (ir1) return ir1; | ||
| 537 | } | ||
| 538 | if (irref_isk(ir->op2)) return NULL; | ||
| 539 | ir = IR(ir->op2); /* Flatten right-recursion. */ | ||
| 540 | } | ||
| 541 | return ir->o == IR_CNEW ? ir : NULL; | ||
| 542 | } | ||
| 543 | |||
| 544 | /* Alias analysis for two cdata allocations. */ | ||
| 545 | static AliasRet aa_cnew(jit_State *J, IRIns *refa, IRIns *refb) | ||
| 546 | { | ||
| 547 | IRIns *cnewa = aa_findcnew(J, refa); | ||
| 548 | IRIns *cnewb = aa_findcnew(J, refb); | ||
| 549 | if (cnewa == cnewb) | ||
| 550 | return ALIAS_MAY; /* Same allocation or neither is an allocation. */ | ||
| 551 | if (cnewa && cnewb) | ||
| 552 | return ALIAS_NO; /* Two different allocations never alias. */ | ||
| 553 | if (cnewb) { cnewa = cnewb; refb = refa; } | ||
| 554 | return aa_escape(J, cnewa, refb); | ||
| 555 | } | ||
| 556 | |||
| 528 | /* Alias analysis for XLOAD/XSTORE. */ | 557 | /* Alias analysis for XLOAD/XSTORE. */ |
| 529 | static AliasRet aa_xref(jit_State *J, IRIns *xa, IRIns *xb) | 558 | static AliasRet aa_xref(jit_State *J, IRIns *xa, IRIns *xb) |
| 530 | { | 559 | { |
| @@ -570,8 +599,7 @@ static AliasRet aa_xref(jit_State *J, IRIns *xa, IRIns *xb) | |||
| 570 | return ALIAS_MAY; | 599 | return ALIAS_MAY; |
| 571 | } | 600 | } |
| 572 | /* NYI: structural disambiguation. */ | 601 | /* NYI: structural disambiguation. */ |
| 573 | /* NYI: disambiguate new allocations. */ | 602 | return aa_cnew(J, basea, baseb); /* Try to disambiguate allocations. */ |
| 574 | return ALIAS_MAY; | ||
| 575 | } | 603 | } |
| 576 | 604 | ||
| 577 | /* XLOAD forwarding. */ | 605 | /* XLOAD forwarding. */ |
