xref: /src/contrib/llvm-project/llvm/lib/CodeGen/RegisterUsageInfo.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
108bbd35aSDimitry Andric //===- RegisterUsageInfo.cpp - Register Usage Information Storage ---------===//
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 //===----------------------------------------------------------------------===//
1301095a5dSDimitry Andric 
1401095a5dSDimitry Andric #include "llvm/CodeGen/RegisterUsageInfo.h"
15044eb2f6SDimitry Andric #include "llvm/ADT/SmallVector.h"
1601095a5dSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
17044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
18044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
197ab83427SDimitry Andric #include "llvm/IR/Function.h"
2001095a5dSDimitry Andric #include "llvm/IR/Module.h"
217ab83427SDimitry Andric #include "llvm/Pass.h"
227ab83427SDimitry Andric #include "llvm/Support/CommandLine.h"
2301095a5dSDimitry Andric #include "llvm/Support/raw_ostream.h"
247ab83427SDimitry Andric #include "llvm/Target/TargetMachine.h"
257ab83427SDimitry Andric #include <cstdint>
267ab83427SDimitry Andric #include <utility>
277ab83427SDimitry Andric #include <vector>
2801095a5dSDimitry Andric 
2901095a5dSDimitry Andric using namespace llvm;
3001095a5dSDimitry Andric 
31b915e9e0SDimitry Andric static cl::opt<bool> DumpRegUsage(
3201095a5dSDimitry Andric     "print-regusage", cl::init(false), cl::Hidden,
3301095a5dSDimitry Andric     cl::desc("print register usage details collected for analysis."));
3401095a5dSDimitry Andric 
3501095a5dSDimitry Andric INITIALIZE_PASS(PhysicalRegisterUsageInfo, "reg-usage-info",
3608bbd35aSDimitry Andric                 "Register Usage Information Storage", false, true)
3701095a5dSDimitry Andric 
3801095a5dSDimitry Andric char PhysicalRegisterUsageInfo::ID = 0;
3901095a5dSDimitry Andric 
setTargetMachine(const LLVMTargetMachine & TM)40d8e91e46SDimitry Andric void PhysicalRegisterUsageInfo::setTargetMachine(const LLVMTargetMachine &TM) {
41eb11fae6SDimitry Andric   this->TM = &TM;
42eb11fae6SDimitry Andric }
4301095a5dSDimitry Andric 
doInitialization(Module & M)4401095a5dSDimitry Andric bool PhysicalRegisterUsageInfo::doInitialization(Module &M) {
4501095a5dSDimitry Andric   RegMasks.grow(M.size());
4601095a5dSDimitry Andric   return false;
4701095a5dSDimitry Andric }
4801095a5dSDimitry Andric 
doFinalization(Module & M)4901095a5dSDimitry Andric bool PhysicalRegisterUsageInfo::doFinalization(Module &M) {
5001095a5dSDimitry Andric   if (DumpRegUsage)
5101095a5dSDimitry Andric     print(errs());
5201095a5dSDimitry Andric 
5301095a5dSDimitry Andric   RegMasks.shrink_and_clear();
5401095a5dSDimitry Andric   return false;
5501095a5dSDimitry Andric }
5601095a5dSDimitry Andric 
storeUpdateRegUsageInfo(const Function & FP,ArrayRef<uint32_t> RegMask)5701095a5dSDimitry Andric void PhysicalRegisterUsageInfo::storeUpdateRegUsageInfo(
58eb11fae6SDimitry Andric     const Function &FP, ArrayRef<uint32_t> RegMask) {
59eb11fae6SDimitry Andric   RegMasks[&FP] = RegMask;
6001095a5dSDimitry Andric }
6101095a5dSDimitry Andric 
62eb11fae6SDimitry Andric ArrayRef<uint32_t>
getRegUsageInfo(const Function & FP)63eb11fae6SDimitry Andric PhysicalRegisterUsageInfo::getRegUsageInfo(const Function &FP) {
64eb11fae6SDimitry Andric   auto It = RegMasks.find(&FP);
6501095a5dSDimitry Andric   if (It != RegMasks.end())
66e3b55780SDimitry Andric     return ArrayRef<uint32_t>(It->second);
67eb11fae6SDimitry Andric   return ArrayRef<uint32_t>();
6801095a5dSDimitry Andric }
6901095a5dSDimitry Andric 
print(raw_ostream & OS,const Module * M) const7001095a5dSDimitry Andric void PhysicalRegisterUsageInfo::print(raw_ostream &OS, const Module *M) const {
717ab83427SDimitry Andric   using FuncPtrRegMaskPair = std::pair<const Function *, std::vector<uint32_t>>;
7201095a5dSDimitry Andric 
7301095a5dSDimitry Andric   SmallVector<const FuncPtrRegMaskPair *, 64> FPRMPairVector;
7401095a5dSDimitry Andric 
7501095a5dSDimitry Andric   // Create a vector of pointer to RegMasks entries
7601095a5dSDimitry Andric   for (const auto &RegMask : RegMasks)
7701095a5dSDimitry Andric     FPRMPairVector.push_back(&RegMask);
7801095a5dSDimitry Andric 
7901095a5dSDimitry Andric   // sort the vector to print analysis in alphabatic order of function name.
80eb11fae6SDimitry Andric   llvm::sort(
81d8e91e46SDimitry Andric       FPRMPairVector,
8201095a5dSDimitry Andric       [](const FuncPtrRegMaskPair *A, const FuncPtrRegMaskPair *B) -> bool {
8301095a5dSDimitry Andric         return A->first->getName() < B->first->getName();
8401095a5dSDimitry Andric       });
8501095a5dSDimitry Andric 
8601095a5dSDimitry Andric   for (const FuncPtrRegMaskPair *FPRMPair : FPRMPairVector) {
8701095a5dSDimitry Andric     OS << FPRMPair->first->getName() << " "
8801095a5dSDimitry Andric        << "Clobbered Registers: ";
89eb11fae6SDimitry Andric     const TargetRegisterInfo *TRI
90eb11fae6SDimitry Andric         = TM->getSubtarget<TargetSubtargetInfo>(*(FPRMPair->first))
9101095a5dSDimitry Andric           .getRegisterInfo();
9201095a5dSDimitry Andric 
9301095a5dSDimitry Andric     for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) {
9401095a5dSDimitry Andric       if (MachineOperand::clobbersPhysReg(&(FPRMPair->second[0]), PReg))
95044eb2f6SDimitry Andric         OS << printReg(PReg, TRI) << " ";
9601095a5dSDimitry Andric     }
9701095a5dSDimitry Andric     OS << "\n";
9801095a5dSDimitry Andric   }
9901095a5dSDimitry Andric }
100