|
14 | 14 | #include "GCNRegPressure.h" |
15 | 15 | #include "AMDGPU.h" |
16 | 16 | #include "SIMachineFunctionInfo.h" |
| 17 | +#include "llvm/CodeGen/MachineLoopInfo.h" |
17 | 18 | #include "llvm/CodeGen/RegisterPressure.h" |
18 | 19 |
|
19 | 20 | using namespace llvm; |
@@ -459,10 +460,14 @@ LaneBitmask llvm::getLiveLaneMask(const LiveInterval &LI, SlotIndex SI, |
459 | 460 |
|
460 | 461 | GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI, |
461 | 462 | const LiveIntervals &LIS, |
462 | | - const MachineRegisterInfo &MRI) { |
| 463 | + const MachineRegisterInfo &MRI, |
| 464 | + GCNRegPressure::RegKind RegKind) { |
463 | 465 | GCNRPTracker::LiveRegSet LiveRegs; |
464 | 466 | for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { |
465 | 467 | auto Reg = Register::index2VirtReg(I); |
| 468 | + if (RegKind != GCNRegPressure::TOTAL_KINDS && |
| 469 | + GCNRegPressure::getRegKind(Reg, MRI) != RegKind) |
| 470 | + continue; |
466 | 471 | if (!LIS.hasInterval(Reg)) |
467 | 472 | continue; |
468 | 473 | auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI); |
@@ -986,3 +991,128 @@ bool GCNRegPressurePrinter::runOnMachineFunction(MachineFunction &MF) { |
986 | 991 |
|
987 | 992 | #undef PFX |
988 | 993 | } |
| 994 | + |
| 995 | +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
| 996 | +LLVM_DUMP_METHOD void llvm::dumpMaxRegPressure(MachineFunction &MF, |
| 997 | + GCNRegPressure::RegKind Kind, |
| 998 | + LiveIntervals &LIS, |
| 999 | + const MachineLoopInfo *MLI) { |
| 1000 | + |
| 1001 | + const MachineRegisterInfo &MRI = MF.getRegInfo(); |
| 1002 | + const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); |
| 1003 | + auto &OS = dbgs(); |
| 1004 | + const char *RegName = GCNRegPressure::getName(Kind); |
| 1005 | + |
| 1006 | + unsigned MaxNumRegs = 0; |
| 1007 | + const MachineInstr *MaxPressureMI = nullptr; |
| 1008 | + GCNUpwardRPTracker RPT(LIS); |
| 1009 | + for (const MachineBasicBlock &MBB : MF) { |
| 1010 | + RPT.reset(MRI, LIS.getSlotIndexes()->getMBBEndIdx(&MBB).getPrevSlot()); |
| 1011 | + for (const MachineInstr &MI : reverse(MBB)) { |
| 1012 | + RPT.recede(MI); |
| 1013 | + unsigned NumRegs = RPT.getMaxPressure().getNumRegs(Kind); |
| 1014 | + if (NumRegs > MaxNumRegs) { |
| 1015 | + MaxNumRegs = NumRegs; |
| 1016 | + MaxPressureMI = &MI; |
| 1017 | + } |
| 1018 | + } |
| 1019 | + } |
| 1020 | + |
| 1021 | + SlotIndex MISlot = LIS.getInstructionIndex(*MaxPressureMI); |
| 1022 | + |
| 1023 | + // Max pressure can occur at either the early-clobber or register slot. |
| 1024 | + // Choose the maximum liveset between both slots. This is ugly but this is |
| 1025 | + // diagnostic code. |
| 1026 | + SlotIndex ECSlot = MISlot.getRegSlot(true); |
| 1027 | + SlotIndex RSlot = MISlot.getRegSlot(false); |
| 1028 | + GCNRPTracker::LiveRegSet ECLiveSet = getLiveRegs(ECSlot, LIS, MRI, Kind); |
| 1029 | + GCNRPTracker::LiveRegSet RLiveSet = getLiveRegs(RSlot, LIS, MRI, Kind); |
| 1030 | + unsigned ECNumRegs = getRegPressure(MRI, ECLiveSet).getNumRegs(Kind); |
| 1031 | + unsigned RNumRegs = getRegPressure(MRI, RLiveSet).getNumRegs(Kind); |
| 1032 | + GCNRPTracker::LiveRegSet *LiveSet = |
| 1033 | + ECNumRegs > RNumRegs ? &ECLiveSet : &RLiveSet; |
| 1034 | + SlotIndex MaxPressureSlot = ECNumRegs > RNumRegs ? ECSlot : RSlot; |
| 1035 | + assert(getRegPressure(MRI, *LiveSet).getNumRegs(Kind) == MaxNumRegs); |
| 1036 | + |
| 1037 | + // Split live registers into single-def and multi-def sets. |
| 1038 | + GCNRegPressure SDefPressure, MDefPressure; |
| 1039 | + SmallVector<Register, 16> SDefRegs, MDefRegs; |
| 1040 | + for (auto [Reg, LaneMask] : *LiveSet) { |
| 1041 | + assert(GCNRegPressure::getRegKind(Reg, MRI) == Kind); |
| 1042 | + LiveInterval &LI = LIS.getInterval(Reg); |
| 1043 | + if (LI.getNumValNums() == 1 || |
| 1044 | + (LI.hasSubRanges() && |
| 1045 | + llvm::all_of(LI.subranges(), [](const LiveInterval::SubRange &SR) { |
| 1046 | + return SR.getNumValNums() == 1; |
| 1047 | + }))) { |
| 1048 | + SDefPressure.inc(Reg, LaneBitmask::getNone(), LaneMask, MRI); |
| 1049 | + SDefRegs.push_back(Reg); |
| 1050 | + } else { |
| 1051 | + MDefPressure.inc(Reg, LaneBitmask::getNone(), LaneMask, MRI); |
| 1052 | + MDefRegs.push_back(Reg); |
| 1053 | + } |
| 1054 | + } |
| 1055 | + unsigned SDefNumRegs = SDefPressure.getNumRegs(Kind); |
| 1056 | + unsigned MDefNumRegs = MDefPressure.getNumRegs(Kind); |
| 1057 | + assert(SDefNumRegs + MDefNumRegs == MaxNumRegs); |
| 1058 | + |
| 1059 | + auto printLoc = [&](const MachineBasicBlock *MBB, SlotIndex SI) { |
| 1060 | + return Printable([&, MBB, SI](raw_ostream &OS) { |
| 1061 | + OS << SI << ':' << printMBBReference(*MBB); |
| 1062 | + if (MLI) |
| 1063 | + if (const MachineLoop *ML = MLI->getLoopFor(MBB)) |
| 1064 | + OS << " (LoopHdr " << printMBBReference(*ML->getHeader()) |
| 1065 | + << ", Depth " << ML->getLoopDepth() << ")"; |
| 1066 | + }); |
| 1067 | + }; |
| 1068 | + |
| 1069 | + auto PrintRegInfo = [&](Register Reg, LaneBitmask LiveMask) { |
| 1070 | + GCNRegPressure RegPressure; |
| 1071 | + RegPressure.inc(Reg, LaneBitmask::getNone(), LiveMask, MRI); |
| 1072 | + OS << " " << printReg(Reg, TRI) << ':' |
| 1073 | + << TRI->getRegClassName(MRI.getRegClass(Reg)) << ", LiveMask " |
| 1074 | + << PrintLaneMask(LiveMask) << " (" << RegPressure.getNumRegs(Kind) << ' ' |
| 1075 | + << RegName << "s)\n"; |
| 1076 | + |
| 1077 | + // Use std::map to sort def/uses by SlotIndex. |
| 1078 | + std::map<SlotIndex, const MachineInstr *> Instrs; |
| 1079 | + for (const MachineInstr &MI : MRI.reg_nodbg_instructions(Reg)) { |
| 1080 | + Instrs[LIS.getInstructionIndex(MI).getRegSlot()] = &MI; |
| 1081 | + } |
| 1082 | + |
| 1083 | + for (const auto &[SI, MI] : Instrs) { |
| 1084 | + OS << " "; |
| 1085 | + if (MI->definesRegister(Reg, TRI)) |
| 1086 | + OS << "def "; |
| 1087 | + if (MI->readsRegister(Reg, TRI)) |
| 1088 | + OS << "use "; |
| 1089 | + OS << printLoc(MI->getParent(), SI) << ": " << *MI; |
| 1090 | + } |
| 1091 | + }; |
| 1092 | + |
| 1093 | + OS << "\n*** Register pressure info (" << RegName << "s) for " << MF.getName() |
| 1094 | + << " ***\n"; |
| 1095 | + OS << "Max pressure is " << MaxNumRegs << ' ' << RegName << "s at " |
| 1096 | + << printLoc(MaxPressureMI->getParent(), MaxPressureSlot) << ": " |
| 1097 | + << *MaxPressureMI; |
| 1098 | + |
| 1099 | + OS << "\nLive registers with single definition (" << SDefNumRegs << ' ' |
| 1100 | + << RegName << "s):\n"; |
| 1101 | + |
| 1102 | + // Sort SDefRegs by number of uses (smallest first) |
| 1103 | + llvm::sort(SDefRegs, [&](Register A, Register B) { |
| 1104 | + return std::distance(MRI.use_nodbg_begin(A), MRI.use_nodbg_end()) < |
| 1105 | + std::distance(MRI.use_nodbg_begin(B), MRI.use_nodbg_end()); |
| 1106 | + }); |
| 1107 | + |
| 1108 | + for (const Register Reg : SDefRegs) { |
| 1109 | + PrintRegInfo(Reg, LiveSet->lookup(Reg)); |
| 1110 | + } |
| 1111 | + |
| 1112 | + OS << "\nLive registers with multiple definitions (" << MDefNumRegs << ' ' |
| 1113 | + << RegName << "s):\n"; |
| 1114 | + for (const Register Reg : MDefRegs) { |
| 1115 | + PrintRegInfo(Reg, LiveSet->lookup(Reg)); |
| 1116 | + } |
| 1117 | +} |
| 1118 | +#endif |
0 commit comments