[llvm] r184105 - Switch spill weights from a basic loop depth estimation to BlockFrequencyInfo.

Jakob Stoklund Olesen stoklund at 2pi.dk
Mon Jun 17 14:47:13 PDT 2013


On Jun 17, 2013, at 2:06 PM, Benjamin Kramer <benny.kra at gmail.com> wrote:

> 
> On 17.06.2013, at 22:55, Jakob Stoklund Olesen <stoklund at 2pi.dk> wrote:
> 
>> 
>> On Jun 17, 2013, at 12:00 PM, Benjamin Kramer <benny.kra at googlemail.com> wrote:
>> 
>>> Author: d0k
>>> Date: Mon Jun 17 14:00:36 2013
>>> New Revision: 184105
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=184105&view=rev
>>> Log:
>>> Switch spill weights from a basic loop depth estimation to BlockFrequencyInfo.
>> 
>> Thanks, Ben!
>> 
>> Are you also going to kill off floating point completely in the register allocator?
> 
> 
> Sure, I can give it a try.

Awesome!

> Can you explain what we should replace the floating point trickery in SpillPlacement with? It uses values that can't be represented properly with BlockFrequencies or BranchProbabilities currently.

struct SpillPlacement::Node {
  /// Scale - Inverse block frequency feeding into[0] or out of[1] the bundle.
  /// Ideally, these two numbers should be identical, but inaccuracies in the
  /// block frequency estimates means that we need to normalize ingoing and
  /// outgoing frequencies separately so they are commensurate.
  float Scale[2];

You should be able to remove this one now. The scaling was supposed to guarantee that all the CFG edges entering a bundle, and all the CFG edges leaving the bundle add up to the same frequency.

That property should be guaranteed by the block frequency analysis, so no rescaling is necessary.

  /// Bias - Normalized contributions from non-transparent blocks.
  /// A bundle connected to a MustSpill block has a huge negative bias,
  /// otherwise it is a number in the range [-2;2].
  float Bias;

This is signed a sum of block frequencies once the normalization is gone. IIRC, my plan was to represent this as two BlockFrequency variables - a negative part and a positive part. That should tame the saturating fixpoint arithmetic in a sensible way.

  /// Value - Output value of this node computed from the Bias and links.
  /// This is always in the range [-1;1]. A positive number means the variable
  /// should go in a register through this bundle.
  float Value;

This is actually an integer from the set {-1, 0, 1}. It is represented as a float for performance reasons.

  typedef SmallVector<std::pair<float, unsigned>, 4> LinkVector;

This is a direct block frequency, see the calls to addLink().


The key function is this one:

  bool update(const Node nodes[]) {
    // Compute the weighted sum of inputs.
    float Sum = Bias;
    for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I)
      Sum += I->first * nodes[I->second].Value;

This is computing a biased weighted sum of ‘links’, each link representing a basic block. Currently, the whole sum is normalized so the sum of links is 2 (actually, the incoming links sum to 1 and the outgoing links sum to 1).

The sum is then compared to 0:

    if (Sum < -Thres)
      Value = -1;
    else if (Sum > Thres)
      Value = 1;
    else
      Value = 0;

You can rescale the whole thing such that both the bias and link weights are expressed in units of block frequencies. Scaling doesn’t change if the sum is positive of negative. The important part is that the incoming and outgoing link weights add up to the same number. The absolute value of the threshold band around 0 is not critical, you should be able to make do with a small integer constant.


This is not completely trivial. I think a good way of getting started is to first remove the scale factor while preserving the floats.

Thanks,
/jakob





More information about the llvm-commits mailing list