summaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp')
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp511
1 files changed, 0 insertions, 511 deletions
diff --git a/contrib/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp b/contrib/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp
deleted file mode 100644
index 39460fbd8a84..000000000000
--- a/contrib/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp
+++ /dev/null
@@ -1,511 +0,0 @@
-//===- GCNRegPressure.cpp -------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "GCNRegPressure.h"
-#include "AMDGPUSubtarget.h"
-#include "SIRegisterInfo.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/LiveInterval.h"
-#include "llvm/CodeGen/LiveIntervals.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/RegisterPressure.h"
-#include "llvm/CodeGen/SlotIndexes.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/Config/llvm-config.h"
-#include "llvm/MC/LaneBitmask.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-
-using namespace llvm;
-
-#define DEBUG_TYPE "machine-scheduler"
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_DUMP_METHOD
-void llvm::printLivesAt(SlotIndex SI,
- const LiveIntervals &LIS,
- const MachineRegisterInfo &MRI) {
- dbgs() << "Live regs at " << SI << ": "
- << *LIS.getInstructionFromIndex(SI);
- unsigned Num = 0;
- for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
- const unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
- if (!LIS.hasInterval(Reg))
- continue;
- const auto &LI = LIS.getInterval(Reg);
- if (LI.hasSubRanges()) {
- bool firstTime = true;
- for (const auto &S : LI.subranges()) {
- if (!S.liveAt(SI)) continue;
- if (firstTime) {
- dbgs() << " " << printReg(Reg, MRI.getTargetRegisterInfo())
- << '\n';
- firstTime = false;
- }
- dbgs() << " " << S << '\n';
- ++Num;
- }
- } else if (LI.liveAt(SI)) {
- dbgs() << " " << LI << '\n';
- ++Num;
- }
- }
- if (!Num) dbgs() << " <none>\n";
-}
-#endif
-
-bool llvm::isEqual(const GCNRPTracker::LiveRegSet &S1,
- const GCNRPTracker::LiveRegSet &S2) {
- if (S1.size() != S2.size())
- return false;
-
- for (const auto &P : S1) {
- auto I = S2.find(P.first);
- if (I == S2.end() || I->second != P.second)
- return false;
- }
- return true;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// GCNRegPressure
-
-unsigned GCNRegPressure::getRegKind(unsigned Reg,
- const MachineRegisterInfo &MRI) {
- assert(TargetRegisterInfo::isVirtualRegister(Reg));
- const auto RC = MRI.getRegClass(Reg);
- auto STI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
- return STI->isSGPRClass(RC) ?
- (STI->getRegSizeInBits(*RC) == 32 ? SGPR32 : SGPR_TUPLE) :
- STI->hasAGPRs(RC) ?
- (STI->getRegSizeInBits(*RC) == 32 ? AGPR32 : AGPR_TUPLE) :
- (STI->getRegSizeInBits(*RC) == 32 ? VGPR32 : VGPR_TUPLE);
-}
-
-void GCNRegPressure::inc(unsigned Reg,
- LaneBitmask PrevMask,
- LaneBitmask NewMask,
- const MachineRegisterInfo &MRI) {
- if (NewMask == PrevMask)
- return;
-
- int Sign = 1;
- if (NewMask < PrevMask) {
- std::swap(NewMask, PrevMask);
- Sign = -1;
- }
-#ifndef NDEBUG
- const auto MaxMask = MRI.getMaxLaneMaskForVReg(Reg);
-#endif
- switch (auto Kind = getRegKind(Reg, MRI)) {
- case SGPR32:
- case VGPR32:
- case AGPR32:
- assert(PrevMask.none() && NewMask == MaxMask);
- Value[Kind] += Sign;
- break;
-
- case SGPR_TUPLE:
- case VGPR_TUPLE:
- case AGPR_TUPLE:
- assert(NewMask < MaxMask || NewMask == MaxMask);
- assert(PrevMask < NewMask);
-
- Value[Kind == SGPR_TUPLE ? SGPR32 : Kind == AGPR_TUPLE ? AGPR32 : VGPR32] +=
- Sign * (~PrevMask & NewMask).getNumLanes();
-
- if (PrevMask.none()) {
- assert(NewMask.any());
- Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
- }
- break;
-
- default: llvm_unreachable("Unknown register kind");
- }
-}
-
-bool GCNRegPressure::less(const GCNSubtarget &ST,
- const GCNRegPressure& O,
- unsigned MaxOccupancy) const {
- const auto SGPROcc = std::min(MaxOccupancy,
- ST.getOccupancyWithNumSGPRs(getSGPRNum()));
- const auto VGPROcc = std::min(MaxOccupancy,
- ST.getOccupancyWithNumVGPRs(getVGPRNum()));
- const auto OtherSGPROcc = std::min(MaxOccupancy,
- ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
- const auto OtherVGPROcc = std::min(MaxOccupancy,
- ST.getOccupancyWithNumVGPRs(O.getVGPRNum()));
-
- const auto Occ = std::min(SGPROcc, VGPROcc);
- const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
- if (Occ != OtherOcc)
- return Occ > OtherOcc;
-
- bool SGPRImportant = SGPROcc < VGPROcc;
- const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
-
- // if both pressures disagree on what is more important compare vgprs
- if (SGPRImportant != OtherSGPRImportant) {
- SGPRImportant = false;
- }
-
- // compare large regs pressure
- bool SGPRFirst = SGPRImportant;
- for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
- if (SGPRFirst) {
- auto SW = getSGPRTuplesWeight();
- auto OtherSW = O.getSGPRTuplesWeight();
- if (SW != OtherSW)
- return SW < OtherSW;
- } else {
- auto VW = getVGPRTuplesWeight();
- auto OtherVW = O.getVGPRTuplesWeight();
- if (VW != OtherVW)
- return VW < OtherVW;
- }
- }
- return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
- (getVGPRNum() < O.getVGPRNum());
-}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_DUMP_METHOD
-void GCNRegPressure::print(raw_ostream &OS, const GCNSubtarget *ST) const {
- OS << "VGPRs: " << getVGPRNum();
- if (ST) OS << "(O" << ST->getOccupancyWithNumVGPRs(getVGPRNum()) << ')';
- OS << ", SGPRs: " << getSGPRNum();
- if (ST) OS << "(O" << ST->getOccupancyWithNumSGPRs(getSGPRNum()) << ')';
- OS << ", LVGPR WT: " << getVGPRTuplesWeight()
- << ", LSGPR WT: " << getSGPRTuplesWeight();
- if (ST) OS << " -> Occ: " << getOccupancy(*ST);
- OS << '\n';
-}
-#endif
-
-static LaneBitmask getDefRegMask(const MachineOperand &MO,
- const MachineRegisterInfo &MRI) {
- assert(MO.isDef() && MO.isReg() &&
- TargetRegisterInfo::isVirtualRegister(MO.getReg()));
-
- // We don't rely on read-undef flag because in case of tentative schedule
- // tracking it isn't set correctly yet. This works correctly however since
- // use mask has been tracked before using LIS.
- return MO.getSubReg() == 0 ?
- MRI.getMaxLaneMaskForVReg(MO.getReg()) :
- MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
-}
-
-static LaneBitmask getUsedRegMask(const MachineOperand &MO,
- const MachineRegisterInfo &MRI,
- const LiveIntervals &LIS) {
- assert(MO.isUse() && MO.isReg() &&
- TargetRegisterInfo::isVirtualRegister(MO.getReg()));
-
- if (auto SubReg = MO.getSubReg())
- return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);
-
- auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
- if (MaxMask == LaneBitmask::getLane(0)) // cannot have subregs
- return MaxMask;
-
- // For a tentative schedule LIS isn't updated yet but livemask should remain
- // the same on any schedule. Subreg defs can be reordered but they all must
- // dominate uses anyway.
- auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
- return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
-}
-
-static SmallVector<RegisterMaskPair, 8>
-collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS,
- const MachineRegisterInfo &MRI) {
- SmallVector<RegisterMaskPair, 8> Res;
- for (const auto &MO : MI.operands()) {
- if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
- continue;
- if (!MO.isUse() || !MO.readsReg())
- continue;
-
- auto const UsedMask = getUsedRegMask(MO, MRI, LIS);
-
- auto Reg = MO.getReg();
- auto I = std::find_if(Res.begin(), Res.end(), [Reg](const RegisterMaskPair &RM) {
- return RM.RegUnit == Reg;
- });
- if (I != Res.end())
- I->LaneMask |= UsedMask;
- else
- Res.push_back(RegisterMaskPair(Reg, UsedMask));
- }
- return Res;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// GCNRPTracker
-
-LaneBitmask llvm::getLiveLaneMask(unsigned Reg,
- SlotIndex SI,
- const LiveIntervals &LIS,
- const MachineRegisterInfo &MRI) {
- LaneBitmask LiveMask;
- const auto &LI = LIS.getInterval(Reg);
- if (LI.hasSubRanges()) {
- for (const auto &S : LI.subranges())
- if (S.liveAt(SI)) {
- LiveMask |= S.LaneMask;
- assert(LiveMask < MRI.getMaxLaneMaskForVReg(Reg) ||
- LiveMask == MRI.getMaxLaneMaskForVReg(Reg));
- }
- } else if (LI.liveAt(SI)) {
- LiveMask = MRI.getMaxLaneMaskForVReg(Reg);
- }
- return LiveMask;
-}
-
-GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI,
- const LiveIntervals &LIS,
- const MachineRegisterInfo &MRI) {
- GCNRPTracker::LiveRegSet LiveRegs;
- for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
- auto Reg = TargetRegisterInfo::index2VirtReg(I);
- if (!LIS.hasInterval(Reg))
- continue;
- auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
- if (LiveMask.any())
- LiveRegs[Reg] = LiveMask;
- }
- return LiveRegs;
-}
-
-void GCNRPTracker::reset(const MachineInstr &MI,
- const LiveRegSet *LiveRegsCopy,
- bool After) {
- const MachineFunction &MF = *MI.getMF();
- MRI = &MF.getRegInfo();
- if (LiveRegsCopy) {
- if (&LiveRegs != LiveRegsCopy)
- LiveRegs = *LiveRegsCopy;
- } else {
- LiveRegs = After ? getLiveRegsAfter(MI, LIS)
- : getLiveRegsBefore(MI, LIS);
- }
-
- MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
-}
-
-void GCNUpwardRPTracker::reset(const MachineInstr &MI,
- const LiveRegSet *LiveRegsCopy) {
- GCNRPTracker::reset(MI, LiveRegsCopy, true);
-}
-
-void GCNUpwardRPTracker::recede(const MachineInstr &MI) {
- assert(MRI && "call reset first");
-
- LastTrackedMI = &MI;
-
- if (MI.isDebugInstr())
- return;
-
- auto const RegUses = collectVirtualRegUses(MI, LIS, *MRI);
-
- // calc pressure at the MI (defs + uses)
- auto AtMIPressure = CurPressure;
- for (const auto &U : RegUses) {
- auto LiveMask = LiveRegs[U.RegUnit];
- AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
- }
- // update max pressure
- MaxPressure = max(AtMIPressure, MaxPressure);
-
- for (const auto &MO : MI.defs()) {
- if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()) ||
- MO.isDead())
- continue;
-
- auto Reg = MO.getReg();
- auto I = LiveRegs.find(Reg);
- if (I == LiveRegs.end())
- continue;
- auto &LiveMask = I->second;
- auto PrevMask = LiveMask;
- LiveMask &= ~getDefRegMask(MO, *MRI);
- CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
- if (LiveMask.none())
- LiveRegs.erase(I);
- }
- for (const auto &U : RegUses) {
- auto &LiveMask = LiveRegs[U.RegUnit];
- auto PrevMask = LiveMask;
- LiveMask |= U.LaneMask;
- CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
- }
- assert(CurPressure == getRegPressure(*MRI, LiveRegs));
-}
-
-bool GCNDownwardRPTracker::reset(const MachineInstr &MI,
- const LiveRegSet *LiveRegsCopy) {
- MRI = &MI.getParent()->getParent()->getRegInfo();
- LastTrackedMI = nullptr;
- MBBEnd = MI.getParent()->end();
- NextMI = &MI;
- NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
- if (NextMI == MBBEnd)
- return false;
- GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
- return true;
-}
-
-bool GCNDownwardRPTracker::advanceBeforeNext() {
- assert(MRI && "call reset first");
-
- NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
- if (NextMI == MBBEnd)
- return false;
-
- SlotIndex SI = LIS.getInstructionIndex(*NextMI).getBaseIndex();
- assert(SI.isValid());
-
- // Remove dead registers or mask bits.
- for (auto &It : LiveRegs) {
- const LiveInterval &LI = LIS.getInterval(It.first);
- if (LI.hasSubRanges()) {
- for (const auto &S : LI.subranges()) {
- if (!S.liveAt(SI)) {
- auto PrevMask = It.second;
- It.second &= ~S.LaneMask;
- CurPressure.inc(It.first, PrevMask, It.second, *MRI);
- }
- }
- } else if (!LI.liveAt(SI)) {
- auto PrevMask = It.second;
- It.second = LaneBitmask::getNone();
- CurPressure.inc(It.first, PrevMask, It.second, *MRI);
- }
- if (It.second.none())
- LiveRegs.erase(It.first);
- }
-
- MaxPressure = max(MaxPressure, CurPressure);
-
- return true;
-}
-
-void GCNDownwardRPTracker::advanceToNext() {
- LastTrackedMI = &*NextMI++;
-
- // Add new registers or mask bits.
- for (const auto &MO : LastTrackedMI->defs()) {
- if (!MO.isReg())
- continue;
- unsigned Reg = MO.getReg();
- if (!TargetRegisterInfo::isVirtualRegister(Reg))
- continue;
- auto &LiveMask = LiveRegs[Reg];
- auto PrevMask = LiveMask;
- LiveMask |= getDefRegMask(MO, *MRI);
- CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
- }
-
- MaxPressure = max(MaxPressure, CurPressure);
-}
-
-bool GCNDownwardRPTracker::advance() {
- // If we have just called reset live set is actual.
- if ((NextMI == MBBEnd) || (LastTrackedMI && !advanceBeforeNext()))
- return false;
- advanceToNext();
- return true;
-}
-
-bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator End) {
- while (NextMI != End)
- if (!advance()) return false;
- return true;
-}
-
-bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator Begin,
- MachineBasicBlock::const_iterator End,
- const LiveRegSet *LiveRegsCopy) {
- reset(*Begin, LiveRegsCopy);
- return advance(End);
-}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_DUMP_METHOD
-static void reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
- const GCNRPTracker::LiveRegSet &TrackedLR,
- const TargetRegisterInfo *TRI) {
- for (auto const &P : TrackedLR) {
- auto I = LISLR.find(P.first);
- if (I == LISLR.end()) {
- dbgs() << " " << printReg(P.first, TRI)
- << ":L" << PrintLaneMask(P.second)
- << " isn't found in LIS reported set\n";
- }
- else if (I->second != P.second) {
- dbgs() << " " << printReg(P.first, TRI)
- << " masks doesn't match: LIS reported "
- << PrintLaneMask(I->second)
- << ", tracked "
- << PrintLaneMask(P.second)
- << '\n';
- }
- }
- for (auto const &P : LISLR) {
- auto I = TrackedLR.find(P.first);
- if (I == TrackedLR.end()) {
- dbgs() << " " << printReg(P.first, TRI)
- << ":L" << PrintLaneMask(P.second)
- << " isn't found in tracked set\n";
- }
- }
-}
-
-bool GCNUpwardRPTracker::isValid() const {
- const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
- const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
- const auto &TrackedLR = LiveRegs;
-
- if (!isEqual(LISLR, TrackedLR)) {
- dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
- " LIS reported livesets mismatch:\n";
- printLivesAt(SI, LIS, *MRI);
- reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
- return false;
- }
-
- auto LISPressure = getRegPressure(*MRI, LISLR);
- if (LISPressure != CurPressure) {
- dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: ";
- CurPressure.print(dbgs());
- dbgs() << "LIS rpt: ";
- LISPressure.print(dbgs());
- return false;
- }
- return true;
-}
-
-void GCNRPTracker::printLiveRegs(raw_ostream &OS, const LiveRegSet& LiveRegs,
- const MachineRegisterInfo &MRI) {
- const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
- for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
- unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
- auto It = LiveRegs.find(Reg);
- if (It != LiveRegs.end() && It->second.any())
- OS << ' ' << printVRegOrUnit(Reg, TRI) << ':'
- << PrintLaneMask(It->second);
- }
- OS << '\n';
-}
-#endif