[NFC][regalloc] Model weight normalization as a virtual

Continuing from D88499, we can now model the normalization function as a
virtual member of VirtRegAuxInfo. Note that the default
(normalizeSpillWeight) is also used stand-alone in RAGreedy.

Differential Revision: https://reviews.llvm.org/D88713
This commit is contained in:
Mircea Trofin 2020-10-01 16:53:23 -07:00
parent 85d5064000
commit 82ebbcfb05
2 changed files with 36 additions and 27 deletions

View File

@ -44,27 +44,23 @@ class VirtRegMap;
/// Calculate auxiliary information for a virtual register such as its
/// spill weight and allocation hint.
class VirtRegAuxInfo {
public:
using NormalizingFn = float (*)(float, unsigned, unsigned);
private:
MachineFunction &MF;
LiveIntervals &LIS;
VirtRegMap *VRM;
VirtRegMap *const 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) {}
VirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap *VRM,
const MachineLoopInfo &Loops,
const MachineBlockFrequencyInfo &MBFI)
: MF(MF), LIS(LIS), VRM(VRM), Loops(Loops), MBFI(MBFI) {}
virtual ~VirtRegAuxInfo() = default;
/// (re)compute li's spill weight and allocation hint.
void calculateSpillWeightAndHint(LiveInterval &li);
void calculateSpillWeightAndHint(LiveInterval &LI);
/// Compute future expected spill weight of a split artifact of li
/// that will span between start and end slot indexes.
@ -75,8 +71,13 @@ class VirtRegMap;
/// after end will not affect the weight.
/// \return The expected spill weight of the split artifact. Returns
/// negative weight for unspillable li.
float futureWeight(LiveInterval &li, SlotIndex start, SlotIndex end);
float futureWeight(LiveInterval &LI, SlotIndex Start, SlotIndex End);
/// Compute spill weights and allocation hints for all virtual register
/// live intervals.
void calculateSpillWeightsAndHints();
protected:
/// Helper function for weight calculations.
/// (Re)compute li's spill weight and allocation hint, or, for non null
/// start and end - compute future expected spill weight of a split
@ -89,12 +90,14 @@ class VirtRegMap;
/// after end will not affect the weight. Relevant for
/// weight calculation of future split artifact.
/// \return The spill weight. Returns negative weight for unspillable li.
float weightCalcHelper(LiveInterval &li, SlotIndex *start = nullptr,
SlotIndex *end = nullptr);
float weightCalcHelper(LiveInterval &LI, SlotIndex *Start = nullptr,
SlotIndex *End = nullptr);
/// Compute spill weights and allocation hints for all virtual register
/// live intervals.
void calculateSpillWeightsAndHints();
/// Weight normalization function.
virtual float normalize(float UseDefFreq, unsigned Size,
unsigned NumInstr) {
return normalizeSpillWeight(UseDefFreq, Size, NumInstr);
}
};
} // end namespace llvm

View File

@ -518,6 +518,20 @@ private:
}
};
/// PBQP-specific implementation of weight normalization.
class PBQPVirtRegAuxInfo final : public VirtRegAuxInfo {
float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr) override {
// All intervals have a spill weight that is mostly proportional to the
// number of uses, with uses in loops having a bigger weight.
return NumInstr * VirtRegAuxInfo::normalize(UseDefFreq, Size, 1);
}
public:
PBQPVirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap *VRM,
const MachineLoopInfo &Loops,
const MachineBlockFrequencyInfo &MBFI)
: VirtRegAuxInfo(MF, LIS, VRM, Loops, MBFI) {}
};
} // end anonymous namespace
// Out-of-line destructor/anchor for PBQPRAConstraint.
@ -778,13 +792,6 @@ void RegAllocPBQP::postOptimization(Spiller &VRegSpiller, LiveIntervals &LIS) {
DeadRemats.clear();
}
static inline float normalizePBQPSpillWeight(float UseDefFreq, unsigned Size,
unsigned NumInstr) {
// All intervals have a spill weight that is mostly proportional to the number
// of uses, with uses in loops having a bigger weight.
return NumInstr * normalizeSpillWeight(UseDefFreq, Size, 1);
}
bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
LiveIntervals &LIS = getAnalysis<LiveIntervals>();
MachineBlockFrequencyInfo &MBFI =
@ -792,8 +799,7 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
VirtRegMap &VRM = getAnalysis<VirtRegMap>();
VirtRegAuxInfo VRAI(MF, LIS, &VRM, getAnalysis<MachineLoopInfo>(), MBFI,
normalizePBQPSpillWeight);
PBQPVirtRegAuxInfo VRAI(MF, LIS, &VRM, getAnalysis<MachineLoopInfo>(), MBFI);
VRAI.calculateSpillWeightsAndHints();
std::unique_ptr<Spiller> VRegSpiller(createInlineSpiller(*this, MF, VRM));