[llvm] r221292 - [PBQP] Tweak spill costs and coalescing benefits
David Blaikie
dblaikie at gmail.com
Tue Nov 4 13:49:28 PST 2014
On Tue, Nov 4, 2014 at 1:47 PM, Lang Hames <lhames at gmail.com> wrote:
> Hi Dave,
>
> Echoing Arnaud's thoughts here - I've found that regression tests for
> heuristic register allocation optimizations such as this one aren't worth
> it: the signal to noise ratio on them is extremely low.
>
Given the lack of perf buildbots watching this, it seems pretty easy to
accidentally regress a bunch of this, which would be unfortunate.
Meh.
- David
>
> Cheers,
> Lang.
>
>
> On Tue, Nov 4, 2014 at 1:34 PM, Arnaud A. de Grandmaison <
> arnaud.degrandmaison at arm.com> wrote:
>
>> Hi David,
>>
>>
>>
>> The reason why there is no test did not make it into the commit log, but
>> was in the pre-commit review request.
>>
>>
>>
>> The reason is it is too complicated to come-up with a meaningful test
>> because the tweaking address some global relationship amongst registers.
>>
>> The tweaking done here was based on experiments with various benchmarks
>> (eembc, spec2000, spec20006, …) and provided a several percent improvement
>> (geomean) across those benchmarks.
>>
>>
>>
>> Cheers,
>>
>> Arnaud
>>
>>
>>
>> *From:* David Blaikie [mailto:dblaikie at gmail.com]
>> *Sent:* 04 November 2014 22:18
>> *To:* Arnaud De Grandmaison
>> *Cc:* llvm-commits at cs.uiuc.edu
>> *Subject:* Re: [llvm] r221292 - [PBQP] Tweak spill costs and coalescing
>> benefits
>>
>>
>>
>>
>>
>>
>>
>> On Tue, Nov 4, 2014 at 12:51 PM, Arnaud A. de Grandmaison <
>> arnaud.degrandmaison at arm.com> wrote:
>>
>> Author: aadg
>> Date: Tue Nov 4 14:51:24 2014
>> New Revision: 221292
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=221292&view=rev
>> Log:
>> [PBQP] Tweak spill costs and coalescing benefits
>>
>>
>>
>> Is this intended to change the observable behavior of the allocator
>> (coalescing more or less often, etc?) - a test would be nice for that.
>>
>> If it isn't, it's helpful (well, to me, at least) to describe why
>> something isn't tested in the commit message (just refactoring to lay the
>> foundation for a future change, etc).
>>
>>
>>
>>
>> This patch improves how the different costs (register, interference, spill
>> and coalescing) relates together. The assumption is now that:
>> - coalescing (or any other "side effect" of reg alloc) is negative, and
>> instead of being derived from a spill cost, they use the block
>> frequency info.
>> - spill costs are in the [MinSpillCost:+inf( range
>> - register or interference costs are in [0.0:MinSpillCost( or +inf
>>
>> The current MinSpillCost is set to 10.0, which is a random value high
>> enough that the current constraint builders do not need to worry about
>> when settings costs. It would however be worth adding a normalization
>> step for register and interference costs as the last step in the
>> constraint builder chain to ensure they are not greater than SpillMinCost
>> (unless this has some sense for some architectures). This would work well
>> with the current builder pipeline, where all costs are tweaked relatively
>> to each others, but could grow above MinSpillCost if the pipeline is
>> deep enough.
>>
>> The current heuristic is tuned to depend rather on the number of uses of
>> a live interval rather than a density of uses, as used by the greedy
>> allocator. This heuristic provides a few percent improvement on a number
>> of benchmarks (eembc, spec, ...) and will definitely need to change once
>> spill placement is implemented: the current spill placement is really
>> ineficient, so making the cost proportionnal to the number of use is a
>> clear win.
>>
>> Modified:
>> llvm/trunk/include/llvm/CodeGen/CalcSpillWeights.h
>> llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp
>> llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp
>> llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp
>>
>> Modified: llvm/trunk/include/llvm/CodeGen/CalcSpillWeights.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CalcSpillWeights.h?rev=221292&r1=221291&r2=221292&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/CodeGen/CalcSpillWeights.h (original)
>> +++ llvm/trunk/include/llvm/CodeGen/CalcSpillWeights.h Tue Nov 4
>> 14:51:24 2014
>> @@ -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;
>>
>> Modified: llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp?rev=221292&r1=221291&r2=221292&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/CalcSpillWeights.cpp Tue Nov 4 14:51:24 2014
>> @@ -100,6 +100,7 @@ VirtRegAuxInfo::calculateSpillWeightAndH
>> MachineLoop *loop = nullptr;
>> bool isExiting = false;
>> float totalWeight = 0;
>> + unsigned numInstr = 0; // Number of instructions using li
>> SmallPtrSet<MachineInstr*, 8> visited;
>>
>> // Find the best physreg hint and the best virtreg hint.
>> @@ -116,6 +117,7 @@ VirtRegAuxInfo::calculateSpillWeightAndH
>> 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::calculateSpillWeightAndH
>> if (isRematerializable(li, LIS, *MF.getSubtarget().getInstrInfo()))
>> totalWeight *= 0.5F;
>>
>> - li.weight = normalize(totalWeight, li.getSize());
>> + li.weight = normalize(totalWeight, li.getSize(), numInstr);
>> }
>>
>> Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=221292&r1=221291&r2=221292&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Tue Nov 4 14:51:24 2014
>> @@ -1789,9 +1789,11 @@ unsigned RAGreedy::tryLocalSplit(LiveInt
>> // 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);
>>
>> Modified: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp?rev=221292&r1=221291&r2=221292&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Tue Nov 4 14:51:24 2014
>> @@ -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<PBQP::PBQPNum>::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(Machine
>> }
>> }
>>
>> +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 =
>> getAnalysis<MachineBlockFrequencyInfo>();
>>
>> - calculateSpillWeightsAndHints(LIS, MF, getAnalysis<MachineLoopInfo>(),
>> MBFI);
>> + calculateSpillWeightsAndHints(LIS, MF, getAnalysis<MachineLoopInfo>(),
>> MBFI,
>> + normalizePBQPSpillWeight);
>>
>> VirtRegMap &VRM = getAnalysis<VirtRegMap>();
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141104/327b736e/attachment.html>
More information about the llvm-commits
mailing list