diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp | 296 |
1 files changed, 148 insertions, 148 deletions
diff --git a/contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp b/contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp index 16f380c1eb..95f94cea85 100644 --- a/contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp +++ b/contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp @@ -28,59 +28,59 @@ using namespace llvm; #define DEBUG_TYPE "calcspillweights" -void VirtRegAuxInfo::calculateSpillWeightsAndHints() { +void VirtRegAuxInfo::calculateSpillWeightsAndHints() { LLVM_DEBUG(dbgs() << "********** Compute Spill Weights **********\n" << "********** Function: " << MF.getName() << '\n'); MachineRegisterInfo &MRI = MF.getRegInfo(); - for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { - unsigned Reg = Register::index2VirtReg(I); + for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { + unsigned Reg = Register::index2VirtReg(I); if (MRI.reg_nodbg_empty(Reg)) continue; - calculateSpillWeightAndHint(LIS.getInterval(Reg)); + calculateSpillWeightAndHint(LIS.getInterval(Reg)); } } // Return the preferred allocation register for reg, given a COPY instruction. -static Register copyHint(const MachineInstr *MI, unsigned Reg, - const TargetRegisterInfo &TRI, - const MachineRegisterInfo &MRI) { - unsigned Sub, HSub; - Register HReg; - if (MI->getOperand(0).getReg() == Reg) { - Sub = MI->getOperand(0).getSubReg(); - HReg = MI->getOperand(1).getReg(); - HSub = MI->getOperand(1).getSubReg(); +static Register copyHint(const MachineInstr *MI, unsigned Reg, + const TargetRegisterInfo &TRI, + const MachineRegisterInfo &MRI) { + unsigned Sub, HSub; + Register HReg; + if (MI->getOperand(0).getReg() == Reg) { + Sub = MI->getOperand(0).getSubReg(); + HReg = MI->getOperand(1).getReg(); + HSub = MI->getOperand(1).getSubReg(); } else { - Sub = MI->getOperand(1).getSubReg(); - HReg = MI->getOperand(0).getReg(); - HSub = MI->getOperand(0).getSubReg(); + Sub = MI->getOperand(1).getSubReg(); + HReg = MI->getOperand(0).getReg(); + HSub = MI->getOperand(0).getSubReg(); } - if (!HReg) + if (!HReg) return 0; - if (Register::isVirtualRegister(HReg)) - return Sub == HSub ? HReg : Register(); + if (Register::isVirtualRegister(HReg)) + return Sub == HSub ? HReg : Register(); - const TargetRegisterClass *rc = MRI.getRegClass(Reg); - MCRegister CopiedPReg = HSub ? TRI.getSubReg(HReg, HSub) : HReg.asMCReg(); + const TargetRegisterClass *rc = MRI.getRegClass(Reg); + MCRegister CopiedPReg = HSub ? TRI.getSubReg(HReg, HSub) : HReg.asMCReg(); if (rc->contains(CopiedPReg)) return CopiedPReg; // Check if reg:sub matches so that a super register could be hinted. - if (Sub) - return TRI.getMatchingSuperReg(CopiedPReg, Sub, rc); + if (Sub) + return TRI.getMatchingSuperReg(CopiedPReg, Sub, rc); return 0; } // Check if all values in LI are rematerializable -static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, - const VirtRegMap &VRM, +static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, + const VirtRegMap &VRM, const TargetInstrInfo &TII) { - unsigned Reg = LI.reg(); - unsigned Original = VRM.getOriginal(Reg); + unsigned Reg = LI.reg(); + unsigned Original = VRM.getOriginal(Reg); for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end(); I != E; ++I) { const VNInfo *VNI = *I; @@ -95,28 +95,28 @@ static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, // Trace copies introduced by live range splitting. The inline // spiller can rematerialize through these copies, so the spill // weight must reflect this. - while (MI->isFullCopy()) { - // The copy destination must match the interval register. - if (MI->getOperand(0).getReg() != Reg) - return false; - - // Get the source register. - Reg = MI->getOperand(1).getReg(); - - // If the original (pre-splitting) registers match this - // copy came from a split. - if (!Register::isVirtualRegister(Reg) || VRM.getOriginal(Reg) != Original) - return false; - - // Follow the copy live-in value. - const LiveInterval &SrcLI = LIS.getInterval(Reg); - LiveQueryResult SrcQ = SrcLI.Query(VNI->def); - VNI = SrcQ.valueIn(); - assert(VNI && "Copy from non-existing value"); - if (VNI->isPHIDef()) - return false; - MI = LIS.getInstructionFromIndex(VNI->def); - assert(MI && "Dead valno in interval"); + while (MI->isFullCopy()) { + // The copy destination must match the interval register. + if (MI->getOperand(0).getReg() != Reg) + return false; + + // Get the source register. + Reg = MI->getOperand(1).getReg(); + + // If the original (pre-splitting) registers match this + // copy came from a split. + if (!Register::isVirtualRegister(Reg) || VRM.getOriginal(Reg) != Original) + return false; + + // Follow the copy live-in value. + const LiveInterval &SrcLI = LIS.getInterval(Reg); + LiveQueryResult SrcQ = SrcLI.Query(VNI->def); + VNI = SrcQ.valueIn(); + assert(VNI && "Copy from non-existing value"); + if (VNI->isPHIDef()) + return false; + MI = LIS.getInstructionFromIndex(VNI->def); + assert(MI && "Dead valno in interval"); } if (!TII.isTriviallyReMaterializable(*MI, LIS.getAliasAnalysis())) @@ -125,55 +125,55 @@ static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, return true; } -void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &LI) { - float Weight = weightCalcHelper(LI); +void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &LI) { + float Weight = weightCalcHelper(LI); // Check if unspillable. - if (Weight < 0) + if (Weight < 0) return; - LI.setWeight(Weight); + LI.setWeight(Weight); } -float VirtRegAuxInfo::futureWeight(LiveInterval &LI, SlotIndex Start, - SlotIndex End) { - return weightCalcHelper(LI, &Start, &End); +float VirtRegAuxInfo::futureWeight(LiveInterval &LI, SlotIndex Start, + SlotIndex End) { + return weightCalcHelper(LI, &Start, &End); } -float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start, - SlotIndex *End) { - MachineRegisterInfo &MRI = MF.getRegInfo(); - const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); - const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); - MachineBasicBlock *MBB = nullptr; - MachineLoop *Loop = nullptr; - bool IsExiting = false; - float TotalWeight = 0; - unsigned NumInstr = 0; // Number of instructions using LI - SmallPtrSet<MachineInstr *, 8> Visited; - - std::pair<Register, Register> TargetHint = MRI.getRegAllocationHint(LI.reg()); - - if (LI.isSpillable()) { - Register Reg = LI.reg(); - Register Original = VRM.getOriginal(Reg); - const LiveInterval &OrigInt = LIS.getInterval(Original); - // li comes from a split of OrigInt. If OrigInt was marked - // as not spillable, make sure the new interval is marked - // as not spillable as well. - if (!OrigInt.isSpillable()) - LI.markNotSpillable(); - } - +float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start, + SlotIndex *End) { + MachineRegisterInfo &MRI = MF.getRegInfo(); + const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); + const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); + MachineBasicBlock *MBB = nullptr; + MachineLoop *Loop = nullptr; + bool IsExiting = false; + float TotalWeight = 0; + unsigned NumInstr = 0; // Number of instructions using LI + SmallPtrSet<MachineInstr *, 8> Visited; + + std::pair<Register, Register> TargetHint = MRI.getRegAllocationHint(LI.reg()); + + if (LI.isSpillable()) { + Register Reg = LI.reg(); + Register Original = VRM.getOriginal(Reg); + const LiveInterval &OrigInt = LIS.getInterval(Original); + // li comes from a split of OrigInt. If OrigInt was marked + // as not spillable, make sure the new interval is marked + // as not spillable as well. + if (!OrigInt.isSpillable()) + LI.markNotSpillable(); + } + // Don't recompute spill weight for an unspillable register. - bool IsSpillable = LI.isSpillable(); + bool IsSpillable = LI.isSpillable(); - bool IsLocalSplitArtifact = Start && End; + bool IsLocalSplitArtifact = Start && End; // Do not update future local split artifacts. - bool ShouldUpdateLI = !IsLocalSplitArtifact; + bool ShouldUpdateLI = !IsLocalSplitArtifact; - if (IsLocalSplitArtifact) { - MachineBasicBlock *localMBB = LIS.getMBBFromIndex(*End); - assert(localMBB == LIS.getMBBFromIndex(*Start) && + if (IsLocalSplitArtifact) { + MachineBasicBlock *localMBB = LIS.getMBBFromIndex(*End); + assert(localMBB == LIS.getMBBFromIndex(*Start) && "start and end are expected to be in the same basic block"); // Local split artifact will have 2 additional copy instructions and they @@ -181,119 +181,119 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start, // localLI = COPY other // ... // other = COPY localLI - TotalWeight += LiveIntervals::getSpillWeight(true, false, &MBFI, localMBB); - TotalWeight += LiveIntervals::getSpillWeight(false, true, &MBFI, localMBB); + TotalWeight += LiveIntervals::getSpillWeight(true, false, &MBFI, localMBB); + TotalWeight += LiveIntervals::getSpillWeight(false, true, &MBFI, localMBB); - NumInstr += 2; + NumInstr += 2; } // CopyHint is a sortable hint derived from a COPY instruction. struct CopyHint { - const Register Reg; - const float Weight; - CopyHint(Register R, float W) : Reg(R), Weight(W) {} - bool operator<(const CopyHint &Rhs) const { + const Register Reg; + const float Weight; + CopyHint(Register R, float W) : Reg(R), Weight(W) {} + bool operator<(const CopyHint &Rhs) const { // Always prefer any physreg hint. - if (Reg.isPhysical() != Rhs.Reg.isPhysical()) - return Reg.isPhysical(); - if (Weight != Rhs.Weight) - return (Weight > Rhs.Weight); - return Reg.id() < Rhs.Reg.id(); // Tie-breaker. + if (Reg.isPhysical() != Rhs.Reg.isPhysical()) + return Reg.isPhysical(); + if (Weight != Rhs.Weight) + return (Weight > Rhs.Weight); + return Reg.id() < Rhs.Reg.id(); // Tie-breaker. } }; - + std::set<CopyHint> CopyHints; - DenseMap<unsigned, float> Hint; + DenseMap<unsigned, float> Hint; for (MachineRegisterInfo::reg_instr_nodbg_iterator - I = MRI.reg_instr_nodbg_begin(LI.reg()), - E = MRI.reg_instr_nodbg_end(); + I = MRI.reg_instr_nodbg_begin(LI.reg()), + E = MRI.reg_instr_nodbg_end(); I != E;) { - MachineInstr *MI = &*(I++); + MachineInstr *MI = &*(I++); // For local split artifacts, we are interested only in instructions between // the expected start and end of the range. - SlotIndex SI = LIS.getInstructionIndex(*MI); - if (IsLocalSplitArtifact && ((SI < *Start) || (SI > *End))) + SlotIndex SI = LIS.getInstructionIndex(*MI); + if (IsLocalSplitArtifact && ((SI < *Start) || (SI > *End))) continue; - NumInstr++; - if (MI->isIdentityCopy() || MI->isImplicitDef()) + NumInstr++; + if (MI->isIdentityCopy() || MI->isImplicitDef()) continue; - if (!Visited.insert(MI).second) + if (!Visited.insert(MI).second) continue; - // For terminators that produce values, ask the backend if the register is - // not spillable. - if (TII.isUnspillableTerminator(MI) && MI->definesRegister(LI.reg())) { - LI.markNotSpillable(); - return -1.0f; - } - - float Weight = 1.0f; - if (IsSpillable) { + // For terminators that produce values, ask the backend if the register is + // not spillable. + if (TII.isUnspillableTerminator(MI) && MI->definesRegister(LI.reg())) { + LI.markNotSpillable(); + return -1.0f; + } + + float Weight = 1.0f; + if (IsSpillable) { // Get loop info for mi. - if (MI->getParent() != MBB) { - MBB = MI->getParent(); - Loop = Loops.getLoopFor(MBB); - IsExiting = Loop ? Loop->isLoopExiting(MBB) : false; + if (MI->getParent() != MBB) { + MBB = MI->getParent(); + Loop = Loops.getLoopFor(MBB); + IsExiting = Loop ? Loop->isLoopExiting(MBB) : false; } // Calculate instr weight. - bool Reads, Writes; - std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg()); - Weight = LiveIntervals::getSpillWeight(Writes, Reads, &MBFI, *MI); + bool Reads, Writes; + std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg()); + Weight = LiveIntervals::getSpillWeight(Writes, Reads, &MBFI, *MI); // Give extra weight to what looks like a loop induction variable update. - if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI, MBB)) - Weight *= 3; + if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI, MBB)) + Weight *= 3; - TotalWeight += Weight; + TotalWeight += Weight; } // Get allocation hints from copies. - if (!MI->isCopy()) + if (!MI->isCopy()) continue; - Register HintReg = copyHint(MI, LI.reg(), TRI, MRI); - if (!HintReg) + Register HintReg = copyHint(MI, LI.reg(), TRI, MRI); + if (!HintReg) continue; // Force hweight onto the stack so that x86 doesn't add hidden precision, // making the comparison incorrectly pass (i.e., 1 > 1 == true??). // // FIXME: we probably shouldn't use floats at all. - volatile float HWeight = Hint[HintReg] += Weight; - if (HintReg.isVirtual() || MRI.isAllocatable(HintReg)) - CopyHints.insert(CopyHint(HintReg, HWeight)); + volatile float HWeight = Hint[HintReg] += Weight; + if (HintReg.isVirtual() || MRI.isAllocatable(HintReg)) + CopyHints.insert(CopyHint(HintReg, HWeight)); } // Pass all the sorted copy hints to mri. - if (ShouldUpdateLI && CopyHints.size()) { + if (ShouldUpdateLI && CopyHints.size()) { // Remove a generic hint if previously added by target. if (TargetHint.first == 0 && TargetHint.second) - MRI.clearSimpleHint(LI.reg()); + MRI.clearSimpleHint(LI.reg()); - std::set<Register> HintedRegs; + std::set<Register> HintedRegs; for (auto &Hint : CopyHints) { if (!HintedRegs.insert(Hint.Reg).second || (TargetHint.first != 0 && Hint.Reg == TargetHint.second)) // Don't add the same reg twice or the target-type hint again. continue; - MRI.addRegAllocationHint(LI.reg(), Hint.Reg); + MRI.addRegAllocationHint(LI.reg(), Hint.Reg); } // Weakly boost the spill weight of hinted registers. - TotalWeight *= 1.01F; + TotalWeight *= 1.01F; } // If the live interval was already unspillable, leave it that way. - if (!IsSpillable) + if (!IsSpillable) return -1.0; // Mark li as unspillable if all live ranges are tiny and the interval // is not live at any reg mask. If the interval is live at a reg mask // spilling may be required. - if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) && - !LI.isLiveAtIndexes(LIS.getRegMaskSlots())) { - LI.markNotSpillable(); + if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) && + !LI.isLiveAtIndexes(LIS.getRegMaskSlots())) { + LI.markNotSpillable(); return -1.0; } @@ -301,10 +301,10 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start, // it is a preferred candidate for spilling. // FIXME: this gets much more complicated once we support non-trivial // re-materialization. - if (isRematerializable(LI, LIS, VRM, *MF.getSubtarget().getInstrInfo())) - TotalWeight *= 0.5F; + if (isRematerializable(LI, LIS, VRM, *MF.getSubtarget().getInstrInfo())) + TotalWeight *= 0.5F; - if (IsLocalSplitArtifact) - return normalize(TotalWeight, Start->distance(*End), NumInstr); - return normalize(TotalWeight, LI.getSize(), NumInstr); + if (IsLocalSplitArtifact) + return normalize(TotalWeight, Start->distance(*End), NumInstr); + return normalize(TotalWeight, LI.getSize(), NumInstr); } |