Skip to content

Commit cab88dd

Browse files
committed
IR Update
IR commit: b9c5fd8d691f576a6a9ae4ad2464ea51e18203a5
1 parent e3b6872 commit cab88dd

File tree

9 files changed

+803
-248
lines changed

9 files changed

+803
-248
lines changed

ext/opcache/jit/ir/gen_ir_fold_hash.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ void print_hash(uint32_t *mask, uint32_t count)
2828
printf("};\n\n");
2929
}
3030

31+
#if 0
3132
static uint32_t hash_shl2(uint32_t mask, uint32_t r1, uint32_t r2)
3233
{
3334
return ((mask << r1) - mask) << r2;
3435
}
35-
36-
#if 0
36+
#else
3737
#define ir_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1))))
3838
#define ir_ror(x, n) (((x)<<(-(int)(n)&(8*sizeof(x)-1))) | ((x)>>(n)))
3939

@@ -52,6 +52,7 @@ int find_hash(uint32_t *mask, uint32_t count)
5252
for (n = (count | 1); n < MAX_SLOTS; n += 2) {
5353
for (r1 = 0; r1 < 31; r1++) {
5454
for (r2 = 0; r2 < 32; r2++) {
55+
#if 0
5556
memset(hash, 0, n * sizeof(uint32_t));
5657
for (i = 0; i < count; i++) {
5758
h = hash_shl2(mask[i] & 0x1fffff, r1, r2) % n;
@@ -63,7 +64,7 @@ int find_hash(uint32_t *mask, uint32_t count)
6364
printf("static uint32_t _ir_fold_hashkey(uint32_t h)\n{\n\treturn (((h << %d) - h) << %d) %% %d;\n}\n", r1, r2, n);
6465
return 1;
6566
}
66-
#if 0
67+
#else
6768
memset(hash, 0, n * sizeof(uint32_t));
6869
for (i = 0; i < count; i++) {
6970
h = hash_rol2(mask[i] & 0x1fffff, r1, r2) % n;
@@ -72,7 +73,7 @@ int find_hash(uint32_t *mask, uint32_t count)
7273
}
7374
if (i == count) {
7475
print_hash(hash, n);
75-
printf("static uint32_t _ir_fold_hashkey(uint32_t h)\n{\nreturn 0; /*rol2(%u,%u,%u)*/\n}\n", r1, r2, n);
76+
printf("static uint32_t _ir_fold_hashkey(uint32_t h)\n{\nreturn ir_rol32((ir_rol32(h, %d) - h), %d) %% %d;\n}\n", r1, r2, n);
7677
return 1;
7778
}
7879
#endif

ext/opcache/jit/ir/ir.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,9 @@ void ir_free(ir_ctx *ctx)
417417
if (ctx->cfg_map) {
418418
ir_mem_free(ctx->cfg_map);
419419
}
420+
if (ctx->cfg_schedule) {
421+
ir_mem_free(ctx->cfg_schedule);
422+
}
420423
if (ctx->rules) {
421424
ir_mem_free(ctx->rules);
422425
}

ext/opcache/jit/ir/ir.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@ struct _ir_ctx {
563563
ir_block *cfg_blocks; /* list of basic blocks (starts from 1) */
564564
uint32_t *cfg_edges; /* the actual basic blocks predecessors and successors edges */
565565
uint32_t *cfg_map; /* map of instructions to basic block number */
566+
uint32_t *cfg_schedule; /* BB order for code generation */
566567
uint32_t *rules; /* array of target specific code-generation rules (for each instruction) */
567568
uint32_t *vregs;
568569
ir_ref vregs_count;

ext/opcache/jit/ir/ir_aarch64.dasc

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,17 +1967,17 @@ static void ir_emit_overflow(ir_ctx *ctx, ir_ref def, ir_insn *insn)
19671967
}
19681968
}
19691969

1970-
static void ir_emit_overflow_and_branch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
1970+
static void ir_emit_overflow_and_branch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint32_t next_block)
19711971
{
19721972
ir_backend_data *data = ctx->data;
19731973
dasm_State **Dst = &data->dasm_state;
19741974
ir_insn *overflow_insn = &ctx->ir_base[insn->op2];
19751975
ir_insn *math_insn = &ctx->ir_base[overflow_insn->op1];
19761976
ir_type type = math_insn->type;
1977-
uint32_t true_block, false_block, next_block;
1977+
uint32_t true_block, false_block;
19781978
bool reverse = 0;
19791979

1980-
ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
1980+
ir_get_true_false_blocks(ctx, b, &true_block, &false_block);
19811981
if (true_block == next_block) {
19821982
reverse = 1;
19831983
true_block = false_block;
@@ -2845,37 +2845,37 @@ static void ir_emit_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
28452845
}
28462846
}
28472847

2848-
static void ir_emit_jmp_true(ir_ctx *ctx, uint32_t b, ir_ref def)
2848+
static void ir_emit_jmp_true(ir_ctx *ctx, uint32_t b, ir_ref def, uint32_t next_block)
28492849
{
2850-
uint32_t true_block, false_block, next_block;
2850+
uint32_t true_block, false_block;
28512851
ir_backend_data *data = ctx->data;
28522852
dasm_State **Dst = &data->dasm_state;
28532853

2854-
ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
2854+
ir_get_true_false_blocks(ctx, b, &true_block, &false_block);
28552855
if (true_block != next_block) {
28562856
| b =>true_block
28572857
}
28582858
}
28592859

2860-
static void ir_emit_jmp_false(ir_ctx *ctx, uint32_t b, ir_ref def)
2860+
static void ir_emit_jmp_false(ir_ctx *ctx, uint32_t b, ir_ref def, uint32_t next_block)
28612861
{
2862-
uint32_t true_block, false_block, next_block;
2862+
uint32_t true_block, false_block;
28632863
ir_backend_data *data = ctx->data;
28642864
dasm_State **Dst = &data->dasm_state;
28652865

2866-
ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
2866+
ir_get_true_false_blocks(ctx, b, &true_block, &false_block);
28672867
if (false_block != next_block) {
28682868
| b =>false_block
28692869
}
28702870
}
28712871

2872-
static void ir_emit_jz(ir_ctx *ctx, uint8_t op, uint32_t b, ir_type type, ir_reg reg)
2872+
static void ir_emit_jz(ir_ctx *ctx, uint32_t b, uint32_t next_block, uint8_t op, ir_type type, ir_reg reg)
28732873
{
2874-
uint32_t true_block, false_block, next_block;
2874+
uint32_t true_block, false_block;
28752875
ir_backend_data *data = ctx->data;
28762876
dasm_State **Dst = &data->dasm_state;
28772877

2878-
ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
2878+
ir_get_true_false_blocks(ctx, b, &true_block, &false_block);
28792879
if (true_block == next_block) {
28802880
IR_ASSERT(op < IR_LT);
28812881
op ^= 1; // reverse
@@ -2904,13 +2904,13 @@ static void ir_emit_jz(ir_ctx *ctx, uint8_t op, uint32_t b, ir_type type, ir_reg
29042904
}
29052905
}
29062906

2907-
static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn *insn, bool int_cmp)
2907+
static void ir_emit_jcc(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint32_t next_block, uint8_t op, bool int_cmp)
29082908
{
2909-
uint32_t true_block, false_block, next_block;
2909+
uint32_t true_block, false_block;
29102910
ir_backend_data *data = ctx->data;
29112911
dasm_State **Dst = &data->dasm_state;
29122912

2913-
ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
2913+
ir_get_true_false_blocks(ctx, b, &true_block, &false_block);
29142914
if (true_block == next_block) {
29152915
/* swap to avoid unconditional JMP */
29162916
if (int_cmp || op == IR_EQ || op == IR_NE) {
@@ -3004,7 +3004,7 @@ static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn
30043004
}
30053005
}
30063006

3007-
static void ir_emit_cmp_and_branch_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
3007+
static void ir_emit_cmp_and_branch_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint32_t next_block)
30083008
{
30093009
ir_insn *cmp_insn = &ctx->ir_base[insn->op2];
30103010
ir_op op = cmp_insn->op;
@@ -3037,43 +3037,43 @@ static void ir_emit_cmp_and_branch_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_i
30373037
&& ctx->ir_base[op2].val.u64 == 0) {
30383038
if (op == IR_ULT) {
30393039
/* always false */
3040-
ir_emit_jmp_false(ctx, b, def);
3040+
ir_emit_jmp_false(ctx, b, def, next_block);
30413041
return;
30423042
} else if (op == IR_UGE) {
30433043
/* always true */
3044-
ir_emit_jmp_true(ctx, b, def);
3044+
ir_emit_jmp_true(ctx, b, def, next_block);
30453045
return;
30463046
} else if (op == IR_ULE) {
30473047
op = IR_EQ;
30483048
} else if (op == IR_UGT) {
30493049
op = IR_NE;
30503050
}
30513051
if (op1_reg != IR_REG_NONE && (op == IR_EQ || op == IR_NE)) {
3052-
ir_emit_jz(ctx, op, b, type, op1_reg);
3052+
ir_emit_jz(ctx, b, next_block, op, type, op1_reg);
30533053
return;
30543054
}
30553055
}
30563056
ir_emit_cmp_int_common(ctx, type, op1_reg, op1, op2_reg, op2);
3057-
ir_emit_jcc(ctx, op, b, def, insn, 1);
3057+
ir_emit_jcc(ctx, b, def, insn, next_block, op, 1);
30583058
}
30593059

3060-
static void ir_emit_cmp_and_branch_fp(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
3060+
static void ir_emit_cmp_and_branch_fp(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint32_t next_block)
30613061
{
30623062
ir_op op = ir_emit_cmp_fp_common(ctx, insn->op2, &ctx->ir_base[insn->op2]);
3063-
ir_emit_jcc(ctx, op, b, def, insn, 0);
3063+
ir_emit_jcc(ctx, b, def, insn, next_block, op, 0);
30643064
}
30653065

3066-
static void ir_emit_if_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
3066+
static void ir_emit_if_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint32_t next_block)
30673067
{
30683068
ir_type type = ctx->ir_base[insn->op2].type;
30693069
ir_reg op2_reg = ctx->regs[def][2];
30703070
ir_backend_data *data = ctx->data;
30713071
dasm_State **Dst = &data->dasm_state;
30723072

30733073
if (IR_IS_CONST_REF(insn->op2)) {
3074-
uint32_t true_block, false_block, next_block;
3074+
uint32_t true_block, false_block;
30753075

3076-
ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
3076+
ir_get_true_false_blocks(ctx, b, &true_block, &false_block);
30773077
if (ir_const_is_true(&ctx->ir_base[insn->op2])) {
30783078
if (true_block != next_block) {
30793079
| b =>true_block
@@ -3091,7 +3091,7 @@ static void ir_emit_if_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
30913091
ir_emit_load(ctx, type, op2_reg, insn->op2);
30923092
}
30933093
| ASM_REG_IMM_OP cmp, type, op2_reg, 0
3094-
ir_emit_jcc(ctx, IR_NE, b, def, insn, 1);
3094+
ir_emit_jcc(ctx, b, def, insn, next_block, IR_NE, 1);
30953095
}
30963096

30973097
static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn)
@@ -5610,9 +5610,20 @@ static void* dasm_labels[ir_lb_MAX];
56105610
/* Veneers support (TODO: avid global variable usage) */
56115611
static ir_ctx *ir_current_ctx;
56125612

5613+
static uint32_t _ir_next_block(ir_ctx *ctx, uint32_t _b)
5614+
{
5615+
uint32_t b = ctx->cfg_schedule[++_b];
5616+
5617+
/* Check for empty ENTRY block */
5618+
while (b && ((ctx->cfg_blocks[b].flags & (IR_BB_START|IR_BB_EMPTY)) == IR_BB_EMPTY)) {
5619+
b = ctx->cfg_schedule[++_b];
5620+
}
5621+
return b;
5622+
}
5623+
56135624
void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
56145625
{
5615-
uint32_t b, n, target;
5626+
uint32_t _b, b, n, target;
56165627
ir_block *bb;
56175628
ir_ref i;
56185629
ir_insn *insn;
@@ -5674,7 +5685,17 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
56745685
ir_emit_load_params(ctx);
56755686
}
56765687

5677-
for (b = 1, bb = ctx->cfg_blocks + b; b <= ctx->cfg_blocks_count; b++, bb++) {
5688+
if (UNEXPECTED(!ctx->cfg_schedule)) {
5689+
uint32_t *list = ctx->cfg_schedule = ir_mem_malloc(sizeof(uint32_t) * (ctx->cfg_blocks_count + 2));
5690+
for (b = 0; b <= ctx->cfg_blocks_count; b++) {
5691+
list[b] = b;
5692+
}
5693+
list[ctx->cfg_blocks_count + 1] = 0;
5694+
}
5695+
5696+
for (_b = 1; _b <= ctx->cfg_blocks_count; _b++) {
5697+
b = ctx->cfg_schedule[_b];
5698+
bb = &ctx->cfg_blocks[b];
56785699
IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE));
56795700
if ((bb->flags & (IR_BB_START|IR_BB_ENTRY|IR_BB_EMPTY)) == IR_BB_EMPTY) {
56805701
continue;
@@ -5774,10 +5795,10 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
57745795
ir_emit_copy_fp(ctx, i, insn);
57755796
break;
57765797
case IR_CMP_AND_BRANCH_INT:
5777-
ir_emit_cmp_and_branch_int(ctx, b, i, insn);
5798+
ir_emit_cmp_and_branch_int(ctx, b, i, insn, _ir_next_block(ctx, _b));
57785799
break;
57795800
case IR_CMP_AND_BRANCH_FP:
5780-
ir_emit_cmp_and_branch_fp(ctx, b, i, insn);
5801+
ir_emit_cmp_and_branch_fp(ctx, b, i, insn, _ir_next_block(ctx, _b));
57815802
break;
57825803
case IR_GUARD_CMP_INT:
57835804
ir_emit_guard_cmp_int(ctx, b, i, insn);
@@ -5786,7 +5807,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
57865807
ir_emit_guard_cmp_fp(ctx, b, i, insn);
57875808
break;
57885809
case IR_IF_INT:
5789-
ir_emit_if_int(ctx, b, i, insn);
5810+
ir_emit_if_int(ctx, b, i, insn, _ir_next_block(ctx, _b));
57905811
break;
57915812
case IR_COND:
57925813
ir_emit_cond(ctx, i, insn);
@@ -5801,7 +5822,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
58015822
ir_emit_overflow(ctx, i, insn);
58025823
break;
58035824
case IR_OVERFLOW_AND_BRANCH:
5804-
ir_emit_overflow_and_branch(ctx, b, i, insn);
5825+
ir_emit_overflow_and_branch(ctx, b, i, insn, _ir_next_block(ctx, _b));
58055826
break;
58065827
case IR_END:
58075828
case IR_LOOP_END:
@@ -5824,7 +5845,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
58245845
IR_ASSERT(bb->successors_count == 1);
58255846
}
58265847
target = ir_skip_empty_target_blocks(ctx, succ);
5827-
if (b == ctx->cfg_blocks_count || target != ir_skip_empty_next_blocks(ctx, b + 1)) {
5848+
if (target != _ir_next_block(ctx, _b)) {
58285849
| b =>target
58295850
}
58305851
} while (0);

0 commit comments

Comments
 (0)