[llvm-dev] The Trouble with Triples

Renato Golin via llvm-dev llvm-dev at lists.llvm.org
Tue Sep 15 12:21:43 PDT 2015

On 15 September 2015 at 19:34, Daniel Sanders <Daniel.Sanders at imgtec.com> wrote:
> We can go further with this analogy too. For example, let's say John Smith
> with the SSN Y also answers to the name Rameses. This is the problem that
> Renato is working on. Renato needs to be able to see the name Rameses and
> map this to the correct John Smith (or at least someone very much like him).
> This is the gist of what ARMTargetParser is/was doing.

A good example is "krait", a CPU design from Qualcomm.

Krait used to be mapped to Cortex-A15 because it has VFP4 and HDIV,
but architecturally, it is a lot closer to a Cortex-A9 than an A15. So
assuming that Krait == A15 means making a lot of bad optimisation
decisions in the back-end, and the code performed poorly.

This year we made the change, so that Krait == A9+HDIV+VFP4, but
neither the triple, nor the CPU descriptions could cope with that.
Then, a hack was made to treat "krait" especially, changing the
internal options (triple and others) to explicitly say cpu=A9 + HDIV +

Logic like that is spread all over the compiler, not just in the
driver, but the back-end. For example, the recent discussions about
GNUEABI not entirely being the same as EABI, and the need for
additional flags, such as "-meabi=gnu". This has direct consequences
to the back-end, which has knowledge that it should not have (when
gnueabi is really just eabi, and when it's not). The back-end should
be ignorant of such things and have a flag "isEabi" do this "else" do

But triples can't do that at all. As Daniel demonstrated, they have a
very specific, irrational and sometimes perverse meaning. Any change
we do to the triples will impact compatibility with other toolchains
and we can't afford that.

So, instead of refactoring the Triple to carry all legacy + all decent
logic, we thought that making the Triple into *just* legacy, and
having a Tuple as the new way forward we'd achieve two main goals that
was discussed in the community for a very long time:

1. Separate target-specific crud from the rest. That also includes
"legacy ARM" from "new ARM". All users of these interfaces should not
just be unaware of the underlying complexity, but also not have to pay
the price for that complexity. So all string-parsing, name-mangling,
legacy-wrapper should be the last action, not the first.

2. Be able to create complex target descriptions from the command
line, or a config file, or some database, or whatever. Especially in
the ARM world, target description databases are not uncommon, as they
solve the ambiguity problem in a clear way. But we don't want to move
everyone into a complex database just because ARM description is a
mess. So, the design is to have the Tuple constructed from a Triple
for legacy and simplicity reasons, but keeping an accurate and
unambiguous description for the more complex targets, while allowing
*other* methods of creating a Tuple for those of us who need it.

So, by default, or if the driver has a "-target foo", it uses the
triple to create the tuple, and no change in behaviour is observed.
OTOH, if the driver has a "-config arm-foo.yaml", it creates the Tuple
from that config file, while still keeping the same unique values
being passed down the target description classes to the back-end, and
*no change in behaviour is observed*.

Hope that helps,


More information about the llvm-dev mailing list