xref: /src/contrib/llvm-project/llvm/lib/CodeGen/RegUsageInfoCollector.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
101095a5dSDimitry Andric //===-- RegUsageInfoCollector.cpp - Register Usage Information Collector --===//
201095a5dSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
601095a5dSDimitry Andric //
701095a5dSDimitry Andric //===----------------------------------------------------------------------===//
801095a5dSDimitry Andric ///
901095a5dSDimitry Andric /// This pass is required to take advantage of the interprocedural register
1001095a5dSDimitry Andric /// allocation infrastructure.
1101095a5dSDimitry Andric ///
1201095a5dSDimitry Andric /// This pass is simple MachineFunction pass which collects register usage
1301095a5dSDimitry Andric /// details by iterating through each physical registers and checking
1401095a5dSDimitry Andric /// MRI::isPhysRegUsed() then creates a RegMask based on this details.
1501095a5dSDimitry Andric /// The pass then stores this RegMask in PhysicalRegisterUsageInfo.cpp
1601095a5dSDimitry Andric ///
1701095a5dSDimitry Andric //===----------------------------------------------------------------------===//
1801095a5dSDimitry Andric 
1901095a5dSDimitry Andric #include "llvm/ADT/Statistic.h"
2001095a5dSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
2101095a5dSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
2201095a5dSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
2301095a5dSDimitry Andric #include "llvm/CodeGen/Passes.h"
2401095a5dSDimitry Andric #include "llvm/CodeGen/RegisterUsageInfo.h"
25145449b1SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
26145449b1SDimitry Andric #include "llvm/IR/Function.h"
2701095a5dSDimitry Andric #include "llvm/Support/Debug.h"
2801095a5dSDimitry Andric #include "llvm/Support/raw_ostream.h"
2901095a5dSDimitry Andric 
3001095a5dSDimitry Andric using namespace llvm;
3101095a5dSDimitry Andric 
3201095a5dSDimitry Andric #define DEBUG_TYPE "ip-regalloc"
3301095a5dSDimitry Andric 
3401095a5dSDimitry Andric STATISTIC(NumCSROpt,
3501095a5dSDimitry Andric           "Number of functions optimized for callee saved registers");
3601095a5dSDimitry Andric 
3701095a5dSDimitry Andric namespace {
38eb11fae6SDimitry Andric 
3901095a5dSDimitry Andric class RegUsageInfoCollector : public MachineFunctionPass {
4001095a5dSDimitry Andric public:
RegUsageInfoCollector()4101095a5dSDimitry Andric   RegUsageInfoCollector() : MachineFunctionPass(ID) {
4201095a5dSDimitry Andric     PassRegistry &Registry = *PassRegistry::getPassRegistry();
4301095a5dSDimitry Andric     initializeRegUsageInfoCollectorPass(Registry);
4401095a5dSDimitry Andric   }
4501095a5dSDimitry Andric 
getPassName() const46b915e9e0SDimitry Andric   StringRef getPassName() const override {
4701095a5dSDimitry Andric     return "Register Usage Information Collector Pass";
4801095a5dSDimitry Andric   }
4901095a5dSDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const50eb11fae6SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
51eb11fae6SDimitry Andric     AU.addRequired<PhysicalRegisterUsageInfo>();
52eb11fae6SDimitry Andric     AU.setPreservesAll();
53eb11fae6SDimitry Andric     MachineFunctionPass::getAnalysisUsage(AU);
54eb11fae6SDimitry Andric   }
5501095a5dSDimitry Andric 
5601095a5dSDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
5701095a5dSDimitry Andric 
58706b4fc4SDimitry Andric   // Call getCalleeSaves and then also set the bits for subregs and
59eb11fae6SDimitry Andric   // fully saved superregs.
60eb11fae6SDimitry Andric   static void computeCalleeSavedRegs(BitVector &SavedRegs, MachineFunction &MF);
61eb11fae6SDimitry Andric 
6201095a5dSDimitry Andric   static char ID;
6301095a5dSDimitry Andric };
64eb11fae6SDimitry Andric 
6501095a5dSDimitry Andric } // end of anonymous namespace
6601095a5dSDimitry Andric 
6701095a5dSDimitry Andric char RegUsageInfoCollector::ID = 0;
6801095a5dSDimitry Andric 
6901095a5dSDimitry Andric INITIALIZE_PASS_BEGIN(RegUsageInfoCollector, "RegUsageInfoCollector",
7001095a5dSDimitry Andric                       "Register Usage Information Collector", false, false)
INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo)7101095a5dSDimitry Andric INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo)
7201095a5dSDimitry Andric INITIALIZE_PASS_END(RegUsageInfoCollector, "RegUsageInfoCollector",
7301095a5dSDimitry Andric                     "Register Usage Information Collector", false, false)
7401095a5dSDimitry Andric 
7501095a5dSDimitry Andric FunctionPass *llvm::createRegUsageInfoCollector() {
7601095a5dSDimitry Andric   return new RegUsageInfoCollector();
7701095a5dSDimitry Andric }
7801095a5dSDimitry Andric 
79e6d15924SDimitry Andric // TODO: Move to hook somwehere?
80e6d15924SDimitry Andric 
81e6d15924SDimitry Andric // Return true if it is useful to track the used registers for IPRA / no CSR
82e6d15924SDimitry Andric // optimizations. This is not useful for entry points, and computing the
83e6d15924SDimitry Andric // register usage information is expensive.
isCallableFunction(const MachineFunction & MF)84e6d15924SDimitry Andric static bool isCallableFunction(const MachineFunction &MF) {
85e6d15924SDimitry Andric   switch (MF.getFunction().getCallingConv()) {
86e6d15924SDimitry Andric   case CallingConv::AMDGPU_VS:
87e6d15924SDimitry Andric   case CallingConv::AMDGPU_GS:
88e6d15924SDimitry Andric   case CallingConv::AMDGPU_PS:
89e6d15924SDimitry Andric   case CallingConv::AMDGPU_CS:
90e6d15924SDimitry Andric   case CallingConv::AMDGPU_HS:
91e6d15924SDimitry Andric   case CallingConv::AMDGPU_ES:
92e6d15924SDimitry Andric   case CallingConv::AMDGPU_LS:
93e6d15924SDimitry Andric   case CallingConv::AMDGPU_KERNEL:
94e6d15924SDimitry Andric     return false;
95e6d15924SDimitry Andric   default:
96e6d15924SDimitry Andric     return true;
97e6d15924SDimitry Andric   }
98e6d15924SDimitry Andric }
99e6d15924SDimitry Andric 
runOnMachineFunction(MachineFunction & MF)10001095a5dSDimitry Andric bool RegUsageInfoCollector::runOnMachineFunction(MachineFunction &MF) {
10101095a5dSDimitry Andric   MachineRegisterInfo *MRI = &MF.getRegInfo();
10201095a5dSDimitry Andric   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
103d8e91e46SDimitry Andric   const LLVMTargetMachine &TM = MF.getTarget();
10401095a5dSDimitry Andric 
105eb11fae6SDimitry Andric   LLVM_DEBUG(dbgs() << " -------------------- " << getPassName()
106e6d15924SDimitry Andric                     << " -------------------- \nFunction Name : "
107e6d15924SDimitry Andric                     << MF.getName() << '\n');
108e6d15924SDimitry Andric 
109e6d15924SDimitry Andric   // Analyzing the register usage may be expensive on some targets.
110e6d15924SDimitry Andric   if (!isCallableFunction(MF)) {
111e6d15924SDimitry Andric     LLVM_DEBUG(dbgs() << "Not analyzing non-callable function\n");
112e6d15924SDimitry Andric     return false;
113e6d15924SDimitry Andric   }
114e6d15924SDimitry Andric 
115e6d15924SDimitry Andric   // If there are no callers, there's no point in computing more precise
116e6d15924SDimitry Andric   // register usage here.
117e6d15924SDimitry Andric   if (MF.getFunction().use_empty()) {
118e6d15924SDimitry Andric     LLVM_DEBUG(dbgs() << "Not analyzing function with no callers\n");
119e6d15924SDimitry Andric     return false;
120e6d15924SDimitry Andric   }
12101095a5dSDimitry Andric 
12201095a5dSDimitry Andric   std::vector<uint32_t> RegMask;
12301095a5dSDimitry Andric 
12401095a5dSDimitry Andric   // Compute the size of the bit vector to represent all the registers.
12501095a5dSDimitry Andric   // The bit vector is broken into 32-bit chunks, thus takes the ceil of
12601095a5dSDimitry Andric   // the number of registers divided by 32 for the size.
127eb11fae6SDimitry Andric   unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
128eb11fae6SDimitry Andric   RegMask.resize(RegMaskSize, ~((uint32_t)0));
12901095a5dSDimitry Andric 
130044eb2f6SDimitry Andric   const Function &F = MF.getFunction();
13101095a5dSDimitry Andric 
132eb11fae6SDimitry Andric   PhysicalRegisterUsageInfo &PRUI = getAnalysis<PhysicalRegisterUsageInfo>();
133eb11fae6SDimitry Andric   PRUI.setTargetMachine(TM);
13401095a5dSDimitry Andric 
135eb11fae6SDimitry Andric   LLVM_DEBUG(dbgs() << "Clobbered Registers: ");
13601095a5dSDimitry Andric 
137eb11fae6SDimitry Andric   BitVector SavedRegs;
138eb11fae6SDimitry Andric   computeCalleeSavedRegs(SavedRegs, MF);
13901095a5dSDimitry Andric 
14071d5a254SDimitry Andric   const BitVector &UsedPhysRegsMask = MRI->getUsedPhysRegsMask();
14171d5a254SDimitry Andric   auto SetRegAsDefined = [&RegMask] (unsigned Reg) {
14271d5a254SDimitry Andric     RegMask[Reg / 32] &= ~(1u << Reg % 32);
14371d5a254SDimitry Andric   };
1441d5ae102SDimitry Andric 
145ac9a064cSDimitry Andric   // Don't include $noreg in any regmasks.
146ac9a064cSDimitry Andric   SetRegAsDefined(MCRegister::NoRegister);
147ac9a064cSDimitry Andric 
1481d5ae102SDimitry Andric   // Some targets can clobber registers "inside" a call, typically in
1491d5ae102SDimitry Andric   // linker-generated code.
1501d5ae102SDimitry Andric   for (const MCPhysReg Reg : TRI->getIntraCallClobberedRegs(&MF))
1511d5ae102SDimitry Andric     for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
1521d5ae102SDimitry Andric       SetRegAsDefined(*AI);
1531d5ae102SDimitry Andric 
15471d5a254SDimitry Andric   // Scan all the physical registers. When a register is defined in the current
15571d5a254SDimitry Andric   // function set it and all the aliasing registers as defined in the regmask.
156e6d15924SDimitry Andric   // FIXME: Rewrite to use regunits.
15771d5a254SDimitry Andric   for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) {
158eb11fae6SDimitry Andric     // Don't count registers that are saved and restored.
159eb11fae6SDimitry Andric     if (SavedRegs.test(PReg))
16071d5a254SDimitry Andric       continue;
16171d5a254SDimitry Andric     // If a register is defined by an instruction mark it as defined together
162eb11fae6SDimitry Andric     // with all it's unsaved aliases.
16371d5a254SDimitry Andric     if (!MRI->def_empty(PReg)) {
16471d5a254SDimitry Andric       for (MCRegAliasIterator AI(PReg, TRI, true); AI.isValid(); ++AI)
165eb11fae6SDimitry Andric         if (!SavedRegs.test(*AI))
16671d5a254SDimitry Andric           SetRegAsDefined(*AI);
167eb11fae6SDimitry Andric       continue;
16871d5a254SDimitry Andric     }
169eb11fae6SDimitry Andric     // If a register is in the UsedPhysRegsMask set then mark it as defined.
170eb11fae6SDimitry Andric     // All clobbered aliases will also be in the set, so we can skip setting
171eb11fae6SDimitry Andric     // as defined all the aliases here.
172eb11fae6SDimitry Andric     if (UsedPhysRegsMask.test(PReg))
173eb11fae6SDimitry Andric       SetRegAsDefined(PReg);
17471d5a254SDimitry Andric   }
17501095a5dSDimitry Andric 
1761d5ae102SDimitry Andric   if (TargetFrameLowering::isSafeForNoCSROpt(F) &&
1771d5ae102SDimitry Andric       MF.getSubtarget().getFrameLowering()->isProfitableForNoCSROpt(F)) {
17801095a5dSDimitry Andric     ++NumCSROpt;
179eb11fae6SDimitry Andric     LLVM_DEBUG(dbgs() << MF.getName()
18001095a5dSDimitry Andric                       << " function optimized for not having CSR.\n");
18101095a5dSDimitry Andric   }
18201095a5dSDimitry Andric 
183e6d15924SDimitry Andric   LLVM_DEBUG(
184e6d15924SDimitry Andric     for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) {
18501095a5dSDimitry Andric       if (MachineOperand::clobbersPhysReg(&(RegMask[0]), PReg))
186e6d15924SDimitry Andric         dbgs() << printReg(PReg, TRI) << " ";
187e6d15924SDimitry Andric     }
18801095a5dSDimitry Andric 
189e6d15924SDimitry Andric     dbgs() << " \n----------------------------------------\n";
190e6d15924SDimitry Andric   );
19101095a5dSDimitry Andric 
192eb11fae6SDimitry Andric   PRUI.storeUpdateRegUsageInfo(F, RegMask);
19301095a5dSDimitry Andric 
19401095a5dSDimitry Andric   return false;
19501095a5dSDimitry Andric }
196eb11fae6SDimitry Andric 
197eb11fae6SDimitry Andric void RegUsageInfoCollector::
computeCalleeSavedRegs(BitVector & SavedRegs,MachineFunction & MF)198eb11fae6SDimitry Andric computeCalleeSavedRegs(BitVector &SavedRegs, MachineFunction &MF) {
199eb11fae6SDimitry Andric   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
200eb11fae6SDimitry Andric   const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
201eb11fae6SDimitry Andric 
202eb11fae6SDimitry Andric   // Target will return the set of registers that it saves/restores as needed.
203eb11fae6SDimitry Andric   SavedRegs.clear();
204706b4fc4SDimitry Andric   TFI.getCalleeSaves(MF, SavedRegs);
205e6d15924SDimitry Andric   if (SavedRegs.none())
206e6d15924SDimitry Andric     return;
207eb11fae6SDimitry Andric 
208eb11fae6SDimitry Andric   // Insert subregs.
209eb11fae6SDimitry Andric   const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF);
210eb11fae6SDimitry Andric   for (unsigned i = 0; CSRegs[i]; ++i) {
211e6d15924SDimitry Andric     MCPhysReg Reg = CSRegs[i];
212e6d15924SDimitry Andric     if (SavedRegs.test(Reg)) {
213e6d15924SDimitry Andric       // Save subregisters
2147fa27ce4SDimitry Andric       for (MCPhysReg SR : TRI.subregs(Reg))
2157fa27ce4SDimitry Andric         SavedRegs.set(SR);
216eb11fae6SDimitry Andric     }
217eb11fae6SDimitry Andric   }
218d8e91e46SDimitry Andric }
219