diff options
| author | Mike Pall <mike> | 2010-09-14 16:48:52 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-09-14 16:48:52 +0200 |
| commit | 23655bd52ebffd0a4bdb9d34009816f9ca501f04 (patch) | |
| tree | 7b606a71de030fd18957de134640ceb26fea3d3d | |
| parent | b69c02eb68b91af7f45c45fcc6a70526d4d62797 (diff) | |
| download | luajit-23655bd52ebffd0a4bdb9d34009816f9ca501f04.tar.gz luajit-23655bd52ebffd0a4bdb9d34009816f9ca501f04.tar.bz2 luajit-23655bd52ebffd0a4bdb9d34009816f9ca501f04.zip | |
Improve alias analysis for vararg loads.
| -rw-r--r-- | src/lj_opt_mem.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c index 042d6081..c862e67e 100644 --- a/src/lj_opt_mem.c +++ b/src/lj_opt_mem.c | |||
| @@ -102,13 +102,16 @@ static TRef fwd_ahload(jit_State *J, IRRef xref) | |||
| 102 | IRRef lim = xref; /* Search limit. */ | 102 | IRRef lim = xref; /* Search limit. */ |
| 103 | IRRef ref; | 103 | IRRef ref; |
| 104 | 104 | ||
| 105 | if (IR(xr->op1)->o != IR_FLOAD) /* Varargs have no corresponding stores. */ | ||
| 106 | goto cselim; | ||
| 107 | |||
| 105 | /* Search for conflicting stores. */ | 108 | /* Search for conflicting stores. */ |
| 106 | ref = J->chain[fins->o+IRDELTA_L2S]; | 109 | ref = J->chain[fins->o+IRDELTA_L2S]; |
| 107 | while (ref > xref) { | 110 | while (ref > xref) { |
| 108 | IRIns *store = IR(ref); | 111 | IRIns *store = IR(ref); |
| 109 | switch (aa_ahref(J, xr, IR(store->op1))) { | 112 | switch (aa_ahref(J, xr, IR(store->op1))) { |
| 110 | case ALIAS_NO: break; /* Continue searching. */ | 113 | case ALIAS_NO: break; /* Continue searching. */ |
| 111 | case ALIAS_MAY: lim = ref; goto conflict; /* Limit search for load. */ | 114 | case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */ |
| 112 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ | 115 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ |
| 113 | } | 116 | } |
| 114 | ref = store->prev; | 117 | ref = store->prev; |
| @@ -129,7 +132,7 @@ static TRef fwd_ahload(jit_State *J, IRRef xref) | |||
| 129 | while (ref2 > tab) { | 132 | while (ref2 > tab) { |
| 130 | IRIns *newref = IR(ref2); | 133 | IRIns *newref = IR(ref2); |
| 131 | if (irt_isnum(IR(newref->op2)->t)) | 134 | if (irt_isnum(IR(newref->op2)->t)) |
| 132 | goto conflict; | 135 | goto cselim; |
| 133 | ref2 = newref->prev; | 136 | ref2 = newref->prev; |
| 134 | } | 137 | } |
| 135 | } | 138 | } |
| @@ -142,7 +145,7 @@ static TRef fwd_ahload(jit_State *J, IRRef xref) | |||
| 142 | IRIns *store = IR(ref); | 145 | IRIns *store = IR(ref); |
| 143 | switch (aa_ahref(J, xr, IR(store->op1))) { | 146 | switch (aa_ahref(J, xr, IR(store->op1))) { |
| 144 | case ALIAS_NO: break; /* Continue searching. */ | 147 | case ALIAS_NO: break; /* Continue searching. */ |
| 145 | case ALIAS_MAY: goto conflict; /* Conflicting store. */ | 148 | case ALIAS_MAY: goto cselim; /* Conflicting store. */ |
| 146 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ | 149 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ |
| 147 | } | 150 | } |
| 148 | ref = store->prev; | 151 | ref = store->prev; |
| @@ -167,7 +170,7 @@ static TRef fwd_ahload(jit_State *J, IRRef xref) | |||
| 167 | } | 170 | } |
| 168 | } | 171 | } |
| 169 | 172 | ||
| 170 | conflict: | 173 | cselim: |
| 171 | /* Try to find a matching load. Below the conflicting store, if any. */ | 174 | /* Try to find a matching load. Below the conflicting store, if any. */ |
| 172 | ref = J->chain[fins->o]; | 175 | ref = J->chain[fins->o]; |
| 173 | while (ref > lim) { | 176 | while (ref > lim) { |
| @@ -333,13 +336,13 @@ TRef LJ_FASTCALL lj_opt_fwd_uload(jit_State *J) | |||
| 333 | IRIns *store = IR(ref); | 336 | IRIns *store = IR(ref); |
| 334 | switch (aa_uref(xr, IR(store->op1))) { | 337 | switch (aa_uref(xr, IR(store->op1))) { |
| 335 | case ALIAS_NO: break; /* Continue searching. */ | 338 | case ALIAS_NO: break; /* Continue searching. */ |
| 336 | case ALIAS_MAY: lim = ref; goto conflict; /* Limit search for load. */ | 339 | case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */ |
| 337 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ | 340 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ |
| 338 | } | 341 | } |
| 339 | ref = store->prev; | 342 | ref = store->prev; |
| 340 | } | 343 | } |
| 341 | 344 | ||
| 342 | conflict: | 345 | cselim: |
| 343 | /* Try to find a matching load. Below the conflicting store, if any. */ | 346 | /* Try to find a matching load. Below the conflicting store, if any. */ |
| 344 | return lj_opt_cselim(J, lim); | 347 | return lj_opt_cselim(J, lim); |
| 345 | } | 348 | } |
| @@ -417,7 +420,7 @@ TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J) | |||
| 417 | IRIns *store = IR(ref); | 420 | IRIns *store = IR(ref); |
| 418 | switch (aa_fref(fins, IR(store->op1))) { | 421 | switch (aa_fref(fins, IR(store->op1))) { |
| 419 | case ALIAS_NO: break; /* Continue searching. */ | 422 | case ALIAS_NO: break; /* Continue searching. */ |
| 420 | case ALIAS_MAY: lim = ref; goto conflict; /* Limit search for load. */ | 423 | case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */ |
| 421 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ | 424 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ |
| 422 | } | 425 | } |
| 423 | ref = store->prev; | 426 | ref = store->prev; |
| @@ -430,7 +433,7 @@ TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J) | |||
| 430 | return lj_ir_knull(J, IRT_TAB); | 433 | return lj_ir_knull(J, IRT_TAB); |
| 431 | } | 434 | } |
| 432 | 435 | ||
| 433 | conflict: | 436 | cselim: |
| 434 | /* Try to find a matching load. Below the conflicting store, if any. */ | 437 | /* Try to find a matching load. Below the conflicting store, if any. */ |
| 435 | return lj_opt_cselim(J, lim); | 438 | return lj_opt_cselim(J, lim); |
| 436 | } | 439 | } |
