views:

25

answers:

1

I've been constructing my own compiler and one large part of it is obviously the register allocator, which matches up temporary variables with machine registers as efficiently as possible. On an architecture such as the x86 there aren't many registers so there are a number of spills in which variables must be stored in memory (the stack). There are also variables stored in memory because they are too large to fit in a register.

The register allocator is actually invoked again to allocate the variables in memory efficiently, so that as much space is shared as possible. The real problem is there is no way to constrain the register allocator to place two variables in memory next to each other (since I can then give it larger variables as a number of smaller variables) and to allow the allocator to move the smaller variables around so that the larger variables can fit, and I'm wondering if there are any algorithms around to handle this, otherwise I have to split the memory into different areas, each holding variables of a different size.

Here's an example to demonstrate this:

void f(){
    int32_t a, b;
    //something happens to a and b...
    int64_t c;
    //something happens to c...
}

There are a few assumptions to make here for the purpose of the example...that the variables aren't optimized away, a and b are no longer useful once c has been defined and that all the variables are allocated to stack memory. Clearly I would want 'c' to use the same memory as 'a' and 'b' just used and hence only allocate 8 bytes, however the current version of my compiler would allocate a full 16 bytes.

My question is, how can I allocate variables in memory of different sizes efficiently?

+1  A: 

Clearly the register allocator isn't general enough to allocate stack space, since it doesn't make sense to coalesce adjacent registers—at least on an x86.

Why not expand it to do just that? Or, better yet—divide or subclass it to directly handle register and stack allocations.

As for the stack allocator, it's not usually execution time-efficient nor particularly space efficient to minimize the stack used in the (rare) case that two variables could share the same allocation due to non-overlapping scope. The operations to allocate and deallocate the extra stack space at the scope transition is unlikely to be worth it. Even in the most critical of realtime processing, one is usually way more interested in robustness and speed than shaving off a few bytes of stack space.

wallyk
Ok good points, thanks.
Stephen Cross