Skip to content

Commit

Permalink
Update IR
Browse files Browse the repository at this point in the history
IR commit: e445f57f3a936584db28489a49098d52f03388a7
  • Loading branch information
dstogov committed Jan 9, 2025
1 parent 28b448a commit 4763193
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 81 deletions.
145 changes: 119 additions & 26 deletions ext/opcache/jit/ir/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1283,9 +1283,11 @@ void ir_build_def_use_lists(ir_ctx *ctx)
void ir_use_list_remove_all(ir_ctx *ctx, ir_ref from, ir_ref ref)
{
ir_ref j, n, *p, *q, use;
ir_use_list *use_list = &ctx->use_lists[from];
ir_use_list *use_list;
ir_ref skip = 0;

IR_ASSERT(from > 0);
use_list = &ctx->use_lists[from];
n = use_list->count;
for (j = 0, p = q = &ctx->use_edges[use_list->refs]; j < n; j++, p++) {
use = *p;
Expand All @@ -1310,8 +1312,10 @@ void ir_use_list_remove_all(ir_ctx *ctx, ir_ref from, ir_ref ref)
void ir_use_list_remove_one(ir_ctx *ctx, ir_ref from, ir_ref ref)
{
ir_ref j, n, *p;
ir_use_list *use_list = &ctx->use_lists[from];
ir_use_list *use_list;

IR_ASSERT(from > 0);
use_list = &ctx->use_lists[from];
n = use_list->count;
j = 0;
p = &ctx->use_edges[use_list->refs];
Expand All @@ -1334,9 +1338,11 @@ void ir_use_list_remove_one(ir_ctx *ctx, ir_ref from, ir_ref ref)

void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use)
{
ir_use_list *use_list = &ctx->use_lists[ref];
ir_use_list *use_list;
ir_ref i, n, *p;

IR_ASSERT(ref > 0);
use_list = &ctx->use_lists[ref];
n = use_list->count;
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
if (*p == use) {
Expand All @@ -1348,9 +1354,11 @@ void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use

void ir_use_list_replace_all(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use)
{
ir_use_list *use_list = &ctx->use_lists[ref];
ir_use_list *use_list;
ir_ref i, n, *p;

IR_ASSERT(ref > 0);
use_list = &ctx->use_lists[ref];
n = use_list->count;
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
if (*p == use) {
Expand All @@ -1361,9 +1369,12 @@ void ir_use_list_replace_all(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use

bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref)
{
ir_use_list *use_list = &ctx->use_lists[to];
ir_ref n = use_list->refs + use_list->count;
ir_use_list *use_list;
ir_ref n;

IR_ASSERT(to > 0);
use_list = &ctx->use_lists[to];
n = use_list->refs + use_list->count;
if (n < ctx->use_edges_count && ctx->use_edges[n] == IR_UNUSED) {
ctx->use_edges[n] = ref;
use_list->count++;
Expand All @@ -1385,6 +1396,59 @@ bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref)
}
}

static int ir_ref_cmp(const void *p1, const void *p2)
{
return *(ir_ref*)p1 - *(ir_ref*)p2;
}

void ir_use_list_sort(ir_ctx *ctx, ir_ref ref)
{
ir_use_list *use_list;
uint32_t n;

IR_ASSERT(ref > 0);
use_list = &ctx->use_lists[ref];
n = use_list->count;
if (n > 1) {
qsort(ctx->use_edges + use_list->refs, n, sizeof(ir_ref), ir_ref_cmp);
}
}

void ir_replace(ir_ctx *ctx, ir_ref ref, ir_ref new_ref)
{
int i, j, n, use;
ir_insn *insn;

IR_ASSERT(ref != new_ref);
n = ctx->use_lists[ref].count;
for (i = 0; i < n; i++) {
use = ctx->use_edges[ctx->use_lists[ref].refs + i];
IR_ASSERT(use != ref);
insn = &ctx->ir_base[use];
j = ir_insn_find_op(insn, ref);
IR_ASSERT(j > 0);
ir_insn_set_op(insn, j, new_ref);
if (!IR_IS_CONST_REF(new_ref)) {
ir_use_list_add(ctx, new_ref, use);
}
}
}

void ir_update_op(ir_ctx *ctx, ir_ref ref, uint32_t idx, ir_ref new_val)
{
ir_insn *insn = &ctx->ir_base[ref];
ir_ref old_val = ir_insn_op(insn, idx);

IR_ASSERT(old_val != new_val);
if (new_val > 0) {
ir_use_list_add(ctx, new_val, ref);
}
ir_insn_set_op(insn, idx, new_val);
if (old_val > 0) {
ir_use_list_remove_one(ctx, old_val, ref);
}
}

/* Helper Data Types */
void ir_array_grow(ir_array *a, uint32_t size)
{
Expand Down Expand Up @@ -1428,16 +1492,16 @@ void ir_list_remove(ir_list *l, uint32_t i)
l->len--;
}

bool ir_list_contains(const ir_list *l, ir_ref val)
uint32_t ir_list_find(const ir_list *l, ir_ref val)
{
uint32_t i;

for (i = 0; i < l->len; i++) {
if (ir_array_at(&l->a, i) == val) {
return 1;
return i;
}
}
return 0;
return (uint32_t)-1;
}

static uint32_t ir_hashtab_hash_size(uint32_t size)
Expand Down Expand Up @@ -2010,18 +2074,22 @@ ir_ref _ir_PHI_N(ir_ctx *ctx, ir_type type, ir_ref n, ir_ref *inputs)
return inputs[0];
} else {
ir_ref i;
ir_ref ref = inputs[0];

IR_ASSERT(ctx->ir_base[ctx->control].op == IR_MERGE || ctx->ir_base[ctx->control].op == IR_LOOP_BEGIN);
if (ref != IR_UNUSED) {
for (i = 1; i < n; i++) {
if (inputs[i] != ref) {
break;
ir_ref ref;

if (UNEXPECTED(!(ctx->flags & IR_OPT_FOLDING))) {
IR_ASSERT(ctx->ir_base[ctx->control].op == IR_MERGE
|| ctx->ir_base[ctx->control].op == IR_LOOP_BEGIN);
ref = inputs[0];
if (ref != IR_UNUSED) {
for (i = 1; i < n; i++) {
if (inputs[i] != ref) {
break;
}
}
if (i == n) {
/* all the same */
return ref;
}
}
if (i == n) {
/* all the same */
return ref;
}
}

Expand Down Expand Up @@ -2066,7 +2134,8 @@ void _ir_ENTRY(ir_ctx *ctx, ir_ref src, ir_ref num)
void _ir_BEGIN(ir_ctx *ctx, ir_ref src)
{
IR_ASSERT(!ctx->control);
if (src
if (EXPECTED(ctx->flags & IR_OPT_FOLDING)
&& src
&& src + 1 == ctx->insns_count
&& ctx->ir_base[src].op == IR_END) {
/* merge with the last END */
Expand Down Expand Up @@ -2095,8 +2164,14 @@ ir_ref _ir_IF(ir_ctx *ctx, ir_ref condition)
{
ir_ref if_ref;

condition = _ir_fold_condition(ctx, condition);
IR_ASSERT(ctx->control);
if (UNEXPECTED(!(ctx->flags & IR_OPT_FOLDING))) {
if_ref = ir_emit2(ctx, IR_IF, ctx->control, condition);
ctx->control = IR_UNUSED;
return if_ref;
}

condition = _ir_fold_condition(ctx, condition);
if (IR_IS_CONST_REF(condition)) {
condition = ir_ref_is_true(ctx, condition) ? IR_TRUE : IR_FALSE;
} else {
Expand Down Expand Up @@ -2649,7 +2724,7 @@ void _ir_GUARD(ir_ctx *ctx, ir_ref condition, ir_ref addr)
return;
}
condition = IR_FALSE;
} else {
} else if (EXPECTED(ctx->flags & IR_OPT_FOLDING)) {
ir_insn *prev = NULL;
ir_ref ref = ctx->control;
ir_insn *insn;
Expand Down Expand Up @@ -2695,7 +2770,7 @@ void _ir_GUARD_NOT(ir_ctx *ctx, ir_ref condition, ir_ref addr)
return;
}
condition = IR_TRUE;
} else {
} else if (EXPECTED(ctx->flags & IR_OPT_FOLDING)) {
ir_insn *prev = NULL;
ir_ref ref = ctx->control;
ir_insn *insn;
Expand Down Expand Up @@ -2779,6 +2854,10 @@ ir_ref _ir_VLOAD(ir_ctx *ctx, ir_type type, ir_ref var)
ir_ref ref = ctx->control;
ir_insn *insn;

if (UNEXPECTED(!(ctx->flags & IR_OPT_FOLDING))) {
IR_ASSERT(ctx->control);
return ctx->control = ir_emit2(ctx, IR_OPT(IR_VLOAD, type), ctx->control, var);
}
while (ref > var) {
insn = &ctx->ir_base[ref];
if (insn->op == IR_VLOAD) {
Expand Down Expand Up @@ -2825,6 +2904,12 @@ void _ir_VSTORE(ir_ctx *ctx, ir_ref var, ir_ref val)
ir_insn *insn;
bool guarded = 0;

if (UNEXPECTED(!(ctx->flags & IR_OPT_FOLDING))) {
IR_ASSERT(ctx->control);
ctx->control = ir_emit3(ctx, IR_VSTORE, ctx->control, var, val);
return;
}

if (!IR_IS_CONST_REF(val)) {
insn = &ctx->ir_base[val];
if (insn->op == IR_BITCAST
Expand Down Expand Up @@ -2893,9 +2978,12 @@ void _ir_RSTORE(ir_ctx *ctx, ir_ref reg, ir_ref val)

ir_ref _ir_LOAD(ir_ctx *ctx, ir_type type, ir_ref addr)
{
ir_ref ref = ir_find_aliasing_load(ctx, ctx->control, type, addr);
ir_ref ref = IR_UNUSED;

IR_ASSERT(ctx->control);
if (EXPECTED(ctx->flags & IR_OPT_FOLDING)) {
ref = ir_find_aliasing_load(ctx, ctx->control, type, addr);
}
if (!ref) {
ctx->control = ref = ir_emit2(ctx, IR_OPT(IR_LOAD, type), ctx->control, addr);
}
Expand All @@ -2912,6 +3000,12 @@ void _ir_STORE(ir_ctx *ctx, ir_ref addr, ir_ref val)
ir_type type2;
bool guarded = 0;

IR_ASSERT(ctx->control);
if (UNEXPECTED(!(ctx->flags & IR_OPT_FOLDING))) {
ctx->control = ir_emit3(ctx, IR_STORE, ctx->control, addr, val);
return;
}

if (!IR_IS_CONST_REF(val)) {
insn = &ctx->ir_base[val];
if (insn->op == IR_BITCAST
Expand All @@ -2922,7 +3016,6 @@ void _ir_STORE(ir_ctx *ctx, ir_ref addr, ir_ref val)
}
}

IR_ASSERT(ctx->control);
while (ref > limit) {
insn = &ctx->ir_base[ref];
if (insn->op == IR_STORE) {
Expand Down
15 changes: 13 additions & 2 deletions ext/opcache/jit/ir/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,7 @@ ir_ref ir_emit3(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3);

ir_ref ir_emit_N(ir_ctx *ctx, uint32_t opt, int32_t count);
void ir_set_op(ir_ctx *ctx, ir_ref ref, int32_t n, ir_ref val);
ir_ref ir_get_op(ir_ctx *ctx, ir_ref ref, int32_t n);

IR_ALWAYS_INLINE void ir_set_op1(ir_ctx *ctx, ir_ref ref, ir_ref val)
{
Expand All @@ -721,8 +722,6 @@ IR_ALWAYS_INLINE void ir_set_op3(ir_ctx *ctx, ir_ref ref, ir_ref val)
ctx->ir_base[ref].op3 = val;
}

ir_ref ir_get_op(ir_ctx *ctx, ir_ref ref, int32_t n);

IR_ALWAYS_INLINE ir_ref ir_insn_op(const ir_insn *insn, int32_t n)
{
const ir_ref *p = insn->ops + n;
Expand All @@ -735,6 +734,18 @@ IR_ALWAYS_INLINE void ir_insn_set_op(ir_insn *insn, int32_t n, ir_ref val)
*p = val;
}

IR_ALWAYS_INLINE uint32_t ir_insn_find_op(const ir_insn *insn, ir_ref val)
{
int i, n = insn->inputs_count;

for (i = 1; i <= n; i++) {
if (ir_insn_op(insn, i) == val) {
return i;
}
}
return 0;
}

ir_ref ir_fold(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3);

ir_ref ir_fold0(ir_ctx *ctx, uint32_t opt);
Expand Down
23 changes: 13 additions & 10 deletions ext/opcache/jit/ir/ir_fold.h
Original file line number Diff line number Diff line change
Expand Up @@ -1808,10 +1808,6 @@ IR_FOLD(MUL(_, C_ADDR))
IR_FOLD_COPY(op2);
} else if (op2_insn->val.u64 == 1) {
IR_FOLD_COPY(op1);
} else if (op2_insn->val.u64 == 2 && IR_OPT_TYPE(opt) != IR_ADDR) {
opt = IR_ADD | (opt & IR_OPT_TYPE_MASK);
op2 = op1;
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
Expand All @@ -1827,11 +1823,6 @@ IR_FOLD(MUL(_, C_I64))
} else if (op2_insn->val.i64 == 1) {
/* a * 1 => a */
IR_FOLD_COPY(op1);
} else if (op2_insn->val.i64 == 2) {
/* a * 2 => a + a */
opt = IR_ADD | (opt & IR_OPT_TYPE_MASK);
op2 = op1;
IR_FOLD_RESTART;
} else if (op2_insn->val.i64 == -1) {
/* a * -1 => -a */
opt = IR_NEG | (opt & IR_OPT_TYPE_MASK);
Expand Down Expand Up @@ -2907,7 +2898,6 @@ IR_FOLD(ADD(SHR, SHL))


/* Swap operands (move lower ref to op2) for better CSE */
IR_FOLD(ADD(_, _))
IR_FOLD(MUL(_, _))
IR_FOLD_NAMED(swap_ops)
{
Expand All @@ -2929,6 +2919,19 @@ IR_FOLD(MUL_OV(_, _))
IR_FOLD_EMIT;
}

IR_FOLD(ADD(_, _))
{
if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt)) && op1 == op2) {
/* a + a => a * 2 */
IR_ASSERT(!IR_IS_CONST_REF(op1));
val.u64 = 2;
opt = IR_MUL | (opt & IR_OPT_TYPE_MASK);
op2 = ir_const(ctx, val, IR_OPT_TYPE(opt));
IR_FOLD_RESTART;
}
IR_FOLD_DO_NAMED(swap_ops);
}

IR_FOLD(SUB(_, _))
{
if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt)) && op1 == op2) {
Expand Down
Loading

0 comments on commit 4763193

Please sign in to comment.