NumLoads/NumStores for linearscan?

Hi,

Is there a way for me to collect statistics about the number of loads/stores added by the “linearscan” register allocator (just like can be done with the “local” allocator)? I still haven’t grokked very well the interaction between RALinScan and Spiller… Should I add those two statistics to the spiller’s class?

Thanks,
– Silvio Ricardo Cordeiro

RALinearScan asks the Spiller to spill a virtual register. The StandardSpiller passes the request to LiveIntervals::addIntervalsForSpills. Here, the spill and restore points are added to the VirtRegMap. No spill code has been inserted yet. After register allocation completes, VirtRegRewriter inserts the store and load instructions specified in VirtRegMap.

The counters you are looking for are in VirtRegRewriter.cpp.

We are working on simplifying this for obvious reasons. If you specify -spiller=inline, the InlineSpiller will insert loads and stores immediately. There are currently no statistics counters in InlineSpiller.cpp. Feel free to add some.

/jakob

Is there a way for me to collect statistics about the number of loads/stores added by the “linearscan” register allocator (just like can be done with the “local” allocator)? I still haven’t grokked very well the interaction between RALinScan and Spiller… Should I add those two statistics to the spiller’s class?

RALinearScan asks the Spiller to spill a virtual register. The StandardSpiller passes the request to LiveIntervals::addIntervalsForSpills. Here, the spill and restore points are added to the VirtRegMap. No spill code has been inserted yet. After register allocation completes, VirtRegRewriter inserts the store and load instructions specified in VirtRegMap.

The counters you are looking for are in VirtRegRewriter.cpp.

I compiled “sort.c” from coreutils8.5 using both local and linearscan allocators (I’m using LLVM 2.7). For local, I get a Load/Store count of 314/367. But when I use linearscan, the counters at VirtRegRewriter.cpp end up being 0/0. I’ve also tried to compile a couple other source files, and VirtRegRewriter.cpp always has NumLoads=0 and NumStores=0 in the end.

I can’t believe linearscan is that good! I’ve tried to add other variables to the source code, but it seems to be spiling them without updating NumLoads/NumStores…

Is there a source file that’s commonly used to test this kind of thing?

We are working on simplifying this for obvious reasons. If you specify -spiller=inline, the InlineSpiller will insert loads and stores immediately. There are currently no statistics counters in InlineSpiller.cpp. Feel free to add some.

Hmmm yeah, but that’s not available for LLVM 2.7, so no luck (although I may try to “adapt” it for 2.7 if I need to).

hmm, having information if an operation is (a, or part of a) spill generated by the register allocation would be benefical in some cases; Those memory operations cannon alias with any other memory operations in the code, so it would help Alias Analysis.

(though I'm not sure if anyone else than us at the TCE project have any use for alias analysis after regalloc)

We actually have our own hacked version of the linear scan allocator which adds this information to the instructions it creates, but our implementation is quite ugly/kludgy.

So,

1) does anybody else find this benefcial for their use?
2) what would be the cleanest, least kludge way to store this information? (currently we use a hack based on DebugLoc)

Heikki Kultala <hkultala@cs.tut.fi> writes:

> Is there a way for me to collect statistics about the number of
> loads/stores added by the "linearscan" register allocator (just
> like can be done with the "local" allocator)? I still haven't
> grokked very well the interaction between RALinScan and
> Spiller... Should I add those two statistics to the spiller's
> class?

hmm, having information if an operation is (a, or part of a) spill
generated by the register allocation would be benefical in some cases;
Those memory operations cannon alias with any other memory operations
in the code, so it would help Alias Analysis.

This is already done. Look in CodeGen/MachineFrameInfo.h:

  struct StackObject {
    [...]

    // isSpillSlot - If true the stack object is used as spill slot. It
    // cannot alias any other memory objects.
    bool isSpillSlot;

Right now this gets used to print out some comments to label spill
instructions, among other things.

                            -Dave