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