1321369Sdim//===- RegisterUsageInfo.cpp - Register Usage Information Storage ---------===//
2303231Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6303231Sdim//
7303231Sdim//===----------------------------------------------------------------------===//
8303231Sdim///
9303231Sdim/// This pass is required to take advantage of the interprocedural register
10303231Sdim/// allocation infrastructure.
11303231Sdim///
12303231Sdim//===----------------------------------------------------------------------===//
13303231Sdim
14327952Sdim#include "llvm/CodeGen/RegisterUsageInfo.h"
15321369Sdim#include "llvm/ADT/SmallVector.h"
16303231Sdim#include "llvm/CodeGen/MachineOperand.h"
17327952Sdim#include "llvm/CodeGen/TargetRegisterInfo.h"
18327952Sdim#include "llvm/CodeGen/TargetSubtargetInfo.h"
19321369Sdim#include "llvm/IR/Function.h"
20303231Sdim#include "llvm/IR/Module.h"
21321369Sdim#include "llvm/Pass.h"
22321369Sdim#include "llvm/Support/CommandLine.h"
23303231Sdim#include "llvm/Support/raw_ostream.h"
24321369Sdim#include "llvm/Target/TargetMachine.h"
25321369Sdim#include <algorithm>
26321369Sdim#include <cassert>
27321369Sdim#include <cstdint>
28321369Sdim#include <utility>
29321369Sdim#include <vector>
30303231Sdim
31303231Sdimusing namespace llvm;
32303231Sdim
33314564Sdimstatic cl::opt<bool> DumpRegUsage(
34303231Sdim    "print-regusage", cl::init(false), cl::Hidden,
35303231Sdim    cl::desc("print register usage details collected for analysis."));
36303231Sdim
37303231SdimINITIALIZE_PASS(PhysicalRegisterUsageInfo, "reg-usage-info",
38321369Sdim                "Register Usage Information Storage", false, true)
39303231Sdim
40303231Sdimchar PhysicalRegisterUsageInfo::ID = 0;
41303231Sdim
42344779Sdimvoid PhysicalRegisterUsageInfo::setTargetMachine(const LLVMTargetMachine &TM) {
43341825Sdim  this->TM = &TM;
44341825Sdim}
45303231Sdim
46303231Sdimbool PhysicalRegisterUsageInfo::doInitialization(Module &M) {
47303231Sdim  RegMasks.grow(M.size());
48303231Sdim  return false;
49303231Sdim}
50303231Sdim
51303231Sdimbool PhysicalRegisterUsageInfo::doFinalization(Module &M) {
52303231Sdim  if (DumpRegUsage)
53303231Sdim    print(errs());
54303231Sdim
55303231Sdim  RegMasks.shrink_and_clear();
56303231Sdim  return false;
57303231Sdim}
58303231Sdim
59303231Sdimvoid PhysicalRegisterUsageInfo::storeUpdateRegUsageInfo(
60341825Sdim    const Function &FP, ArrayRef<uint32_t> RegMask) {
61341825Sdim  RegMasks[&FP] = RegMask;
62303231Sdim}
63303231Sdim
64341825SdimArrayRef<uint32_t>
65341825SdimPhysicalRegisterUsageInfo::getRegUsageInfo(const Function &FP) {
66341825Sdim  auto It = RegMasks.find(&FP);
67303231Sdim  if (It != RegMasks.end())
68341825Sdim    return makeArrayRef<uint32_t>(It->second);
69341825Sdim  return ArrayRef<uint32_t>();
70303231Sdim}
71303231Sdim
72303231Sdimvoid PhysicalRegisterUsageInfo::print(raw_ostream &OS, const Module *M) const {
73321369Sdim  using FuncPtrRegMaskPair = std::pair<const Function *, std::vector<uint32_t>>;
74303231Sdim
75303231Sdim  SmallVector<const FuncPtrRegMaskPair *, 64> FPRMPairVector;
76303231Sdim
77303231Sdim  // Create a vector of pointer to RegMasks entries
78303231Sdim  for (const auto &RegMask : RegMasks)
79303231Sdim    FPRMPairVector.push_back(&RegMask);
80303231Sdim
81303231Sdim  // sort the vector to print analysis in alphabatic order of function name.
82341825Sdim  llvm::sort(
83344779Sdim      FPRMPairVector,
84303231Sdim      [](const FuncPtrRegMaskPair *A, const FuncPtrRegMaskPair *B) -> bool {
85303231Sdim        return A->first->getName() < B->first->getName();
86303231Sdim      });
87303231Sdim
88303231Sdim  for (const FuncPtrRegMaskPair *FPRMPair : FPRMPairVector) {
89303231Sdim    OS << FPRMPair->first->getName() << " "
90303231Sdim       << "Clobbered Registers: ";
91341825Sdim    const TargetRegisterInfo *TRI
92341825Sdim        = TM->getSubtarget<TargetSubtargetInfo>(*(FPRMPair->first))
93341825Sdim          .getRegisterInfo();
94303231Sdim
95303231Sdim    for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) {
96303231Sdim      if (MachineOperand::clobbersPhysReg(&(FPRMPair->second[0]), PReg))
97327952Sdim        OS << printReg(PReg, TRI) << " ";
98303231Sdim    }
99303231Sdim    OS << "\n";
100303231Sdim  }
101303231Sdim}
102