mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
ac5d349432
PR24139 contains an analysis of poor register allocation. One of the findings was that when calculating the spill weight, a rematerializable interval once split is no longer rematerializable. This is because the isRematerializable check in CalcSpillWeights.cpp does not follow the copies introduced by live range splitting (after splitting, the live interval register definition is a copy which is not rematerializable). Reviewers: qcolombet Differential Revision: http://reviews.llvm.org/D11686 llvm-svn: 244439
83 lines
3.1 KiB
C++
83 lines
3.1 KiB
C++
//===---------------- lib/CodeGen/CalcSpillWeights.h ------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
#ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H
|
|
#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
|
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/CodeGen/SlotIndexes.h"
|
|
|
|
namespace llvm {
|
|
|
|
class LiveInterval;
|
|
class LiveIntervals;
|
|
class MachineBlockFrequencyInfo;
|
|
class MachineLoopInfo;
|
|
class VirtRegMap;
|
|
|
|
/// \brief Normalize the spill weight of a live interval
|
|
///
|
|
/// The spill weight of a live interval is computed as:
|
|
///
|
|
/// (sum(use freq) + sum(def freq)) / (K + size)
|
|
///
|
|
/// @param UseDefFreq Expected number of executed use and def instructions
|
|
/// per function call. Derived from block frequencies.
|
|
/// @param Size Size of live interval as returnexd by getSize()
|
|
/// @param NumInstr Number of instructions using this live interval
|
|
///
|
|
static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size,
|
|
unsigned NumInstr) {
|
|
// The constant 25 instructions is added to avoid depending too much on
|
|
// accidental SlotIndex gaps for small intervals. The effect is that small
|
|
// intervals have a spill weight that is mostly proportional to the number
|
|
// of uses, while large intervals get a spill weight that is closer to a use
|
|
// density.
|
|
return UseDefFreq / (Size + 25*SlotIndex::InstrDist);
|
|
}
|
|
|
|
/// \brief Calculate auxiliary information for a virtual register such as its
|
|
/// spill weight and allocation hint.
|
|
class VirtRegAuxInfo {
|
|
public:
|
|
typedef float (*NormalizingFn)(float, unsigned, unsigned);
|
|
|
|
private:
|
|
MachineFunction &MF;
|
|
LiveIntervals &LIS;
|
|
VirtRegMap *VRM;
|
|
const MachineLoopInfo &Loops;
|
|
const MachineBlockFrequencyInfo &MBFI;
|
|
DenseMap<unsigned, float> Hint;
|
|
NormalizingFn normalize;
|
|
|
|
public:
|
|
VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis,
|
|
VirtRegMap *vrm, const MachineLoopInfo &loops,
|
|
const MachineBlockFrequencyInfo &mbfi,
|
|
NormalizingFn norm = normalizeSpillWeight)
|
|
: MF(mf), LIS(lis), VRM(vrm), Loops(loops), MBFI(mbfi), normalize(norm) {}
|
|
|
|
/// \brief (re)compute li's spill weight and allocation hint.
|
|
void calculateSpillWeightAndHint(LiveInterval &li);
|
|
};
|
|
|
|
/// \brief Compute spill weights and allocation hints for all virtual register
|
|
/// live intervals.
|
|
void calculateSpillWeightsAndHints(LiveIntervals &LIS, MachineFunction &MF,
|
|
VirtRegMap *VRM,
|
|
const MachineLoopInfo &MLI,
|
|
const MachineBlockFrequencyInfo &MBFI,
|
|
VirtRegAuxInfo::NormalizingFn norm =
|
|
normalizeSpillWeight);
|
|
}
|
|
|
|
#endif // LLVM_CODEGEN_CALCSPILLWEIGHTS_H
|