I would like to do constant pools over an entire module instead of just on a per function basis as constant islands does it now. It seems there are two options for this: 1) collect the machine functions with their machine instructions for the whole module, edit them as needed and then call asmprinter for them one at a time. 2) collect all the instruction streams and store them in lists, one per section and put them all out at the end. There are possibly other kinds of module level optimizations that could benefit from this. Some of this might be better done by moving this functionality into target independent code but I think I could do it all without such changes. Any thoughts? Reed
On Mon, Oct 14, 2013 at 6:56 PM, reed kotler <rkotler at mips.com> wrote:> I would like to do constant pools over an entire module instead of just on a > per function basis as constant islands does it now. > > It seems there are two options for this: > > 1) collect the machine functions with their machine instructions for the > whole module, edit them as needed and then > call asmprinter for them one at a time. > > 2) collect all the instruction streams and store them in lists, one per > section and put them all out at the end. > > There are possibly other kinds of module level optimizations that could > benefit from this. > > Some of this might be better done by moving this functionality into target > independent code but I think I could do it all > without such changes. > > Any thoughts? >Two questions: a) what do you think you'll gain over per-function, b) how are you going to handle constants out of range on a module level? -eric
On 10/15/2013 11:05 AM, Eric Christopher wrote:> On Mon, Oct 14, 2013 at 6:56 PM, reed kotler <rkotler at mips.com> wrote: >> I would like to do constant pools over an entire module instead of just on a >> per function basis as constant islands does it now. >> >> It seems there are two options for this: >> >> 1) collect the machine functions with their machine instructions for the >> whole module, edit them as needed and then >> call asmprinter for them one at a time. >> >> 2) collect all the instruction streams and store them in lists, one per >> section and put them all out at the end. >> >> There are possibly other kinds of module level optimizations that could >> benefit from this. >> >> Some of this might be better done by moving this functionality into target >> independent code but I think I could do it all >> without such changes. >> >> Any thoughts? >> > Two questions: > > a) what do you think you'll gain over per-function, > b) how are you going to handle constants out of range on a module level? > > -ericYou make some good points. We have actually been further discussing this inside of Mips/Imagination. One of the guys here has done a module level constant island for another architecture. We've discussed some further improvements to his scheme and have come up with something that can work and later be extended, using the current model for constant islands that llvm uses for ARM. I will create some module level statistics on missed possibilities so that we can evaluate how much better things could have been if we had module level optimizations. One big win is that often you need to load the 32 bit address of something and these addresses can be placed in a constant island, i.e. printf, sin, cos, etc.. So it's possible to have a lot of references to such things. Recreating them inline on a true risc machine can be expensive. How much we save? I have no statistics on this for Mips since we have never had a constant island compiler (gcc does something simple with one pool at the end of the function). If we decide that there is something there, then the following steps would be something like: 1) When a function is compiled, remember where the constant islands for it where. New functions can reference those places. 2) Delay putting out the constant island that is at the end of the function. When the next function appears, see if it is small enough to where this earlier constant island could have been put at the end of this new function. This make things work when you have lots of small functions and you keep moving the pool further down in the stream. 3) It's also possible to create a module pass to collect module level statistics that tells you whether something in you constant pool will occur later. You can decide if it will be beneficial to move a constant from one pool to another. Well...many ideas. The point is that we have a lot of room that we can grow into in order to do better pooling, while starting with the basic scheme of a per function. So there is a lot of room that we can improve things, starting with the basic model that already exists in LLVM so that is the plan for how I intend to proceed. Reed
On 14 October 2013 21:56, reed kotler <rkotler at mips.com> wrote:> I would like to do constant pools over an entire module instead of just on a > per function basis as constant islands does it now. > > It seems there are two options for this: > > 1) collect the machine functions with their machine instructions for the > whole module, edit them as needed and then > call asmprinter for them one at a time. > > 2) collect all the instruction streams and store them in lists, one per > section and put them all out at the end. > > There are possibly other kinds of module level optimizations that could > benefit from this. > > Some of this might be better done by moving this functionality into target > independent code but I think I could do it all > without such changes. > > Any thoughts?My experience is here consists of only once debugging an issue on the ARM constant island pass, so take my opinion with a grain of salt When looking at the pass, it is easy to notice how much it looks like an assembler doing relaxations. It needs to know exact offsets, adding data to an island changes offsets, etc. It is also easy to notice how hard it is to test a pass like that that is nested deep inside codegen. My thought at the time was that it would be nice to implement the pass in the assembler itself by having codegen use pseudo instructions. Something like .const_island_set_reg r4, 0x12345678 The assembler would then be responsible for creating the islands and producing a load (or using something like movw + movt if it was better in that case. The advantages would be * The assembler already naturally handles exact addresses. * It would be much easier to test. * It would work across functions Then again, it is entirely possible I missed something that mandates this pass being in codegen. Cheers, Rafael
On 10/15/2013 01:30 PM, Rafael Espíndola wrote:> On 14 October 2013 21:56, reed kotler <rkotler at mips.com> wrote: >> I would like to do constant pools over an entire module instead of just on a >> per function basis as constant islands does it now. >> >> It seems there are two options for this: >> >> 1) collect the machine functions with their machine instructions for the >> whole module, edit them as needed and then >> call asmprinter for them one at a time. >> >> 2) collect all the instruction streams and store them in lists, one per >> section and put them all out at the end. >> >> There are possibly other kinds of module level optimizations that could >> benefit from this. >> >> Some of this might be better done by moving this functionality into target >> independent code but I think I could do it all >> without such changes. >> >> Any thoughts? > My experience is here consists of only once debugging an issue on the > ARM constant island pass, so take my opinion with a grain of salt > > When looking at the pass, it is easy to notice how much it looks like > an assembler doing relaxations. It needs to know exact offsets, adding > data to an island changes offsets, etc. It is also easy to notice how > hard it is to test a pass like that that is nested deep inside > codegen. > > My thought at the time was that it would be nice to implement the pass > in the assembler itself by having codegen use pseudo instructions. > Something like > > .const_island_set_reg r4, 0x12345678 > > The assembler would then be responsible for creating the islands and > producing a load (or using something like movw + movt if it was better > in that case. > > The advantages would be > * The assembler already naturally handles exact addresses. > * It would be much easier to test. > * It would work across functions > > Then again, it is entirely possible I missed something that mandates > this pass being in codegen. > > Cheers, > RafaelI agree with you 100%. I think it should be an assembler function too, as should long branch optimization. In fact the earliest pdp-11 unix compilers did long branch optimization in the assembler. Moving this to the assembler would require some community buy in. To do this in the assembler and not create any issues, I think you would need to serialize one the asmstreamer interfaces and have a way to edit the instruction stream parts. Then you could play it back through asm printer. Reed
On Oct 15, 2013, at 1:30 PM, Rafael Espíndola <rafael.espindola at gmail.com> wrote:> On 14 October 2013 21:56, reed kotler <rkotler at mips.com> wrote: >> I would like to do constant pools over an entire module instead of just on a >> per function basis as constant islands does it now. >> >> It seems there are two options for this: >> >> 1) collect the machine functions with their machine instructions for the >> whole module, edit them as needed and then >> call asmprinter for them one at a time. >> >> 2) collect all the instruction streams and store them in lists, one per >> section and put them all out at the end. >> >> There are possibly other kinds of module level optimizations that could >> benefit from this. >> >> Some of this might be better done by moving this functionality into target >> independent code but I think I could do it all >> without such changes. >> >> Any thoughts? > > My experience is here consists of only once debugging an issue on the > ARM constant island pass, so take my opinion with a grain of salt > > When looking at the pass, it is easy to notice how much it looks like > an assembler doing relaxations. It needs to know exact offsets, adding > data to an island changes offsets, etc. It is also easy to notice how > hard it is to test a pass like that that is nested deep inside > codegen. > > My thought at the time was that it would be nice to implement the pass > in the assembler itself by having codegen use pseudo instructions. > Something like > > .const_island_set_reg r4, 0x12345678 > > The assembler would then be responsible for creating the islands and > producing a load (or using something like movw + movt if it was better > in that case. > > The advantages would be > * The assembler already naturally handles exact addresses. > * It would be much easier to test. > * It would work across functionsThis would be really great, and a powerful way to make it so that each RISC target didn't have to have their own implementation of the same thing. Pulling this off well would require teaching the assembler about branches, including how to shorten them (like x86 does) which can be more complex for RISC targets. However, I think this would be really great infrastructure to have at the MC level in any case. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131017/e01bee93/attachment.html>