Skip to content

Commit

Permalink
Update IR
Browse files Browse the repository at this point in the history
IR commit: f7c0ddb1b4630e1287b0239f85d64a6965dfea29
  • Loading branch information
dstogov committed Feb 14, 2024
1 parent 1e770d1 commit ce96aa9
Show file tree
Hide file tree
Showing 9 changed files with 331 additions and 92 deletions.
55 changes: 51 additions & 4 deletions ext/opcache/jit/ir/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ ir_ref ir_unique_const_addr(ir_ctx *ctx, uintptr_t addr)
return ref;
}

static IR_NEVER_INLINE ir_ref ir_const_ex(ir_ctx *ctx, ir_val val, uint8_t type, uint32_t optx)
ir_ref ir_const_ex(ir_ctx *ctx, ir_val val, uint8_t type, uint32_t optx)
{
ir_insn *insn, *prev_insn;
ir_ref ref, prev;
Expand Down Expand Up @@ -1499,7 +1499,7 @@ ir_ref ir_addrtab_find(const ir_hashtab *tab, uint64_t key)
return IR_INVALID_VAL;
}

bool ir_addrtab_add(ir_hashtab *tab, uint64_t key, ir_ref val)
void ir_addrtab_set(ir_hashtab *tab, uint64_t key, ir_ref val)
{
char *data = (char*)tab->data;
uint32_t pos = ((uint32_t*)data)[(int32_t)(key | tab->mask)];
Expand All @@ -1508,7 +1508,8 @@ bool ir_addrtab_add(ir_hashtab *tab, uint64_t key, ir_ref val)
while (pos != IR_INVALID_IDX) {
p = (ir_addrtab_bucket*)(data + pos);
if (p->key == key) {
return p->val == val;
p->val = val;
return;
}
pos = p->next;
}
Expand All @@ -1527,7 +1528,6 @@ bool ir_addrtab_add(ir_hashtab *tab, uint64_t key, ir_ref val)
key |= tab->mask;
p->next = ((uint32_t*)data)[(int32_t)key];
((uint32_t*)data)[(int32_t)key] = pos;
return 1;
}

/* Memory API */
Expand Down Expand Up @@ -1977,6 +1977,18 @@ ir_ref _ir_END_LIST(ir_ctx *ctx, ir_ref list)
return ref;
}

ir_ref _ir_END_PHI_LIST(ir_ctx *ctx, ir_ref list, ir_ref val)
{
ir_ref ref;

IR_ASSERT(ctx->control);
IR_ASSERT(!list || ctx->ir_base[list].op == IR_END);
/* create a liked list of END nodes with the same destination through END.op2 */
ref = ir_emit3(ctx, IR_END, ctx->control, list, val);
ctx->control = IR_UNUSED;
return ref;
}

void _ir_MERGE_LIST(ir_ctx *ctx, ir_ref list)
{
ir_ref ref = list;
Expand Down Expand Up @@ -2016,6 +2028,41 @@ void _ir_MERGE_LIST(ir_ctx *ctx, ir_ref list)
}
}

ir_ref _ir_PHI_LIST(ir_ctx *ctx, ir_ref list)
{
ir_insn *merge, *end;
ir_ref phi, *ops, i;
ir_type type;

if (list == IR_UNUSED) {
return IR_UNUSED;
}
end = &ctx->ir_base[list];
if (!end->op2) {
phi = end->op3;
end->op3 = IR_UNUSED;
_ir_BEGIN(ctx, list);
} else if (!end->op3) {
_ir_MERGE_LIST(ctx, list);
phi = IR_UNUSED;
} else {
type = ctx->ir_base[end->op3].type;
_ir_MERGE_LIST(ctx, list);
merge = &ctx->ir_base[ctx->control];
IR_ASSERT(merge->op == IR_MERGE);
phi = ir_emit_N(ctx, IR_OPT(IR_PHI, type), merge->inputs_count + 1);
merge = &ctx->ir_base[ctx->control];
ops = merge->ops;
ir_set_op(ctx, phi, 1, ctx->control);
for (i = 0; i < merge->inputs_count; i++) {
end = &ctx->ir_base[ops[i + 1]];
ir_set_op(ctx, phi, i + 2, end->op3);
end->op3 = IR_END;
}
}
return phi;
}

ir_ref _ir_LOOP_BEGIN(ir_ctx *ctx, ir_ref src1)
{
IR_ASSERT(!ctx->control);
Expand Down
15 changes: 8 additions & 7 deletions ext/opcache/jit/ir/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,13 +501,14 @@ void ir_strtab_free(ir_strtab *strtab);
#define IR_GEN_ENDBR (1<<14)
#define IR_MERGE_EMPTY_ENTRIES (1<<15)

#define IR_OPT_FOLDING (1<<16)
#define IR_OPT_CFG (1<<17) /* merge BBs, by remove END->BEGIN nodes during CFG construction */
#define IR_OPT_CODEGEN (1<<18)
#define IR_GEN_NATIVE (1<<19)
#define IR_GEN_CODE (1<<20) /* C or LLVM */

#define IR_GEN_CACHE_DEMOTE (1<<21) /* Demote the generated code from closest CPU caches */
#define IR_OPT_INLINE (1<<16)
#define IR_OPT_FOLDING (1<<17)
#define IR_OPT_CFG (1<<18) /* merge BBs, by remove END->BEGIN nodes during CFG construction */
#define IR_OPT_CODEGEN (1<<19)
#define IR_GEN_NATIVE (1<<20)
#define IR_GEN_CODE (1<<21) /* C or LLVM */

#define IR_GEN_CACHE_DEMOTE (1<<22) /* Demote the generated code from closest CPU caches */

/* debug related */
#ifdef IR_DEBUG
Expand Down
78 changes: 47 additions & 31 deletions ext/opcache/jit/ir/ir_aarch64.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co
n++;
}
}
flags = IR_USE_SHOULD_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG;
flags = IR_USE_SHOULD_BE_IN_REG | IR_OP2_MUST_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG;
break;
case IR_COND:
insn = &ctx->ir_base[ref];
Expand Down Expand Up @@ -3953,6 +3953,10 @@ static void ir_emit_alloca(ir_ctx *ctx, ir_ref def, ir_insn *insn)
dasm_State **Dst = &data->dasm_state;
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);

if (ctx->use_lists[def].count == 1) {
/* dead alloca */
return;
}
if (IR_IS_CONST_REF(insn->op2)) {
ir_insn *val = &ctx->ir_base[insn->op2];
int32_t size = val->val.i32;
Expand Down Expand Up @@ -4314,16 +4318,18 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
}
}

if (aarch64_may_encode_imm12(max.i64)) {
| ASM_REG_IMM_OP cmp, type, op2_reg, max.i64
} else {
ir_emit_load_imm_int(ctx, type, tmp_reg, max.i64);
| ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg
}
if (IR_IS_TYPE_SIGNED(type)) {
| bgt =>default_label
} else {
| bhi =>default_label
if (default_label) {
if (aarch64_may_encode_imm12(max.i64)) {
| ASM_REG_IMM_OP cmp, type, op2_reg, max.i64
} else {
ir_emit_load_imm_int(ctx, type, tmp_reg, max.i64);
| ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg
}
if (IR_IS_TYPE_SIGNED(type)) {
| bgt =>default_label
} else {
| bhi =>default_label
}
}

if (op1_reg == IR_REG_NONE) {
Expand All @@ -4335,11 +4341,15 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
ir_emit_load_imm_int(ctx, type, tmp_reg, min.i64);
| ASM_REG_REG_REG_OP subs, type, op1_reg, op2_reg, tmp_reg
}
if (IR_IS_TYPE_SIGNED(type)) {
| blt =>default_label
} else {
| blo =>default_label

if (default_label) {
if (IR_IS_TYPE_SIGNED(type)) {
| blt =>default_label
} else {
| blo =>default_label
}
}

| adr Rx(tmp_reg), >1
| ldr Rx(tmp_reg), [Rx(tmp_reg), Rx(op1_reg), lsl #3]
| br Rx(tmp_reg)
Expand All @@ -4352,25 +4362,29 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
|1:
for (i = 0; i <= (max.i64 - min.i64); i++) {
int b = labels[i];
ir_block *bb = &ctx->cfg_blocks[b];
ir_insn *insn = &ctx->ir_base[bb->end];

if (insn->op == IR_IJMP && IR_IS_CONST_REF(insn->op2)) {
ir_ref prev = ctx->prev_ref[bb->end];
if (prev != bb->start && ctx->ir_base[prev].op == IR_SNAPSHOT) {
prev = ctx->prev_ref[prev];
}
if (prev == bb->start) {
void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op2]);
if (b) {
ir_block *bb = &ctx->cfg_blocks[b];
ir_insn *insn = &ctx->ir_base[bb->end];

if (insn->op == IR_IJMP && IR_IS_CONST_REF(insn->op2)) {
ir_ref prev = ctx->prev_ref[bb->end];
if (prev != bb->start && ctx->ir_base[prev].op == IR_SNAPSHOT) {
prev = ctx->prev_ref[prev];
}
if (prev == bb->start) {
void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op2]);

| .addr &addr
if (ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) {
bb->flags |= IR_BB_EMPTY;
| .addr &addr
if (ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) {
bb->flags |= IR_BB_EMPTY;
}
continue;
}
continue;
}
| .addr =>b
} else {
| .addr 0
}
| .addr =>b
}
|.code
ir_mem_free(labels);
Expand Down Expand Up @@ -5187,7 +5201,9 @@ static void ir_emit_load_params(ir_ctx *ctx)
dst_reg = IR_REG_NUM(ctx->regs[use][0]);
IR_ASSERT(src_reg != IR_REG_NONE || dst_reg != IR_REG_NONE ||
stack_offset == ctx->live_intervals[ctx->vregs[use]]->stack_spill_pos +
((ctx->flags & IR_USE_FRAME_POINTER) ? -ctx->stack_frame_size : ctx->call_stack_size));
((ctx->flags & IR_USE_FRAME_POINTER) ?
-(ctx->stack_frame_size - ctx->stack_frame_alignment) :
ctx->call_stack_size));
if (src_reg != dst_reg) {
ir_emit_param_move(ctx, insn->type, src_reg, dst_reg, use, stack_offset);
}
Expand Down
5 changes: 5 additions & 0 deletions ext/opcache/jit/ir/ir_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,9 @@ extern "C" {
#define ir_END_list(_list) do { _list = _ir_END_LIST(_ir_CTX, _list); } while (0)
#define ir_MERGE_list(_list) _ir_MERGE_LIST(_ir_CTX, (_list))

#define ir_END_PHI_list(_list, _val) do { _list = _ir_END_PHI_LIST(_ir_CTX, _list, _val); } while (0)
#define ir_PHI_list(_list) _ir_PHI_LIST(_ir_CTX, (_list))

#define ir_MERGE_WITH(_src2) do {ir_ref end = ir_END(); ir_MERGE_2(end, _src2);} while (0)
#define ir_MERGE_WITH_EMPTY_TRUE(_if) do {ir_ref end = ir_END(); ir_IF_TRUE(_if); ir_MERGE_2(end, ir_END());} while (0)
#define ir_MERGE_WITH_EMPTY_FALSE(_if) do {ir_ref end = ir_END(); ir_IF_FALSE(_if); ir_MERGE_2(end, ir_END());} while (0)
Expand Down Expand Up @@ -655,6 +658,7 @@ void _ir_ENTRY(ir_ctx *ctx, ir_ref src, ir_ref num);
void _ir_BEGIN(ir_ctx *ctx, ir_ref src);
ir_ref _ir_END(ir_ctx *ctx);
ir_ref _ir_END_LIST(ir_ctx *ctx, ir_ref list);
ir_ref _ir_END_PHI_LIST(ir_ctx *ctx, ir_ref list, ir_ref val);
ir_ref _ir_IF(ir_ctx *ctx, ir_ref condition);
void _ir_IF_TRUE(ir_ctx *ctx, ir_ref if_ref);
void _ir_IF_TRUE_cold(ir_ctx *ctx, ir_ref if_ref);
Expand All @@ -664,6 +668,7 @@ void _ir_MERGE_2(ir_ctx *ctx, ir_ref src1, ir_ref src2);
void _ir_MERGE_N(ir_ctx *ctx, ir_ref n, ir_ref *inputs);
void _ir_MERGE_SET_OP(ir_ctx *ctx, ir_ref merge, ir_ref pos, ir_ref src);
void _ir_MERGE_LIST(ir_ctx *ctx, ir_ref list);
ir_ref _ir_PHI_LIST(ir_ctx *ctx, ir_ref list);
ir_ref _ir_LOOP_BEGIN(ir_ctx *ctx, ir_ref src1);
ir_ref _ir_LOOP_END(ir_ctx *ctx);
ir_ref _ir_TLS(ir_ctx *ctx, ir_ref index, ir_ref offset);
Expand Down
2 changes: 1 addition & 1 deletion ext/opcache/jit/ir/ir_emit.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ static void ir_emit_dessa_move(ir_ctx *ctx, ir_type type, ir_ref to, ir_ref from

IR_ALWAYS_INLINE void ir_dessa_resolve_cycle(ir_ctx *ctx, int32_t *pred, int32_t *loc, ir_bitset todo, ir_type type, int32_t to, ir_reg tmp_reg, ir_reg tmp_fp_reg)
{
ir_reg from;
ir_ref from;
ir_mem tmp_spill_slot;

IR_MEM_VAL(tmp_spill_slot) = 0;
Expand Down
Loading

0 comments on commit ce96aa9

Please sign in to comment.