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/Analysis.h" 20 #include "llvm/IR/Function.h" 21 #include "llvm/IR/Module.h" 22 #include "llvm/IR/PassManager.h" 23 #include "llvm/Pass.h" 24 #include "llvm/Support/CommandLine.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include "llvm/Target/TargetMachine.h" 27 #include <cstdint> 28 #include <utility> 29 #include <vector> 30 31 using namespace llvm; 32 33 static cl::opt<bool> DumpRegUsage( 34 "print-regusage", cl::init(false), cl::Hidden, 35 cl::desc("print register usage details collected for analysis.")); 36 37 INITIALIZE_PASS(PhysicalRegisterUsageInfoWrapperLegacy, "reg-usage-info", 38 "Register Usage Information Storage", false, true) 39 40 char PhysicalRegisterUsageInfoWrapperLegacy::ID = 0; 41 42 void PhysicalRegisterUsageInfo::setTargetMachine(const TargetMachine &TM) { 43 this->TM = &TM; 44 } 45 46 bool PhysicalRegisterUsageInfo::doInitialization(Module &M) { 47 RegMasks.grow(M.size()); 48 return false; 49 } 50 51 bool PhysicalRegisterUsageInfo::doFinalization(Module &M) { 52 if (DumpRegUsage) 53 print(errs()); 54 55 RegMasks.shrink_and_clear(); 56 return false; 57 } 58 59 void PhysicalRegisterUsageInfo::storeUpdateRegUsageInfo( 60 const Function &FP, ArrayRef<uint32_t> RegMask) { 61 RegMasks[&FP] = RegMask; 62 } 63 64 ArrayRef<uint32_t> 65 PhysicalRegisterUsageInfo::getRegUsageInfo(const Function &FP) { 66 auto It = RegMasks.find(&FP); 67 if (It != RegMasks.end()) 68 return ArrayRef<uint32_t>(It->second); 69 return ArrayRef<uint32_t>(); 70 } 71 72 void PhysicalRegisterUsageInfo::print(raw_ostream &OS, const Module *M) const { 73 using FuncPtrRegMaskPair = std::pair<const Function *, std::vector<uint32_t>>; 74 75 // Create a vector of pointer to RegMasks entries 76 SmallVector<const FuncPtrRegMaskPair *, 64> FPRMPairVector( 77 llvm::make_pointer_range(RegMasks)); 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 101 bool PhysicalRegisterUsageInfo::invalidate( 102 Module &M, const PreservedAnalyses &PA, 103 ModuleAnalysisManager::Invalidator &) { 104 auto PAC = PA.getChecker<PhysicalRegisterUsageAnalysis>(); 105 return !PAC.preservedWhenStateless(); 106 } 107 108 AnalysisKey PhysicalRegisterUsageAnalysis::Key; 109 PhysicalRegisterUsageInfo 110 PhysicalRegisterUsageAnalysis::run(Module &M, ModuleAnalysisManager &) { 111 PhysicalRegisterUsageInfo PRUI; 112 PRUI.doInitialization(M); 113 return PRUI; 114 } 115 116 PreservedAnalyses 117 PhysicalRegisterUsageInfoPrinterPass::run(Module &M, 118 ModuleAnalysisManager &AM) { 119 auto *PRUI = &AM.getResult<PhysicalRegisterUsageAnalysis>(M); 120 PRUI->print(OS, &M); 121 return PreservedAnalyses::all(); 122 } 123