Allocate scratch (caller-saved) registers first

This commit is contained in:
Dmitry Stogov 2022-04-15 14:22:35 +03:00
parent 2c2f2dabab
commit 3cb707522f
3 changed files with 40 additions and 4 deletions

7
TODO
View File

@ -35,7 +35,7 @@
? register allocation
+ linear scan
- allocate scratch registers first
+ allocate scratch registers first
- separate INT and FP allocation phases
+ use positions
? fixed registers constraints
@ -52,14 +52,13 @@
+ spill slot allocation ( uniqe for each VREG)
- uniqe for each VREG
- SpillRange ???
- splitting
- SplitAt
? splitting
- splinting
- spill only at cold path if possible
? hints
+ hints for fixed input/outpu registers
+ hints for parameter nodes
- hints for call arguments
+ hints for call arguments
- hints propagation
- hints and low priority

View File

@ -962,6 +962,12 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, int current, uint32_t len, i
if (freeUntilPos[i] > pos) {
pos = freeUntilPos[i];
reg = i;
} else if (freeUntilPos[i] == pos
&& !IR_REGSET_IN(IR_REGSET_SCRATCH, reg)
&& IR_REGSET_IN(IR_REGSET_SCRATCH, i)) {
/* prefer caller-saved registers to avoid save/restore in prologue/epilogue */
pos = freeUntilPos[i];
reg = i;
}
} IR_REGSET_FOREACH_END();

31
tests/x86_64/ra_013.irt Normal file
View File

@ -0,0 +1,31 @@
--TEST--
013: Register Allocation (MOD + MOD + MOD)
--ARGS--
-S
--CODE--
{
l_1 = START(l_4);
uint32_t x_1 = PARAM(l_1, "x", 1);
uint32_t y_1 = PARAM(l_1, "y", 2);
uint32_t z_1 = PARAM(l_1, "z", 3);
uint32_t v_1 = PARAM(l_1, "v", 4);
uint32_t x_2 = MOD(x_1, y_1);
uint32_t x_3 = MOD(x_2, z_1);
uint32_t x_4 = MOD(v_1, x_3);
l_4 = RETURN(l_1, x_4);
}
--EXPECT--
test:
movl %edx, %r8d
movl %edi, %eax
xorl %edx, %edx
divl %esi
movl %edx, %eax
xorl %edx, %edx
divl %r8d
movl %edx, %esi
movl %ecx, %eax
xorl %edx, %edx
divl %esi
movl %edx, %eax
retq