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