Related articles |
---|
Nitty-gritty aspects of register allocation elronnd@elronnd.net (Elijah Stone) (2020-09-10) |
Re: Nitty-gritty aspects of register allocation alexfrunews@gmail.com (Alexei A. Frounze) (2020-09-10) |
Re: Nitty-gritty aspects of register allocation bo@bo-persson.se (Bo Persson) (2020-09-11) |
Re: Nitty-gritty aspects of register allocation anton@mips.complang.tuwien.ac.at (2020-09-11) |
From: | Elijah Stone <elronnd@elronnd.net> |
Newsgroups: | comp.compilers |
Date: | Thu, 10 Sep 2020 16:41:26 -0700 |
Organization: | A noiseless patient Spider |
Injection-Info: | gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="64671"; mail-complaints-to="abuse@iecc.com" |
Keywords: | code, optimize, question |
Posted-Date: | 10 Sep 2020 20:14:09 EDT |
There is a lot of research and a lot of resources on the high-level
aspects of register allocation--colouring interference graphs, lifetimes,
CFGs, etc.
But there are a lot of low-level architecture-specific things that these
models don't account for on their own. Most notably, not all registers
can be used for the same things. Just on amd64:
- Multiplication and division use the rdx:rax register pair.
- Bit shifts always use cl.
- When calling functions, their arguments have to go in specific registers.
In all of these cases, you can spill whatever happens to already be in
those registers, but it would be nicer if you could arrange for the
appropriate values to already be in the right places. But how? A naive
solution to the first two problems just makes rax/rcx/rdx the
lowest-priority registers except when doing a multiply/divide/shift; and
spills only if necessary (rare). But that's not a general solution
(imagine if every register has a few pieces of unique functionality), and
function calls reserve too many registers for that strategy to be
practical in that case.
Bonus microconsiderations (these seem much easier to model, but still not
trivial):
- Some registers need a special prefix to be used (REX prefix). These
registers are generally different from the special-purpose registers
(for e.g. multiplication). Is it better to put a non-multiplied value
in a REX-prefixed register, or keep it in an unprefixed register and
spill it later when you need to multiply?
- The second-lowest 8 bits of some registers can be addressed
separately. When does it make sense to use them?
(All of these are x86-specific, and most architectures admittedly have
fewer esotericisms.)
--
time flies like an arrow;
fruit flies like a banana
Return to the
comp.compilers page.
Search the
comp.compilers archives again.