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. */ |