Skip to content

Commit ac1cd9c

Browse files
committed
Update IR
IR commit: 6e2aea0ebfef2c741ebec30c57aa492df0d4e319
1 parent b3f4863 commit ac1cd9c

File tree

13 files changed

+685
-127
lines changed

13 files changed

+685
-127
lines changed

ext/opcache/jit/ir/ir.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted
172172
} else if (insn->val.c == '\0') {
173173
fprintf(f, "'\\0'");
174174
} else {
175-
fprintf(f, "%u", insn->val.c);
175+
fprintf(f, "%u", (unsigned char)insn->val.c);
176176
}
177177
break;
178178
case IR_I8:
@@ -247,6 +247,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted
247247
#define ir_op_flag_S1X1 (ir_op_flag_S | 1 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
248248
#define ir_op_flag_S2 (ir_op_flag_S | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
249249
#define ir_op_flag_S2X1 (ir_op_flag_S | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
250+
#define ir_op_flag_S3 (ir_op_flag_S | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
250251
#define ir_op_flag_SN (ir_op_flag_S | IR_OP_FLAG_VAR_INPUTS)
251252
#define ir_op_flag_E (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_END)
252253
#define ir_op_flag_E1 (ir_op_flag_E | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT))
@@ -803,7 +804,9 @@ ir_ref ir_proto(ir_ctx *ctx, uint8_t flags, ir_type ret_type, uint32_t params_co
803804
proto->flags = flags;
804805
proto->ret_type = ret_type;
805806
proto->params_count = params_count;
806-
memcpy(proto->param_types, param_types, params_count);
807+
if (params_count) {
808+
memcpy(proto->param_types, param_types, params_count);
809+
}
807810
return ir_strl(ctx, (const char *)proto, offsetof(ir_proto_t, param_types) + params_count);
808811
}
809812

@@ -1080,7 +1083,7 @@ ir_ref ir_emit_N(ir_ctx *ctx, uint32_t opt, int32_t count)
10801083
ir_ref *p, ref = ctx->insns_count;
10811084
ir_insn *insn;
10821085

1083-
IR_ASSERT(count >= 0);
1086+
IR_ASSERT(count >= 0 && count < 65536);
10841087
while (UNEXPECTED(ref + count/4 >= ctx->insns_limit)) {
10851088
ir_grow_top(ctx);
10861089
}
@@ -2973,6 +2976,12 @@ void _ir_CASE_VAL(ir_ctx *ctx, ir_ref switch_ref, ir_ref val)
29732976
ctx->control = ir_emit2(ctx, IR_CASE_VAL, switch_ref, val);
29742977
}
29752978

2979+
void _ir_CASE_RANGE(ir_ctx *ctx, ir_ref switch_ref, ir_ref v1, ir_ref v2)
2980+
{
2981+
IR_ASSERT(!ctx->control);
2982+
ctx->control = ir_emit3(ctx, IR_CASE_RANGE, switch_ref, v1, v2);
2983+
}
2984+
29762985
void _ir_CASE_DEFAULT(ir_ctx *ctx, ir_ref switch_ref)
29772986
{
29782987
IR_ASSERT(!ctx->control);

ext/opcache/jit/ir/ir.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ typedef enum _ir_type {
359359
_(IF_TRUE, S1X1, src, prb, ___) /* IF TRUE proj. */ \
360360
_(IF_FALSE, S1X1, src, prb, ___) /* IF FALSE proj. */ \
361361
_(CASE_VAL, S2X1, src, def, prb) /* switch proj. */ \
362+
_(CASE_RANGE, S3, src, def, def) /* switch proj. */ \
362363
_(CASE_DEFAULT, S1X1, src, prb, ___) /* switch proj. */ \
363364
_(MERGE, SN, src, src, src) /* control merge */ \
364365
_(LOOP_BEGIN, SN, src, src, src) /* loop start */ \
@@ -854,6 +855,9 @@ void ir_gdb_unregister_all(void);
854855
bool ir_gdb_present(void);
855856

856857
/* IR load API (implementation in ir_load.c) */
858+
#define IR_RESOLVE_SYM_ADD_THUNK (1<<0)
859+
#define IR_RESOLVE_SYM_SILENT (1<<1)
860+
857861
struct _ir_loader {
858862
uint32_t default_func_flags;
859863
bool (*init_module) (ir_loader *loader, const char *name, const char *filename, const char *target);
@@ -870,7 +874,7 @@ struct _ir_loader {
870874
bool (*sym_data_end) (ir_loader *loader, uint32_t flags);
871875
bool (*func_init) (ir_loader *loader, ir_ctx *ctx, const char *name);
872876
bool (*func_process) (ir_loader *loader, ir_ctx *ctx, const char *name);
873-
void*(*resolve_sym_name) (ir_loader *loader, const char *name, bool add_thunk);
877+
void*(*resolve_sym_name) (ir_loader *loader, const char *name, uint32_t flags);
874878
bool (*has_sym) (ir_loader *loader, const char *name);
875879
bool (*add_sym) (ir_loader *loader, const char *name, void *addr);
876880
};
@@ -884,11 +888,12 @@ int ir_load_llvm_bitcode(ir_loader *loader, const char *filename);
884888
int ir_load_llvm_asm(ir_loader *loader, const char *filename);
885889

886890
/* IR save API (implementation in ir_save.c) */
887-
#define IR_SAVE_CFG (1<<0) /* add info about CFG */
888-
#define IR_SAVE_CFG_MAP (1<<1) /* add info about CFG block assignment */
889-
#define IR_SAVE_USE_LISTS (1<<2) /* add info about def->use lists */
890-
#define IR_SAVE_RULES (1<<3) /* add info about selected code-generation rules */
891-
#define IR_SAVE_REGS (1<<4) /* add info about selected registers */
891+
#define IR_SAVE_CFG (1<<0) /* add info about CFG */
892+
#define IR_SAVE_CFG_MAP (1<<1) /* add info about CFG block assignment */
893+
#define IR_SAVE_USE_LISTS (1<<2) /* add info about def->use lists */
894+
#define IR_SAVE_RULES (1<<3) /* add info about selected code-generation rules */
895+
#define IR_SAVE_REGS (1<<4) /* add info about selected registers */
896+
#define IR_SAVE_SAFE_NAMES (1<<5) /* add '@' prefix to symbol names */
892897

893898
void ir_print_proto(const ir_ctx *ctx, ir_ref proto, FILE *f);
894899
void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f);

ext/opcache/jit/ir/ir_aarch64.dasc

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,7 @@ binop_fp:
996996
case IR_IF_TRUE:
997997
case IR_IF_FALSE:
998998
case IR_CASE_VAL:
999+
case IR_CASE_RANGE:
9991000
case IR_CASE_DEFAULT:
10001001
case IR_MERGE:
10011002
case IR_LOOP_BEGIN:
@@ -4366,11 +4367,15 @@ static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn)
43664367
ir_backend_data *data = ctx->data;
43674368
dasm_State **Dst = &data->dasm_state;
43684369
ir_type type = insn->type;
4369-
ir_reg def_reg = ctx->regs[def][0];
4370+
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
43704371
ir_reg op2_reg = ctx->regs[def][2];
43714372
ir_reg tmp_reg = ctx->regs[def][3];
43724373
int32_t offset;
43734374

4375+
if (ctx->use_lists[def].count == 1) {
4376+
/* dead load */
4377+
return;
4378+
}
43744379
IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE);
43754380
if (op2_reg != IR_REG_NONE) {
43764381
if (IR_REG_SPILLED(op2_reg)) {
@@ -4394,11 +4399,15 @@ static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn)
43944399
ir_backend_data *data = ctx->data;
43954400
dasm_State **Dst = &data->dasm_state;
43964401
ir_type type = insn->type;
4397-
ir_reg def_reg = ctx->regs[def][0];
4402+
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
43984403
ir_reg op2_reg = ctx->regs[def][2];
43994404
ir_reg tmp_reg = ctx->regs[def][3];
44004405
int32_t offset;
44014406

4407+
if (ctx->use_lists[def].count == 1) {
4408+
/* dead load */
4409+
return;
4410+
}
44024411
IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE);
44034412
if (op2_reg != IR_REG_NONE) {
44044413
if (IR_REG_SPILLED(op2_reg)) {
@@ -4465,6 +4474,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
44654474
int count = 0;
44664475
ir_val min, max;
44674476
ir_reg op1_reg, op2_reg, tmp_reg;
4477+
bool has_case_range = 0;
44684478

44694479
type = ctx->ir_base[insn->op2].type;
44704480
if (IR_IS_TYPE_SIGNED(type)) {
@@ -4493,6 +4503,22 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
44934503
max.u64 = (int64_t)IR_MAX(max.u64, val->val.u64);
44944504
}
44954505
count++;
4506+
} else if (use_insn->op == IR_CASE_RANGE) {
4507+
has_case_range = 1;
4508+
val = &ctx->ir_base[use_insn->op2];
4509+
IR_ASSERT(!IR_IS_SYM_CONST(val->op));
4510+
ir_insn *val2 = &ctx->ir_base[use_insn->op3];
4511+
IR_ASSERT(!IR_IS_SYM_CONST(val2->op));
4512+
if (IR_IS_TYPE_SIGNED(type)) {
4513+
IR_ASSERT(IR_IS_TYPE_SIGNED(val->type));
4514+
min.i64 = IR_MIN(min.i64, val->val.i64);
4515+
max.i64 = IR_MAX(max.i64, val2->val.i64);
4516+
} else {
4517+
IR_ASSERT(!IR_IS_TYPE_SIGNED(val->type));
4518+
min.u64 = (int64_t)IR_MIN(min.u64, val->val.u64);
4519+
max.u64 = (int64_t)IR_MAX(max.u64, val2->val.u64);
4520+
}
4521+
count++;
44964522
} else {
44974523
IR_ASSERT(use_insn->op == IR_CASE_DEFAULT);
44984524
default_label = ir_skip_empty_target_blocks(ctx, use_block);
@@ -4510,7 +4536,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
45104536
}
45114537

45124538
/* Generate a table jmp or a sequence of calls */
4513-
if (count > 2 && (max.i64-min.i64) < count * 8) {
4539+
if (!has_case_range && count > 2 && (max.i64-min.i64) < count * 8) {
45144540
int *labels = ir_mem_malloc(sizeof(int) * (max.i64 - min.i64 + 1));
45154541

45164542
for (i = 0; i <= (max.i64 - min.i64); i++) {
@@ -4615,6 +4641,38 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
46154641

46164642
}
46174643
| beq =>label
4644+
} else if (use_insn->op == IR_CASE_RANGE) {
4645+
val = &ctx->ir_base[use_insn->op2];
4646+
IR_ASSERT(!IR_IS_SYM_CONST(val->op));
4647+
label = ir_skip_empty_target_blocks(ctx, use_block);
4648+
if (aarch64_may_encode_imm12(val->val.i64)) {
4649+
| ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i64
4650+
} else {
4651+
ir_emit_load_imm_int(ctx, type, tmp_reg, val->val.i64);
4652+
| ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg
4653+
4654+
}
4655+
if (IR_IS_TYPE_SIGNED(type)) {
4656+
| blt >1
4657+
} else {
4658+
| blo >1
4659+
}
4660+
val = &ctx->ir_base[use_insn->op3];
4661+
IR_ASSERT(!IR_IS_SYM_CONST(val->op));
4662+
label = ir_skip_empty_target_blocks(ctx, use_block);
4663+
if (aarch64_may_encode_imm12(val->val.i64)) {
4664+
| ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i64
4665+
} else {
4666+
ir_emit_load_imm_int(ctx, type, tmp_reg, val->val.i64);
4667+
| ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg
4668+
4669+
}
4670+
if (IR_IS_TYPE_SIGNED(type)) {
4671+
| ble =>label
4672+
} else {
4673+
| bls =>label
4674+
}
4675+
|1:
46184676
}
46194677
}
46204678
if (default_label) {
@@ -4935,6 +4993,28 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
49354993
return;
49364994
}
49374995

4996+
/* Move op2 to a tmp register before epilogue if it's in
4997+
* used_preserved_regs, because it will be overridden. */
4998+
4999+
ir_reg op2_reg = IR_REG_NONE;
5000+
if (!IR_IS_CONST_REF(insn->op2)) {
5001+
op2_reg = ctx->regs[def][2];
5002+
IR_ASSERT(op2_reg != IR_REG_NONE);
5003+
5004+
if (IR_REG_SPILLED(op2_reg)) {
5005+
op2_reg = IR_REG_INT_TMP;
5006+
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
5007+
} else if (IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, IR_REG_NUM(op2_reg))) {
5008+
ir_reg orig_op2_reg = op2_reg;
5009+
op2_reg = IR_REG_INT_TMP;
5010+
5011+
ir_type type = ctx->ir_base[insn->op2].type;
5012+
| ASM_REG_REG_OP mov, type, op2_reg, IR_REG_NUM(orig_op2_reg)
5013+
} else {
5014+
op2_reg = IR_REG_NUM(op2_reg);
5015+
}
5016+
}
5017+
49385018
ir_emit_epilogue(ctx);
49395019

49405020
if (IR_IS_CONST_REF(insn->op2)) {
@@ -4947,13 +5027,8 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
49475027
| br Rx(IR_REG_INT_TMP)
49485028
}
49495029
} else {
4950-
ir_reg op2_reg = ctx->regs[def][2];
4951-
49525030
IR_ASSERT(op2_reg != IR_REG_NONE);
4953-
if (IR_REG_SPILLED(op2_reg)) {
4954-
op2_reg = IR_REG_NUM(op2_reg);
4955-
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
4956-
}
5031+
IR_ASSERT(!IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, op2_reg));
49575032
| br Rx(op2_reg)
49585033
}
49595034
}
@@ -5590,6 +5665,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx)
55905665
case IR_IF_TRUE:
55915666
case IR_IF_FALSE:
55925667
case IR_CASE_VAL:
5668+
case IR_CASE_RANGE:
55935669
case IR_CASE_DEFAULT:
55945670
case IR_MERGE:
55955671
case IR_LOOP_BEGIN:

ext/opcache/jit/ir/ir_builder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ extern "C" {
603603
#define ir_LOOP_END() _ir_LOOP_END(_ir_CTX)
604604
#define ir_SWITCH(_val) _ir_SWITCH(_ir_CTX, (_val))
605605
#define ir_CASE_VAL(_switch, _val) _ir_CASE_VAL(_ir_CTX, (_switch), (_val))
606+
#define ir_CASE_RANGE(_switch, _v1, _v2) _ir_CASE_RANGE(_ir_CTX, (_switch), (_v1), (_v2))
606607
#define ir_CASE_DEFAULT(_switch) _ir_CASE_DEFAULT(_ir_CTX, (_switch))
607608
#define ir_RETURN(_val) _ir_RETURN(_ir_CTX, (_val))
608609
#define ir_IJMP(_addr) _ir_IJMP(_ir_CTX, (_addr))
@@ -682,6 +683,7 @@ ir_ref _ir_TLS(ir_ctx *ctx, ir_ref index, ir_ref offset);
682683
void _ir_UNREACHABLE(ir_ctx *ctx);
683684
ir_ref _ir_SWITCH(ir_ctx *ctx, ir_ref val);
684685
void _ir_CASE_VAL(ir_ctx *ctx, ir_ref switch_ref, ir_ref val);
686+
void _ir_CASE_RANGE(ir_ctx *ctx, ir_ref switch_ref, ir_ref v1, ir_ref v2);
685687
void _ir_CASE_DEFAULT(ir_ctx *ctx, ir_ref switch_ref);
686688
void _ir_RETURN(ir_ctx *ctx, ir_ref val);
687689
void _ir_IJMP(ir_ctx *ctx, ir_ref addr);

0 commit comments

Comments
 (0)