[LLVMdev] The Trouble with Triples
Daniel.Sanders at imgtec.com
Sat Aug 1 05:55:10 PDT 2015
> On 31 July 2015 at 21:10, Daniel Sanders <Daniel.Sanders at imgtec.com> wrote:
> > This turns out to be very difficult to fix since the majority of the Mips
> > target is using Triple::mips and Triple::mips64 to make assumptions about
> > the architecture (e.g. are registers 64 bit?) or the ABI (Triple::mips
> > implies O32, Triple::mips64 implies N64 or, in cases where this has been
> > partially fixed, N32/N64). Unfortunately, in many of these cases the triple
> > is the best information I have. At this point, I've hit this wall and seen
> > misuse of triples in code reviews enough times that my desire to find a
> > general solution to this is very high. I also know of some impending work
> > that it likely to make matters worse. I want to be able to, for example, ask
> > the TargetTuple whether I am targeting a 64-bit ISA and whether I'm supposed
> > to treat it as a 32-bit ISA (e.g. O32 on MIPS64R2) in many areas of LLVM
> > (including those where MipsSubtarget and similar are not available) and be
> > able to rely on the answer. At the moment, we incorrectly conflate 'is it a
> > 64-bit ISA?' with 'is the CPU 64-bit?' as well as 'is the ABI 64-bit?' with
> > 'is the ISA 64-bit?'
> I feel your pain. We have our own variants of VFP, PCS, extensions,
> ILPXX, IEEE support, CPUs with the same revision belonging to two
> different architectures and vice-versa. Not to mention that we have
> two back-ends, and one architecture (ARMv8 is split between the two).
> And all the brand names that people mad up during the years
> (StrongARM, XScale, Krait, Tegra) which map to custom features, etc.
"CPUs with the same revision belonging to two different architectures" is a significant part of the issue for our 64-bit CPU's/ISA's. As llvm::Triple is currently used, they belong to Triple::mips or Triple::mips64 depending on the ABI. If llvm::Triple is just a GNU Triple and not a target description, then we're so far down the wrong track that the most practical solution is to redefine the track so that llvm::Triple (or preferably an object created from it such as TargetTuple) is the target description. If llvm::Triple is a target description (which it is, as evidenced by the -m32/-m64 options and lookupTarget() implementations among other things) then we don't have a clear concept of a GNU Triple or a target description and need to split llvm::Triple into the two concepts.
As an aside, I think it was a mistake to define a Triple::mips64 since it allowed us to ignore these issues for a long time and dig ourselves deeper into the hole. To be fair, it probably made sense at the time.
The bit that's the most painful for Mips is the ABI related information. We have three official ABI's (O32, N32, and N64) and a further three unofficial ABIs (EABI32, EABI64, and O64, which aren't implemented in LLVM). There may be a seventh ABI called NUBI but I don't think anything ever used it. Some of these ABI's break down into further subsets. O32 for example, is really O32 FP32, O32 FP64, O32 FPXX, and O32 FP64A as a result of a historical implementation bug (O32 FP32 and O32 FP64 was supposed to be a single ABI) which the latter two are providing migration paths to dig us out of the fallout of that bug (e.g. FPXX almost the intended O32 and is compatible with either FP32 and FP64 but not both at the same time, one the world is FPXX we can relax a few restrictions and get the intended O32 that was originally designed). Each and every ABI then breaks down again into IEEE754-1985 and IEEE754-2008 variants which is the result of making a valid choice for the signalling NaN bit that would later become the wrong choice in the 2008 standard. So that's a total of 12 official ABI's and potentially up to 18 with complex interlinking rules (and it's actually a bit worse than I've described). We currently pass this ABI information via target features (via a -target-abi option for some tools) but that's not available everywhere we need it and it's not really appropriate for target features.
> But the way we're solving this, via out TargetParser, is to create
> tables of default/allowed values, so that users will often get what
> they want, even if they don't specify most of it. I imagine that MIPS
> would also benefit from a TargetParser. And, if we keep the complexity
> in the parser and the driver, we won't need to store much in the IR,
> IFF they have the same meaning everywhere. So, whatever we spit out in
> the IR has to be necessary and sufficient to get the meaning "just
TargetParser is certainly part of the overall solution and we'll be able to use it to resolve the ABI/CPU/Arch option combinations. However it doesn't solve the whole problem by itself. In particular it doesn't improve the delivery of the target information throughout the LLVM library which is currently insufficient. As things stand, some key data is only delivered to the code generator and/or the assembler and Mips needs access to it from other places.
It also doesn't solve the problem of distributors defining the meaning of their triples but it potentially could do that.
More information about the llvm-dev