[llvm-dev] [GlobalISel] A Proposal for global instruction selection
David Chisnall via llvm-dev
llvm-dev at lists.llvm.org
Fri Nov 20 01:39:13 PST 2015
On 20 Nov 2015, at 01:43, Quentin Colombet via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>
>>> By more flexible we mean that targets should be able to inject target specific passes between the generic passes or replace those passes by their own.
>>
>> It'll be interesting to see how this is going to be developed and how to keep the target independentness of the code generator with this new scheme. I.e. this is basically turning (in my mind) into "every backend for themselves" with very little target independent unification. Outside of special purpose ports I don't see a lot of need for this, but we'll see. I think it's going to take some discipline to avoid the "every backend is a large C++ project that defines everything it needs custom”.
>
> At this point, the idea is to have the standard passes shared (i.e., IRTranslator, Legalizer, RegBankSelect, and Select) and let the targets create their own pass if they want to do more stuff. Then, if we see room for generalization, we can refactor :).
To give a concrete example of this:
Currently, SelectionDAG has completely generic infrastructure for expanding unaligned loads and stores into sequences of aligned loads and masks. Unfortunately, the interface is entirely push from the generic side, not pull from the target side. We hit a problem where we needed different handling of unaligned loads and stores based on the address space of the base pointer. We ended up having to duplicate a load of the SelectionDAG logic in the back end. Eventually, extending our CPU to support unaligned loads and stores proved less effort than trying to get SelectionDAG to place nicely with our constraints.
With the new design, I’d imagine that there’d be a generic ExpandUnalignedLoad function in the supporting library that any target could simply use for the places where it makes sense. On MIPS, for example, the load-word-left and load-word-right instructions need some special handling and allow you to generate quite efficient code, but other forms of unaligned load and store may want to be handled generically. Being able to have the targets choose at a fine granularity by explicitly calling into the generic code for the functionality that they need is likely to be a lot better than having to provide a load of predicates up-front and hoping that the ones that the generic infrastructure asks for match the ones that you want (currently, there’s no way to tell SelectionDAG that you want different handling for things with pointers in different address spaces and no way to specify Custom for all address spaces and then call back into the generic behaviour if you want to use it for a subset).
There’s also the issue that, because SelectionDAG is a push model, it’s very easy to get into a situation (especially with the set_cc / br_cc families) where you do a transform, SelectionDAG does the inverse transform, then calls back into the back end, which redoes the transform, which SelectionDAG undoes, and so on. I think everyone who has worked on any back end has encountered this at least once (often identified with ‘why is this one test in the test suite running forever?’).
A few other things that come to mind as being easier to generalise in this model:
- Constant island generation (the ARM constant islands pass has been copied around the place a few times)
- The expansions for ll/sc atomics (we currently do this in LLVM IR, which is the wrong place, because the right place is MIR, which doesn’t exist yet)
I’m sure that there are others.
David
More information about the llvm-dev
mailing list