1f5d61d79SMatt Arsenault //===- RegisterUsageInfo.cpp - Register Usage Information Storage ---------===//
2bbacddfeSMehdi Amini //
3bbacddfeSMehdi Amini //                     The LLVM Compiler Infrastructure
4bbacddfeSMehdi Amini //
5bbacddfeSMehdi Amini // This file is distributed under the University of Illinois Open Source
6bbacddfeSMehdi Amini // License. See LICENSE.TXT for details.
7bbacddfeSMehdi Amini //
8bbacddfeSMehdi Amini //===----------------------------------------------------------------------===//
9bbacddfeSMehdi Amini ///
10bbacddfeSMehdi Amini /// This pass is required to take advantage of the interprocedural register
11bbacddfeSMehdi Amini /// allocation infrastructure.
12bbacddfeSMehdi Amini ///
13bbacddfeSMehdi Amini //===----------------------------------------------------------------------===//
14bbacddfeSMehdi Amini 
15bbacddfeSMehdi Amini #include "llvm/CodeGen/RegisterUsageInfo.h"
16*b3bde2eaSDavid Blaikie #include "llvm/ADT/SmallVector.h"
17bbacddfeSMehdi Amini #include "llvm/CodeGen/MachineOperand.h"
18*b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
19*b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h"
20fb69e66cSEugene Zelenko #include "llvm/IR/Function.h"
21bbacddfeSMehdi Amini #include "llvm/IR/Module.h"
22fb69e66cSEugene Zelenko #include "llvm/Pass.h"
23fb69e66cSEugene Zelenko #include "llvm/Support/CommandLine.h"
24bbacddfeSMehdi Amini #include "llvm/Support/raw_ostream.h"
25fb69e66cSEugene Zelenko #include "llvm/Target/TargetMachine.h"
26fb69e66cSEugene Zelenko #include <algorithm>
27fb69e66cSEugene Zelenko #include <cassert>
28fb69e66cSEugene Zelenko #include <cstdint>
29fb69e66cSEugene Zelenko #include <utility>
30fb69e66cSEugene Zelenko #include <vector>
31bbacddfeSMehdi Amini 
32bbacddfeSMehdi Amini using namespace llvm;
33bbacddfeSMehdi Amini 
34bbacddfeSMehdi Amini #define DEBUG_TYPE "ip-regalloc"
35bbacddfeSMehdi Amini 
36b7d3311cSBenjamin Kramer static cl::opt<bool> DumpRegUsage(
37bbacddfeSMehdi Amini     "print-regusage", cl::init(false), cl::Hidden,
38bbacddfeSMehdi Amini     cl::desc("print register usage details collected for analysis."));
39bbacddfeSMehdi Amini 
40bbacddfeSMehdi Amini INITIALIZE_PASS(PhysicalRegisterUsageInfo, "reg-usage-info",
41f5d61d79SMatt Arsenault                 "Register Usage Information Storage", false, true)
42bbacddfeSMehdi Amini 
43bbacddfeSMehdi Amini char PhysicalRegisterUsageInfo::ID = 0;
44bbacddfeSMehdi Amini 
45bbacddfeSMehdi Amini void PhysicalRegisterUsageInfo::anchor() {}
46bbacddfeSMehdi Amini 
47bbacddfeSMehdi Amini bool PhysicalRegisterUsageInfo::doInitialization(Module &M) {
48bbacddfeSMehdi Amini   RegMasks.grow(M.size());
49bbacddfeSMehdi Amini   return false;
50bbacddfeSMehdi Amini }
51bbacddfeSMehdi Amini 
52bbacddfeSMehdi Amini bool PhysicalRegisterUsageInfo::doFinalization(Module &M) {
53bbacddfeSMehdi Amini   if (DumpRegUsage)
54bbacddfeSMehdi Amini     print(errs());
55bbacddfeSMehdi Amini 
56bbacddfeSMehdi Amini   RegMasks.shrink_and_clear();
57bbacddfeSMehdi Amini   return false;
58bbacddfeSMehdi Amini }
59bbacddfeSMehdi Amini 
60bbacddfeSMehdi Amini void PhysicalRegisterUsageInfo::storeUpdateRegUsageInfo(
61bbacddfeSMehdi Amini     const Function *FP, std::vector<uint32_t> RegMask) {
62bbacddfeSMehdi Amini   assert(FP != nullptr && "Function * can't be nullptr.");
63bbacddfeSMehdi Amini   RegMasks[FP] = std::move(RegMask);
64bbacddfeSMehdi Amini }
65bbacddfeSMehdi Amini 
66bbacddfeSMehdi Amini const std::vector<uint32_t> *
67bbacddfeSMehdi Amini PhysicalRegisterUsageInfo::getRegUsageInfo(const Function *FP) {
68e203b610SMehdi Amini   auto It = RegMasks.find(FP);
69e203b610SMehdi Amini   if (It != RegMasks.end())
70e203b610SMehdi Amini     return &(It->second);
71bbacddfeSMehdi Amini   return nullptr;
72bbacddfeSMehdi Amini }
73bbacddfeSMehdi Amini 
74bbacddfeSMehdi Amini void PhysicalRegisterUsageInfo::print(raw_ostream &OS, const Module *M) const {
75bbacddfeSMehdi Amini   const TargetRegisterInfo *TRI;
76bbacddfeSMehdi Amini 
77fb69e66cSEugene Zelenko   using FuncPtrRegMaskPair = std::pair<const Function *, std::vector<uint32_t>>;
78bbacddfeSMehdi Amini 
79bbacddfeSMehdi Amini   SmallVector<const FuncPtrRegMaskPair *, 64> FPRMPairVector;
80bbacddfeSMehdi Amini 
81bbacddfeSMehdi Amini   // Create a vector of pointer to RegMasks entries
82bbacddfeSMehdi Amini   for (const auto &RegMask : RegMasks)
83bbacddfeSMehdi Amini     FPRMPairVector.push_back(&RegMask);
84bbacddfeSMehdi Amini 
85bbacddfeSMehdi Amini   // sort the vector to print analysis in alphabatic order of function name.
86bbacddfeSMehdi Amini   std::sort(
87bbacddfeSMehdi Amini       FPRMPairVector.begin(), FPRMPairVector.end(),
88bbacddfeSMehdi Amini       [](const FuncPtrRegMaskPair *A, const FuncPtrRegMaskPair *B) -> bool {
89bbacddfeSMehdi Amini         return A->first->getName() < B->first->getName();
90bbacddfeSMehdi Amini       });
91bbacddfeSMehdi Amini 
92bbacddfeSMehdi Amini   for (const FuncPtrRegMaskPair *FPRMPair : FPRMPairVector) {
93bbacddfeSMehdi Amini     OS << FPRMPair->first->getName() << " "
94bbacddfeSMehdi Amini        << "Clobbered Registers: ";
95bbacddfeSMehdi Amini     TRI = TM->getSubtarget<TargetSubtargetInfo>(*(FPRMPair->first))
96bbacddfeSMehdi Amini               .getRegisterInfo();
97bbacddfeSMehdi Amini 
98bbacddfeSMehdi Amini     for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) {
99bbacddfeSMehdi Amini       if (MachineOperand::clobbersPhysReg(&(FPRMPair->second[0]), PReg))
100bbacddfeSMehdi Amini         OS << TRI->getName(PReg) << " ";
101bbacddfeSMehdi Amini     }
102bbacddfeSMehdi Amini     OS << "\n";
103bbacddfeSMehdi Amini   }
104bbacddfeSMehdi Amini }
105