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