[LLVMdev] Pointer vs. integer: backend troubles
Jakob Stoklund Olesen
stoklund at 2pi.dk
Wed May 6 10:47:26 PDT 2009
On 06/05/2009, at 10.58, Christoph Erhardt wrote:
[...]
> Unfortunately, this does not hold true for the TriCore architecture,
> which strictly differentiates between "normal" integer values and
> pointer values. The register set is split into two subsets: 16
> general-purpose registers %d0..%d15 for 32-bit integers and floats,
> and
> 16 address registers %a0..%a15 for 32-bit pointers, with separate
> instructions.
Hi Christoph,
I am working on a back end for the blackfin DSP. It also has two
register sets: data and pointers, so the architectures are similar. I
am using a lot of register classes to represent the many instruction
constraints. The code generator support for weird register classes has
improved a lot recently.
The instruction selector does not know about register classes - it
only uses value types when pattern matching. That is probably a good
idea; it can be hard to tell what is a pointer and what is an integer
beforehand.
After instruction selection is complete, each virtual register is
assigned to a register class (A or D, say). Currently, the defining
instruction determines the register class. Sometimes it is necessary
to insert extra copy instructions before instructions that require an
incompatible register class. Enabling -join-cross-class-copies will
clean up a lot of these copies afterwards.
I have a patch in my own tree that will do register class inference
instead: It tries to choose a register class for a virtual register
based on all interested instructions, rather than just the defining
one. This causes less copies to be emitted only to be removed later.
The end result is similar, so it is mostly an optimisation.
There are some unsolved problems:
1. Virtual registers from PHI nodes are created before instruction
selection, so there is no way of giving them a proper register class.
Instead, TargetLowering::getRegClassFor() is used, fingers crossed. It
may be that -join-cross-class-copies is able to clean up here too. I
have not tested that. Ideally, I would like
TargetLowering::getRegClassFor() to go away entirely.
2. There is no way of using alternative instructions with different
operand classes. For instance, TriCore can subtract two D registers
(SUB), or two A registers (SUB.A). You can only have one pattern for
i32 subtraction, so the SUB.A instruction will not be used. We need a
way of replacing SUB with SUB.A when it makes sense. Calculating when
it makes sense is the hard part.
You can produce correct code without solving these problems - you will
just have some extra copies between A and D registers.
> Moreover, the ABI requires that pointer arguments to (and
> pointer results from) functions be passed in address registers instead
> of general-purpose registers.
You should treat this as a separate issue from register allocation.
The ABI requirements must be followed exactly, and you need some kind
of annotation as Dan described. For register allocation you can be
less exact, and that can be an advantage. Pointer and integer
arithmetic is sometimes mixed, and it can be an advantage to keep an
integer in a pointer register and vice versa.
HTH
/jakob
More information about the llvm-dev
mailing list