xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/RegisterUsageInfo.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1  //===- RegisterUsageInfo.cpp - Register Usage Information Storage ---------===//
2  //
3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4  // See https://llvm.org/LICENSE.txt for license information.
5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6  //
7  //===----------------------------------------------------------------------===//
8  ///
9  /// This pass is required to take advantage of the interprocedural register
10  /// allocation infrastructure.
11  ///
12  //===----------------------------------------------------------------------===//
13  
14  #include "llvm/CodeGen/RegisterUsageInfo.h"
15  #include "llvm/ADT/SmallVector.h"
16  #include "llvm/CodeGen/MachineOperand.h"
17  #include "llvm/CodeGen/TargetRegisterInfo.h"
18  #include "llvm/CodeGen/TargetSubtargetInfo.h"
19  #include "llvm/IR/Function.h"
20  #include "llvm/IR/Module.h"
21  #include "llvm/Pass.h"
22  #include "llvm/Support/CommandLine.h"
23  #include "llvm/Support/raw_ostream.h"
24  #include "llvm/Target/TargetMachine.h"
25  #include <cstdint>
26  #include <utility>
27  #include <vector>
28  
29  using namespace llvm;
30  
31  static cl::opt<bool> DumpRegUsage(
32      "print-regusage", cl::init(false), cl::Hidden,
33      cl::desc("print register usage details collected for analysis."));
34  
35  INITIALIZE_PASS(PhysicalRegisterUsageInfo, "reg-usage-info",
36                  "Register Usage Information Storage", false, true)
37  
38  char PhysicalRegisterUsageInfo::ID = 0;
39  
setTargetMachine(const LLVMTargetMachine & TM)40  void PhysicalRegisterUsageInfo::setTargetMachine(const LLVMTargetMachine &TM) {
41    this->TM = &TM;
42  }
43  
doInitialization(Module & M)44  bool PhysicalRegisterUsageInfo::doInitialization(Module &M) {
45    RegMasks.grow(M.size());
46    return false;
47  }
48  
doFinalization(Module & M)49  bool PhysicalRegisterUsageInfo::doFinalization(Module &M) {
50    if (DumpRegUsage)
51      print(errs());
52  
53    RegMasks.shrink_and_clear();
54    return false;
55  }
56  
storeUpdateRegUsageInfo(const Function & FP,ArrayRef<uint32_t> RegMask)57  void PhysicalRegisterUsageInfo::storeUpdateRegUsageInfo(
58      const Function &FP, ArrayRef<uint32_t> RegMask) {
59    RegMasks[&FP] = RegMask;
60  }
61  
62  ArrayRef<uint32_t>
getRegUsageInfo(const Function & FP)63  PhysicalRegisterUsageInfo::getRegUsageInfo(const Function &FP) {
64    auto It = RegMasks.find(&FP);
65    if (It != RegMasks.end())
66      return ArrayRef<uint32_t>(It->second);
67    return ArrayRef<uint32_t>();
68  }
69  
print(raw_ostream & OS,const Module * M) const70  void PhysicalRegisterUsageInfo::print(raw_ostream &OS, const Module *M) const {
71    using FuncPtrRegMaskPair = std::pair<const Function *, std::vector<uint32_t>>;
72  
73    SmallVector<const FuncPtrRegMaskPair *, 64> FPRMPairVector;
74  
75    // Create a vector of pointer to RegMasks entries
76    for (const auto &RegMask : RegMasks)
77      FPRMPairVector.push_back(&RegMask);
78  
79    // sort the vector to print analysis in alphabatic order of function name.
80    llvm::sort(
81        FPRMPairVector,
82        [](const FuncPtrRegMaskPair *A, const FuncPtrRegMaskPair *B) -> bool {
83          return A->first->getName() < B->first->getName();
84        });
85  
86    for (const FuncPtrRegMaskPair *FPRMPair : FPRMPairVector) {
87      OS << FPRMPair->first->getName() << " "
88         << "Clobbered Registers: ";
89      const TargetRegisterInfo *TRI
90          = TM->getSubtarget<TargetSubtargetInfo>(*(FPRMPair->first))
91            .getRegisterInfo();
92  
93      for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) {
94        if (MachineOperand::clobbersPhysReg(&(FPRMPair->second[0]), PReg))
95          OS << printReg(PReg, TRI) << " ";
96      }
97      OS << "\n";
98    }
99  }
100