pass: de-prioritize base pointer in register allocation (#184)

Updates #156
This commit is contained in:
Michael McLoughlin
2021-04-18 19:22:09 -07:00
committed by GitHub
parent f295bde84c
commit c32f24fb1e
9 changed files with 5273 additions and 5207 deletions

View File

@@ -106,6 +106,51 @@ func ConstructLiveness(t *testing.T, ctx *build.Context) *ir.Function {
return BuildFunction(t, ctx, pass.LabelTarget, pass.CFG, pass.Liveness)
}
func TestAllocateRegistersBasePointerDeprioritized(t *testing.T) {
// Construct a function that requires n general-purpose registers all live
// at once. Choose n to be the maximal possible number of registers without
// touching the base pointer.
n := 14
ctx := build.NewContext()
ctx.Function("sum")
ctx.SignatureExpr("func() uint64")
x := make([]reg.GPVirtual, n)
for i := 0; i < n; i++ {
x[i] = ctx.GP64()
ctx.MOVQ(operand.U64(i), x[i])
}
for i := 1; i < n; i++ {
ctx.ADDQ(x[i], x[0])
}
ctx.Store(x[0], ctx.ReturnIndex(0))
ctx.RET()
// Build and compile the function up to register allocation.
fn := BuildFunction(t, ctx, pass.LabelTarget, pass.CFG, pass.Liveness, pass.AllocateRegisters, pass.BindRegisters)
// Verify this function uses n registers, but not the base pointer.
ps := map[reg.Physical]bool{}
for _, i := range fn.Instructions() {
for _, r := range i.OutputRegisters() {
ps[reg.ToPhysical(r)] = true
}
}
if len(ps) != n {
t.Fatalf("expected function to require %d registers", n)
}
for p := range ps {
if (p.Info() & reg.BasePointer) != 0 {
t.Fatal("base pointer used")
}
}
}
func TestEnsureBasePointerCalleeSavedFrameless(t *testing.T) {
// Construct a function that writes to the base pointer.
ctx := build.NewContext()