aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:30 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:30 +0300
commit2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch)
tree012bb94d777798f1f56ac1cec429509766d05181 /contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp
parent6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff)
downloadydb-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.cpp296
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);
}