mirror of
https://github.com/danog/ir.git
synced 2024-12-11 16:59:46 +01:00
Cleanup spill related code
This commit is contained in:
parent
d67c212916
commit
99bcde9e1e
@ -873,6 +873,13 @@ static int32_t ir_ref_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg *reg)
|
|||||||
return IR_SPILL_POS_TO_OFFSET(offset);
|
return IR_SPILL_POS_TO_OFFSET(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ir_is_same_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg reg, int32_t offset)
|
||||||
|
{
|
||||||
|
ir_reg fp;
|
||||||
|
|
||||||
|
return ir_ref_spill_slot(ctx, ref, &fp) == offset && reg == fp;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t ir_var_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg *reg)
|
static int32_t ir_var_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg *reg)
|
||||||
{
|
{
|
||||||
ir_insn *var_insn = &ctx->ir_base[ref];
|
ir_insn *var_insn = &ctx->ir_base[ref];
|
||||||
@ -2929,12 +2936,10 @@ static void ir_emit_load_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
||||||
|
|
||||||
if (op2_reg == IR_REG_NONE) {
|
if (op2_reg == IR_REG_NONE) {
|
||||||
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
if (IR_REG_SPILLED(ctx->regs[def][0]) && ir_is_same_spill_slot(ctx, def, op1_reg, offset)) {
|
||||||
ir_reg fp;
|
/* avoid load to the same location (valid only when register is not reused) */
|
||||||
if (ir_ref_spill_slot(ctx, def, &fp) == offset && op1_reg == fp) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ir_emit_load_mem_int(ctx, type, def_reg, op1_reg, offset);
|
ir_emit_load_mem_int(ctx, type, def_reg, op1_reg, offset);
|
||||||
} else {
|
} else {
|
||||||
switch (ir_type_size[type]) {
|
switch (ir_type_size[type]) {
|
||||||
@ -2996,12 +3001,10 @@ static void ir_emit_load_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
||||||
|
|
||||||
if (op2_reg == IR_REG_NONE) {
|
if (op2_reg == IR_REG_NONE) {
|
||||||
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
if (IR_REG_SPILLED(ctx->regs[def][0]) && ir_is_same_spill_slot(ctx, def, op1_reg, offset)) {
|
||||||
ir_reg fp;
|
/* avoid load to the same location (valid only when register is not reused) */
|
||||||
if (ir_ref_spill_slot(ctx, def, &fp) == offset && op1_reg == fp) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ir_emit_load_mem_fp(ctx, type, def_reg, op1_reg, offset);
|
ir_emit_load_mem_fp(ctx, type, def_reg, op1_reg, offset);
|
||||||
} else {
|
} else {
|
||||||
if (type == IR_DOUBLE) {
|
if (type == IR_DOUBLE) {
|
||||||
@ -3042,12 +3045,10 @@ static void ir_emit_store_int(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
|||||||
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
||||||
|
|
||||||
if (op2_reg == IR_REG_NONE) {
|
if (op2_reg == IR_REG_NONE) {
|
||||||
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg)) {
|
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg) && ir_is_same_spill_slot(ctx, insn->op3, op1_reg, offset)) {
|
||||||
ir_reg fp;
|
/* avoid store to the same location */
|
||||||
if (ir_ref_spill_slot(ctx, insn->op3, &fp) == offset && op1_reg == fp) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (op3_reg == IR_REG_NONE) {
|
if (op3_reg == IR_REG_NONE) {
|
||||||
IR_ASSERT(IR_IS_CONST_REF(insn->op3) && ctx->ir_base[insn->op3].val.i64 == 0);
|
IR_ASSERT(IR_IS_CONST_REF(insn->op3) && ctx->ir_base[insn->op3].val.i64 == 0);
|
||||||
op3_reg = IR_REG_ZR;
|
op3_reg = IR_REG_ZR;
|
||||||
@ -3113,12 +3114,10 @@ static void ir_emit_store_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
|||||||
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
int32_t offset = ir_fuse_addr(ctx, insn->op2, &op1_reg, &op2_reg);
|
||||||
|
|
||||||
if (op2_reg == IR_REG_NONE) {
|
if (op2_reg == IR_REG_NONE) {
|
||||||
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg)) {
|
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg) && ir_is_same_spill_slot(ctx, insn->op3, op1_reg, offset)) {
|
||||||
ir_reg fp;
|
/* avoid store to the same location */
|
||||||
if (ir_ref_spill_slot(ctx, insn->op3, &fp) == offset && op1_reg == fp) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (IR_REG_SPILLED(op3_reg) || IR_IS_CONST_REF(insn->op3)) {
|
if (IR_REG_SPILLED(op3_reg) || IR_IS_CONST_REF(insn->op3)) {
|
||||||
op3_reg = IR_REG_NUM(op3_reg);
|
op3_reg = IR_REG_NUM(op3_reg);
|
||||||
ir_emit_load(ctx, type, op3_reg, insn->op3);
|
ir_emit_load(ctx, type, op3_reg, insn->op3);
|
||||||
@ -3154,7 +3153,6 @@ static void ir_emit_rload(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
{
|
{
|
||||||
ir_reg src_reg = insn->op2;
|
ir_reg src_reg = insn->op2;
|
||||||
ir_type type = insn->type;
|
ir_type type = insn->type;
|
||||||
ir_reg fp;
|
|
||||||
|
|
||||||
if (IR_REGSET_IN(IR_REGSET_UNION((ir_regset)ctx->fixed_regset, IR_REGSET_FIXED), src_reg)) {
|
if (IR_REGSET_IN(IR_REGSET_UNION((ir_regset)ctx->fixed_regset, IR_REGSET_FIXED), src_reg)) {
|
||||||
if (ctx->vregs[def]
|
if (ctx->vregs[def]
|
||||||
@ -3169,7 +3167,7 @@ static void ir_emit_rload(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
/* op3 is used as a flag that the value is already stored in memory.
|
/* op3 is used as a flag that the value is already stored in memory.
|
||||||
* If op3 is set we don't have to store the value once again (in case of spilling)
|
* If op3 is set we don't have to store the value once again (in case of spilling)
|
||||||
*/
|
*/
|
||||||
if (!insn->op3 || insn->op3 != ir_ref_spill_slot(ctx, def, &fp) || fp != ctx->spill_base) {
|
if (!insn->op3 || !ir_is_same_spill_slot(ctx, def, ctx->spill_base, insn->op3)) {
|
||||||
ir_emit_store(ctx, type, def, src_reg);
|
ir_emit_store(ctx, type, def, src_reg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3182,7 +3180,7 @@ static void ir_emit_rload(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IR_REG_SPILLED(ctx->regs[def][0])
|
if (IR_REG_SPILLED(ctx->regs[def][0])
|
||||||
&& (!insn->op3 || insn->op3 != ir_ref_spill_slot(ctx, def, &fp) || fp != ctx->spill_base)) {
|
&& (!insn->op3 || !ir_is_same_spill_slot(ctx, def, ctx->spill_base, insn->op3))) {
|
||||||
ir_emit_store(ctx, type, def, def_reg);
|
ir_emit_store(ctx, type, def, def_reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
ir_x86.dasc
36
ir_x86.dasc
@ -1899,6 +1899,13 @@ static int32_t ir_ref_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg *reg)
|
|||||||
return IR_SPILL_POS_TO_OFFSET(offset);
|
return IR_SPILL_POS_TO_OFFSET(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ir_is_same_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg reg, int32_t offset)
|
||||||
|
{
|
||||||
|
ir_reg fp;
|
||||||
|
|
||||||
|
return ir_ref_spill_slot(ctx, ref, &fp) == offset && reg == fp;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t ir_var_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg *reg)
|
static int32_t ir_var_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg *reg)
|
||||||
{
|
{
|
||||||
ir_insn *var_insn = &ctx->ir_base[ref];
|
ir_insn *var_insn = &ctx->ir_base[ref];
|
||||||
@ -5303,12 +5310,10 @@ static void ir_emit_load_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
}
|
}
|
||||||
if (!IR_IS_CONST_REF(insn->op2) && (ir_rule(ctx, insn->op2) & IR_FUSED)) {
|
if (!IR_IS_CONST_REF(insn->op2) && (ir_rule(ctx, insn->op2) & IR_FUSED)) {
|
||||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||||
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
if (IR_REG_SPILLED(ctx->regs[def][0]) && ir_is_same_spill_slot(ctx, def, op2_reg, offset)) {
|
||||||
ir_reg fp;
|
/* avoid load to the same location (valid only when register is not reused) */
|
||||||
if (ir_ref_spill_slot(ctx, def, &fp) == offset && op2_reg == fp) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (IR_REG_SPILLED(op2_reg) || IR_IS_CONST_REF(insn->op2)) {
|
} else if (IR_REG_SPILLED(op2_reg) || IR_IS_CONST_REF(insn->op2)) {
|
||||||
op2_reg = IR_REG_NUM(op2_reg);
|
op2_reg = IR_REG_NUM(op2_reg);
|
||||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||||
@ -5350,12 +5355,10 @@ static void ir_emit_load_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
}
|
}
|
||||||
} else if (op2_reg == IR_REG_NONE) {
|
} else if (op2_reg == IR_REG_NONE) {
|
||||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||||
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
if (IR_REG_SPILLED(ctx->regs[def][0]) && ir_is_same_spill_slot(ctx, def, op2_reg, offset)) {
|
||||||
ir_reg fp;
|
/* avoid load to the same location (valid only when register is not reused) */
|
||||||
if (ir_ref_spill_slot(ctx, def, &fp) == offset && op2_reg == fp) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (IR_REG_SPILLED(op2_reg)) {
|
} else if (IR_REG_SPILLED(op2_reg)) {
|
||||||
op2_reg = IR_REG_NUM(op2_reg);
|
op2_reg = IR_REG_NUM(op2_reg);
|
||||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||||
@ -5400,12 +5403,10 @@ static void ir_emit_store_int(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
|||||||
}
|
}
|
||||||
} else if (op2_reg == IR_REG_NONE) {
|
} else if (op2_reg == IR_REG_NONE) {
|
||||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||||
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg)) {
|
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg) && ir_is_same_spill_slot(ctx, insn->op3, op2_reg, offset)) {
|
||||||
ir_reg fp;
|
/* avoid store to the same location */
|
||||||
if (ir_ref_spill_slot(ctx, insn->op3, &fp) == offset && op2_reg == fp) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (IR_REG_SPILLED(op2_reg)) {
|
} else if (IR_REG_SPILLED(op2_reg)) {
|
||||||
op2_reg = IR_REG_NUM(op2_reg);
|
op2_reg = IR_REG_NUM(op2_reg);
|
||||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||||
@ -5450,12 +5451,10 @@ static void ir_emit_store_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
|||||||
}
|
}
|
||||||
} else if (op2_reg == IR_REG_NONE) {
|
} else if (op2_reg == IR_REG_NONE) {
|
||||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||||
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg)) {
|
if (!IR_IS_CONST_REF(insn->op3) && IR_REG_SPILLED(op3_reg) && ir_is_same_spill_slot(ctx, insn->op3, op2_reg, offset)) {
|
||||||
ir_reg fp;
|
/* avoid store to the same location */
|
||||||
if (ir_ref_spill_slot(ctx, insn->op3, &fp) == offset && op2_reg == fp) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (IR_REG_SPILLED(op2_reg)) {
|
} else if (IR_REG_SPILLED(op2_reg)) {
|
||||||
op2_reg = IR_REG_NUM(op2_reg);
|
op2_reg = IR_REG_NUM(op2_reg);
|
||||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||||
@ -5473,7 +5472,6 @@ static void ir_emit_rload(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
{
|
{
|
||||||
ir_reg src_reg = insn->op2;
|
ir_reg src_reg = insn->op2;
|
||||||
ir_type type = insn->type;
|
ir_type type = insn->type;
|
||||||
ir_reg fp;
|
|
||||||
|
|
||||||
if (IR_REGSET_IN(IR_REGSET_UNION((ir_regset)ctx->fixed_regset, IR_REGSET_FIXED), src_reg)) {
|
if (IR_REGSET_IN(IR_REGSET_UNION((ir_regset)ctx->fixed_regset, IR_REGSET_FIXED), src_reg)) {
|
||||||
if (ctx->vregs[def]
|
if (ctx->vregs[def]
|
||||||
@ -5488,7 +5486,7 @@ static void ir_emit_rload(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
/* op3 is used as a flag that the value is already stored in memory.
|
/* op3 is used as a flag that the value is already stored in memory.
|
||||||
* If op3 is set we don't have to store the value once again (in case of spilling)
|
* If op3 is set we don't have to store the value once again (in case of spilling)
|
||||||
*/
|
*/
|
||||||
if (!insn->op3 || insn->op3 != ir_ref_spill_slot(ctx, def, &fp) || fp != ctx->spill_base) {
|
if (!insn->op3 || !ir_is_same_spill_slot(ctx, def, ctx->spill_base, insn->op3)) {
|
||||||
ir_emit_store(ctx, type, def, src_reg);
|
ir_emit_store(ctx, type, def, src_reg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -5501,7 +5499,7 @@ static void ir_emit_rload(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IR_REG_SPILLED(ctx->regs[def][0])
|
if (IR_REG_SPILLED(ctx->regs[def][0])
|
||||||
&& (!insn->op3 || insn->op3 != ir_ref_spill_slot(ctx, def, &fp) || fp != ctx->spill_base)) {
|
&& (!insn->op3 || !ir_is_same_spill_slot(ctx, def, ctx->spill_base, insn->op3))) {
|
||||||
ir_emit_store(ctx, type, def, def_reg);
|
ir_emit_store(ctx, type, def, def_reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user