/* ULOAD forwarding. */ TRef LJ_FASTCALL lj_opt_fwd_uload(jit_State *J) { IRRef uref = fins->op1; IRRef lim = REF_BASE; /* Search limit. */ IRIns *xr = IR(uref); IRRef ref; /* Search for conflicting stores. */ ref = J->chain[IR_USTORE]; while (ref > lim) { IRIns *store = IR(ref); switch (aa_uref(xr, IR(store->op1))) { case ALIAS_NO: break; /* Continue searching. */ case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */ case ALIAS_MUST: return store->op2; /* Store forwarding. */ } ref = store->prev; } cselim: /* Try to find a matching load. Below the conflicting store, if any. */ ref = J->chain[IR_ULOAD]; while (ref > lim) { IRIns *ir = IR(ref); if (ir->op1 == uref || (IR(ir->op1)->op12 == IR(uref)->op12 && IR(ir->op1)->o == IR(uref)->o)) return ref; /* Match for identical or equal UREFx (non-CSEable UREFO). */ ref = ir->prev; } return lj_ir_emit(J); }
/* This is rather simplistic right now, but better than nothing. */ TRef LJ_FASTCALL lj_opt_fwd_tab_len(jit_State *J) { IRRef tab = fins->op1; /* Table reference. */ IRRef lim = tab; /* Search limit. */ IRRef ref; /* Any ASTORE is a conflict and limits the search. */ if (J->chain[IR_ASTORE] > lim) lim = J->chain[IR_ASTORE]; /* Search for conflicting HSTORE with numeric key. */ ref = J->chain[IR_HSTORE]; while (ref > lim) { IRIns *store = IR(ref); IRIns *href = IR(store->op1); IRIns *key = IR(href->op2); if (irt_isnum(key->o == IR_KSLOT ? IR(key->op1)->t : key->t)) { lim = ref; /* Conflicting store found, limits search for TLEN. */ break; } ref = store->prev; } /* Search for aliasing table.clear. */ if (!fwd_aa_tab_clear(J, lim, tab)) return lj_ir_emit(J); /* Try to find a matching load. Below the conflicting store, if any. */ return lj_opt_cselim(J, lim); }