(no subject)

I’m trying to debug a problem with our custom backend with using a tiered register allocation setup.

Just a little background. My target uses vec4 32bit registers and I want to have three levels of registers setup.

Each vec4 register can have two sub-regs of size vec2 32bit, and each sub-reg, has its own two sub-regs of 32bit each.

So it looks like this, xyzw → {xy, zw} → {x, y, z, w}.

Now the problem I am having is that for some reason, the linearscan allocator is running out of registers to allocate.

This makes no sense to me as I have 1024 vec4 registers(so 2048 vec2 and 4096 scalars).

So I limited to a very small test case where I have 1 vec4(2 vec2 and 4 scalar) registers with

a function that requires 1 vec4 register and 5 scalar registers. So, basically what happens

is that everything works fine until the live-in register(which is scalar) to the function

conflicts with a register that is allocated for the vector(as it is a sub-sub-reg). The

linear scan allocator attempts to spill the live-in onto itself and then asserts with

assert(false && “Ran out of registers during register allocation!”);.

I’ve attached the output of running LLC on my test case, which

I don’t know if it will be helpful or not, to see what the live

interval and reg allocator are doing.

I’m having trouble debugging this, any idea on where I might want to look?

Another question is how do I influence the spill costs? I want to make live in’s

infinitely expensive to spill, so any superreg or super-super-reg of the live in

never gets allocated.

Thanks,

Micah

output.txt (19.8 KB)

I'm trying to debug a problem with our custom backend with using a tiered register allocation setup.

Just a little background. My target uses vec4 32bit registers and I want to have three levels of registers setup.
Each vec4 register can have two sub-regs of size vec2 32bit, and each sub-reg, has its own two sub-regs of 32bit each.
So it looks like this, xyzw -> {xy, zw} -> {x, y, z, w}.

Now the problem I am having is that for some reason, the linearscan allocator is running out of registers to allocate.

This makes no sense to me as I have 1024 vec4 registers(so 2048 vec2 and 4096 scalars).
So I limited to a very small test case where I have 1 vec4(2 vec2 and 4 scalar) registers with
a function that requires 1 vec4 register and 5 scalar registers. So, basically what happens
is that everything works fine until the live-in register(which is scalar) to the function
conflicts with a register that is allocated for the vector(as it is a sub-sub-reg). The
linear scan allocator attempts to spill the live-in onto itself and then asserts with
assert(false && "Ran out of registers during register allocation!");.

I've attached the output of running LLC on my test case, which
I don't know if it will be helpful or not, to see what the live
interval and reg allocator are doing.

I'm having trouble debugging this, any idea on where I might want to look?

It's hard to tell without knowing your target. Why does the allocator think there are no free registers in your register class?

Another question is how do I influence the spill costs? I want to make live in's

infinitely expensive to spill, so any superreg or super-super-reg of the live in
never gets allocated.

It's not clear what you mean here. Spill costs are assigned to virtual registers, and virtual registers don't have sub- or super-registers.

If you mean linear scan's emergency spilling of physical registers, that should never happen anyway. Something else is wrong.

BTW, the new greedy register allocator is way better. It never makes mistakes!

/jakob

I’m trying to debug a problem with our custom backend with using a tiered register allocation setup.

Just a little background. My target uses vec4 32bit registers and I want to have three levels of registers setup.

Each vec4 register can have two sub-regs of size vec2 32bit, and each sub-reg, has its own two sub-regs of 32bit each.

So it looks like this, xyzw → {xy, zw} → {x, y, z, w}.

Now the problem I am having is that for some reason, the linearscan allocator is running out of registers to allocate.

This makes no sense to me as I have 1024 vec4 registers(so 2048 vec2 and 4096 scalars).

So I limited to a very small test case where I have 1 vec4(2 vec2 and 4 scalar) registers with

a function that requires 1 vec4 register and 5 scalar registers. So, basically what happens

is that everything works fine until the live-in register(which is scalar) to the function

conflicts with a register that is allocated for the vector(as it is a sub-sub-reg). The

linear scan allocator attempts to spill the live-in onto itself and then asserts with

assert(false && “Ran out of registers during register allocation!”);.

I’ve attached the output of running LLC on my test case, which

I don’t know if it will be helpful or not, to see what the live

interval and reg allocator are doing.

I’m having trouble debugging this, any idea on where I might want to look?

It’s hard to tell without knowing your target. Why does the allocator think there are no free registers in your register class?

[Villmow, Micah] That is what I can’t figure out. I am only setting the live-in’s and some special registers as reserved, and with 1k vector registers, I should not be having any trouble. Somehow the register allocator thinks all registers are used, but if that is the case, it should spill to memory, and even that is failing! If I don’t use sub-registers, then I don’t have this

problem, but then I really can’t specify that one register class is a subclass of another.

Another question is how do I influence the spill costs? I want to make live in’s

infinitely expensive to spill, so any superreg or super-super-reg of the live in

never gets allocated.

It’s not clear what you mean here. Spill costs are assigned to virtual registers, and virtual registers don’t have sub- or super-registers.

If you mean linear scan’s emergency spilling of physical registers, that should never happen anyway. Something else is wrong.

[Villmow, Micah] Yeah, i’m hitting this assert to because I’m emergency spilling twice some times.

BTW, the new greedy register allocator is way better. It never makes mistakes!

/jakob

From: Jakob Stoklund Olesen [mailto:stoklund@2pi.dk]
Sent: Friday, July 01, 2011 2:56 PM
To: Villmow, Micah
Cc: llvmdev@cs.uiuc.edu
Subject: Re: [LLVMdev] (no subject)

I'm trying to debug a problem with our custom backend with using a tiered register allocation setup.

Just a little background. My target uses vec4 32bit registers and I want to have three levels of registers setup.
Each vec4 register can have two sub-regs of size vec2 32bit, and each sub-reg, has its own two sub-regs of 32bit each.
So it looks like this, xyzw -> {xy, zw} -> {x, y, z, w}.

Now the problem I am having is that for some reason, the linearscan allocator is running out of registers to allocate.

This makes no sense to me as I have 1024 vec4 registers(so 2048 vec2 and 4096 scalars).
So I limited to a very small test case where I have 1 vec4(2 vec2 and 4 scalar) registers with
a function that requires 1 vec4 register and 5 scalar registers. So, basically what happens
is that everything works fine until the live-in register(which is scalar) to the function
conflicts with a register that is allocated for the vector(as it is a sub-sub-reg). The
linear scan allocator attempts to spill the live-in onto itself and then asserts with
assert(false && "Ran out of registers during register allocation!");.

I've attached the output of running LLC on my test case, which
I don't know if it will be helpful or not, to see what the live
interval and reg allocator are doing.

I'm having trouble debugging this, any idea on where I might want to look?

It's hard to tell without knowing your target. Why does the allocator think there are no free registers in your register class?
[Villmow, Micah] That is what I can't figure out. I am only setting the live-in's and some special registers as reserved, and with 1k vector registers, I should not be having any trouble. Somehow the register allocator thinks all registers are used, but if that is the case, it should spill to memory, and even that is failing! If I don't use sub-registers, then I don't have this
problem, but then I really can't specify that one register class is a subclass of another.

Another question is how do I influence the spill costs? I want to make live in's

infinitely expensive to spill, so any superreg or super-super-reg of the live in
never gets allocated.

It's not clear what you mean here. Spill costs are assigned to virtual registers, and virtual registers don't have sub- or super-registers.

If you mean linear scan's emergency spilling of physical registers, that should never happen anyway. Something else is wrong.
[Villmow, Micah] Yeah, i'm hitting this assert to because I'm emergency spilling twice some times.

Are you intentionally creating new virtual registers after register allocation?

That assert implies the live ranges of the virtual registers being created after register allocation are too big and overlap. The register scavenger constrains its problem to only a single register being scavenged at a time. The idea is to only use it when you need a temporary register with a very, very short live range (usually two or three instructions) to materialize a value into or something like that. Anything more complicated should go through the real register allocator.

-Jim