diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h index 0d79b1d41bd..91fb0a9d7e7 100644 --- a/include/llvm/CodeGen/CalcSpillWeights.h +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -30,8 +30,10 @@ namespace llvm { /// @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) { + 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 @@ -44,7 +46,7 @@ namespace llvm { /// spill weight and allocation hint. class VirtRegAuxInfo { public: - typedef float (*NormalizingFn)(float, unsigned); + typedef float (*NormalizingFn)(float, unsigned, unsigned); private: MachineFunction &MF; diff --git a/lib/CodeGen/CalcSpillWeights.cpp b/lib/CodeGen/CalcSpillWeights.cpp index bf3882a6e34..0b0c176f686 100644 --- a/lib/CodeGen/CalcSpillWeights.cpp +++ b/lib/CodeGen/CalcSpillWeights.cpp @@ -100,6 +100,7 @@ VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &li) { MachineLoop *loop = nullptr; bool isExiting = false; float totalWeight = 0; + unsigned numInstr = 0; // Number of instructions using li SmallPtrSet visited; // Find the best physreg hint and the best virtreg hint. @@ -116,6 +117,7 @@ VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &li) { I = mri.reg_instr_begin(li.reg), E = mri.reg_instr_end(); I != E; ) { MachineInstr *mi = &*(I++); + numInstr++; if (mi->isIdentityCopy() || mi->isImplicitDef() || mi->isDebugValue()) continue; if (!visited.insert(mi)) @@ -189,5 +191,5 @@ VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &li) { if (isRematerializable(li, LIS, *MF.getSubtarget().getInstrInfo())) totalWeight *= 0.5F; - li.weight = normalize(totalWeight, li.getSize()); + li.weight = normalize(totalWeight, li.getSize(), numInstr); } diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 1d081c748d4..dfeb9c04501 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -1789,9 +1789,11 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order, // instructions. // // Try to guess the size of the new interval. - const float EstWeight = normalizeSpillWeight(blockFreq * (NewGaps + 1), - Uses[SplitBefore].distance(Uses[SplitAfter]) + - (LiveBefore + LiveAfter)*SlotIndex::InstrDist); + const float EstWeight = normalizeSpillWeight( + blockFreq * (NewGaps + 1), + Uses[SplitBefore].distance(Uses[SplitAfter]) + + (LiveBefore + LiveAfter) * SlotIndex::InstrDist, + 1); // Would this split be possible to allocate? // Never allocate all gaps, we wouldn't be making progress. DEBUG(dbgs() << " w=" << EstWeight); diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp index 768e650a952..fa45dd23654 100644 --- a/lib/CodeGen/RegAllocPBQP.cpp +++ b/lib/CodeGen/RegAllocPBQP.cpp @@ -150,11 +150,17 @@ public: void apply(PBQPRAGraph &G) override { LiveIntervals &LIS = G.getMetadata().LIS; + // A minimum spill costs, so that register constraints can can be set + // without normalization in the [0.0:MinSpillCost( interval. + const PBQP::PBQPNum MinSpillCost = 10.0; + for (auto NId : G.nodeIds()) { PBQP::PBQPNum SpillCost = LIS.getInterval(G.getNodeMetadata(NId).getVReg()).weight; if (SpillCost == 0.0) SpillCost = std::numeric_limits::min(); + else + SpillCost += MinSpillCost; PBQPRAGraph::RawVector NodeCosts(G.getNodeCosts(NId)); NodeCosts[PBQP::RegAlloc::getSpillOptionIdx()] = SpillCost; G.setNodeCosts(NId, std::move(NodeCosts)); @@ -350,11 +356,8 @@ public: unsigned DstReg = CP.getDstReg(); unsigned SrcReg = CP.getSrcReg(); - const float CopyFactor = 0.5; // Cost of copy relative to load. Current - // value plucked randomly out of the air. - - PBQP::PBQPNum CBenefit = - CopyFactor * LiveIntervals::getSpillWeight(false, true, &MBFI, &MI); + const float Scale = 1.0f / MBFI.getEntryFreq(); + PBQP::PBQPNum CBenefit = MBFI.getBlockFreq(&MBB).getFrequency() * Scale; if (CP.isPhys()) { if (!MF.getRegInfo().isAllocatable(DstReg)) @@ -607,12 +610,20 @@ void RegAllocPBQP::finalizeAlloc(MachineFunction &MF, } } +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(); MachineBlockFrequencyInfo &MBFI = getAnalysis(); - calculateSpillWeightsAndHints(LIS, MF, getAnalysis(), MBFI); + calculateSpillWeightsAndHints(LIS, MF, getAnalysis(), MBFI, + normalizePBQPSpillWeight); VirtRegMap &VRM = getAnalysis();