@@ -1967,17 +1967,17 @@ static void ir_emit_overflow(ir_ctx *ctx, ir_ref def, ir_insn *insn)
1967
1967
}
1968
1968
}
1969
1969
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 )
1971
1971
{
1972
1972
ir_backend_data *data = ctx->data;
1973
1973
dasm_State **Dst = &data->dasm_state;
1974
1974
ir_insn *overflow_insn = &ctx->ir_base[insn->op2];
1975
1975
ir_insn *math_insn = &ctx->ir_base[overflow_insn->op1];
1976
1976
ir_type type = math_insn->type;
1977
- uint32_t true_block, false_block, next_block ;
1977
+ uint32_t true_block, false_block;
1978
1978
bool reverse = 0;
1979
1979
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);
1981
1981
if (true_block == next_block) {
1982
1982
reverse = 1;
1983
1983
true_block = false_block;
@@ -2845,37 +2845,37 @@ static void ir_emit_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
2845
2845
}
2846
2846
}
2847
2847
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 )
2849
2849
{
2850
- uint32_t true_block, false_block, next_block ;
2850
+ uint32_t true_block, false_block;
2851
2851
ir_backend_data *data = ctx->data;
2852
2852
dasm_State **Dst = &data->dasm_state;
2853
2853
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);
2855
2855
if (true_block != next_block) {
2856
2856
| b =>true_block
2857
2857
}
2858
2858
}
2859
2859
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 )
2861
2861
{
2862
- uint32_t true_block, false_block, next_block ;
2862
+ uint32_t true_block, false_block;
2863
2863
ir_backend_data *data = ctx->data;
2864
2864
dasm_State **Dst = &data->dasm_state;
2865
2865
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);
2867
2867
if (false_block != next_block) {
2868
2868
| b =>false_block
2869
2869
}
2870
2870
}
2871
2871
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)
2873
2873
{
2874
- uint32_t true_block, false_block, next_block ;
2874
+ uint32_t true_block, false_block;
2875
2875
ir_backend_data *data = ctx->data;
2876
2876
dasm_State **Dst = &data->dasm_state;
2877
2877
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);
2879
2879
if (true_block == next_block) {
2880
2880
IR_ASSERT(op < IR_LT);
2881
2881
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
2904
2904
}
2905
2905
}
2906
2906
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)
2908
2908
{
2909
- uint32_t true_block, false_block, next_block ;
2909
+ uint32_t true_block, false_block;
2910
2910
ir_backend_data *data = ctx->data;
2911
2911
dasm_State **Dst = &data->dasm_state;
2912
2912
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);
2914
2914
if (true_block == next_block) {
2915
2915
/* swap to avoid unconditional JMP */
2916
2916
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
3004
3004
}
3005
3005
}
3006
3006
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 )
3008
3008
{
3009
3009
ir_insn *cmp_insn = &ctx->ir_base[insn->op2];
3010
3010
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
3037
3037
&& ctx->ir_base[op2].val.u64 == 0) {
3038
3038
if (op == IR_ULT) {
3039
3039
/* always false */
3040
- ir_emit_jmp_false(ctx, b, def);
3040
+ ir_emit_jmp_false(ctx, b, def, next_block );
3041
3041
return;
3042
3042
} else if (op == IR_UGE) {
3043
3043
/* always true */
3044
- ir_emit_jmp_true(ctx, b, def);
3044
+ ir_emit_jmp_true(ctx, b, def, next_block );
3045
3045
return;
3046
3046
} else if (op == IR_ULE) {
3047
3047
op = IR_EQ;
3048
3048
} else if (op == IR_UGT) {
3049
3049
op = IR_NE;
3050
3050
}
3051
3051
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);
3053
3053
return;
3054
3054
}
3055
3055
}
3056
3056
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);
3058
3058
}
3059
3059
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 )
3061
3061
{
3062
3062
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);
3064
3064
}
3065
3065
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 )
3067
3067
{
3068
3068
ir_type type = ctx->ir_base[insn->op2].type;
3069
3069
ir_reg op2_reg = ctx->regs[def][2];
3070
3070
ir_backend_data *data = ctx->data;
3071
3071
dasm_State **Dst = &data->dasm_state;
3072
3072
3073
3073
if (IR_IS_CONST_REF(insn->op2)) {
3074
- uint32_t true_block, false_block, next_block ;
3074
+ uint32_t true_block, false_block;
3075
3075
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);
3077
3077
if (ir_const_is_true(&ctx->ir_base[insn->op2])) {
3078
3078
if (true_block != next_block) {
3079
3079
| 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)
3091
3091
ir_emit_load(ctx, type, op2_reg, insn->op2);
3092
3092
}
3093
3093
| 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);
3095
3095
}
3096
3096
3097
3097
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];
5610
5610
/* Veneers support (TODO: avid global variable usage) */
5611
5611
static ir_ctx *ir_current_ctx;
5612
5612
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
+
5613
5624
void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
5614
5625
{
5615
- uint32_t b, n, target;
5626
+ uint32_t _b, b, n, target;
5616
5627
ir_block *bb;
5617
5628
ir_ref i;
5618
5629
ir_insn *insn;
@@ -5674,7 +5685,17 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
5674
5685
ir_emit_load_params(ctx);
5675
5686
}
5676
5687
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];
5678
5699
IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE));
5679
5700
if ((bb->flags & (IR_BB_START|IR_BB_ENTRY|IR_BB_EMPTY)) == IR_BB_EMPTY) {
5680
5701
continue;
@@ -5774,10 +5795,10 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
5774
5795
ir_emit_copy_fp(ctx, i, insn);
5775
5796
break;
5776
5797
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) );
5778
5799
break;
5779
5800
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) );
5781
5802
break;
5782
5803
case IR_GUARD_CMP_INT:
5783
5804
ir_emit_guard_cmp_int(ctx, b, i, insn);
@@ -5786,7 +5807,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
5786
5807
ir_emit_guard_cmp_fp(ctx, b, i, insn);
5787
5808
break;
5788
5809
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) );
5790
5811
break;
5791
5812
case IR_COND:
5792
5813
ir_emit_cond(ctx, i, insn);
@@ -5801,7 +5822,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
5801
5822
ir_emit_overflow(ctx, i, insn);
5802
5823
break;
5803
5824
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) );
5805
5826
break;
5806
5827
case IR_END:
5807
5828
case IR_LOOP_END:
@@ -5824,7 +5845,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
5824
5845
IR_ASSERT(bb->successors_count == 1);
5825
5846
}
5826
5847
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 )) {
5828
5849
| b =>target
5829
5850
}
5830
5851
} while (0);
0 commit comments