@@ -996,6 +996,7 @@ binop_fp:
996
996
case IR_IF_TRUE:
997
997
case IR_IF_FALSE:
998
998
case IR_CASE_VAL:
999
+ case IR_CASE_RANGE:
999
1000
case IR_CASE_DEFAULT:
1000
1001
case IR_MERGE:
1001
1002
case IR_LOOP_BEGIN:
@@ -4366,11 +4367,15 @@ static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn)
4366
4367
ir_backend_data *data = ctx->data;
4367
4368
dasm_State **Dst = &data->dasm_state;
4368
4369
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]) ;
4370
4371
ir_reg op2_reg = ctx->regs[def][2];
4371
4372
ir_reg tmp_reg = ctx->regs[def][3];
4372
4373
int32_t offset;
4373
4374
4375
+ if (ctx->use_lists[def].count == 1) {
4376
+ /* dead load */
4377
+ return;
4378
+ }
4374
4379
IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE);
4375
4380
if (op2_reg != IR_REG_NONE) {
4376
4381
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)
4394
4399
ir_backend_data *data = ctx->data;
4395
4400
dasm_State **Dst = &data->dasm_state;
4396
4401
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]) ;
4398
4403
ir_reg op2_reg = ctx->regs[def][2];
4399
4404
ir_reg tmp_reg = ctx->regs[def][3];
4400
4405
int32_t offset;
4401
4406
4407
+ if (ctx->use_lists[def].count == 1) {
4408
+ /* dead load */
4409
+ return;
4410
+ }
4402
4411
IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE);
4403
4412
if (op2_reg != IR_REG_NONE) {
4404
4413
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)
4465
4474
int count = 0;
4466
4475
ir_val min, max;
4467
4476
ir_reg op1_reg, op2_reg, tmp_reg;
4477
+ bool has_case_range = 0;
4468
4478
4469
4479
type = ctx->ir_base[insn->op2].type;
4470
4480
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)
4493
4503
max.u64 = (int64_t)IR_MAX(max.u64, val->val.u64);
4494
4504
}
4495
4505
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++;
4496
4522
} else {
4497
4523
IR_ASSERT(use_insn->op == IR_CASE_DEFAULT);
4498
4524
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)
4510
4536
}
4511
4537
4512
4538
/* 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) {
4514
4540
int *labels = ir_mem_malloc(sizeof(int) * (max.i64 - min.i64 + 1));
4515
4541
4516
4542
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)
4615
4641
4616
4642
}
4617
4643
| 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:
4618
4676
}
4619
4677
}
4620
4678
if (default_label) {
@@ -4935,6 +4993,28 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
4935
4993
return;
4936
4994
}
4937
4995
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
+
4938
5018
ir_emit_epilogue(ctx);
4939
5019
4940
5020
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)
4947
5027
| br Rx(IR_REG_INT_TMP)
4948
5028
}
4949
5029
} else {
4950
- ir_reg op2_reg = ctx->regs[def][2];
4951
-
4952
5030
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));
4957
5032
| br Rx(op2_reg)
4958
5033
}
4959
5034
}
@@ -5590,6 +5665,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx)
5590
5665
case IR_IF_TRUE:
5591
5666
case IR_IF_FALSE:
5592
5667
case IR_CASE_VAL:
5668
+ case IR_CASE_RANGE:
5593
5669
case IR_CASE_DEFAULT:
5594
5670
case IR_MERGE:
5595
5671
case IR_LOOP_BEGIN:
0 commit comments