1edd7eaddSDimitry Andric //===- RegisterUsageInfo.cpp - Register Usage Information Storage ---------===//
23ca95b02SDimitry Andric //
33ca95b02SDimitry Andric // The LLVM Compiler Infrastructure
43ca95b02SDimitry Andric //
53ca95b02SDimitry Andric // This file is distributed under the University of Illinois Open Source
63ca95b02SDimitry Andric // License. See LICENSE.TXT for details.
73ca95b02SDimitry Andric //
83ca95b02SDimitry Andric //===----------------------------------------------------------------------===//
93ca95b02SDimitry Andric ///
103ca95b02SDimitry Andric /// This pass is required to take advantage of the interprocedural register
113ca95b02SDimitry Andric /// allocation infrastructure.
123ca95b02SDimitry Andric ///
133ca95b02SDimitry Andric //===----------------------------------------------------------------------===//
143ca95b02SDimitry Andric
153ca95b02SDimitry Andric #include "llvm/CodeGen/RegisterUsageInfo.h"
162cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
173ca95b02SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
182cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
192cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
20db17bf38SDimitry Andric #include "llvm/IR/Function.h"
213ca95b02SDimitry Andric #include "llvm/IR/Module.h"
22db17bf38SDimitry Andric #include "llvm/Pass.h"
23db17bf38SDimitry Andric #include "llvm/Support/CommandLine.h"
243ca95b02SDimitry Andric #include "llvm/Support/raw_ostream.h"
25db17bf38SDimitry Andric #include "llvm/Target/TargetMachine.h"
26db17bf38SDimitry Andric #include <algorithm>
27db17bf38SDimitry Andric #include <cassert>
28db17bf38SDimitry Andric #include <cstdint>
29db17bf38SDimitry Andric #include <utility>
30db17bf38SDimitry Andric #include <vector>
313ca95b02SDimitry Andric
323ca95b02SDimitry Andric using namespace llvm;
333ca95b02SDimitry Andric
34d88c1a5aSDimitry Andric static cl::opt<bool> DumpRegUsage(
353ca95b02SDimitry Andric "print-regusage", cl::init(false), cl::Hidden,
363ca95b02SDimitry Andric cl::desc("print register usage details collected for analysis."));
373ca95b02SDimitry Andric
383ca95b02SDimitry Andric INITIALIZE_PASS(PhysicalRegisterUsageInfo, "reg-usage-info",
39edd7eaddSDimitry Andric "Register Usage Information Storage", false, true)
403ca95b02SDimitry Andric
413ca95b02SDimitry Andric char PhysicalRegisterUsageInfo::ID = 0;
423ca95b02SDimitry Andric
setTargetMachine(const LLVMTargetMachine & TM)43*b5893f02SDimitry Andric void PhysicalRegisterUsageInfo::setTargetMachine(const LLVMTargetMachine &TM) {
444ba319b5SDimitry Andric this->TM = &TM;
454ba319b5SDimitry Andric }
463ca95b02SDimitry Andric
doInitialization(Module & M)473ca95b02SDimitry Andric bool PhysicalRegisterUsageInfo::doInitialization(Module &M) {
483ca95b02SDimitry Andric RegMasks.grow(M.size());
493ca95b02SDimitry Andric return false;
503ca95b02SDimitry Andric }
513ca95b02SDimitry Andric
doFinalization(Module & M)523ca95b02SDimitry Andric bool PhysicalRegisterUsageInfo::doFinalization(Module &M) {
533ca95b02SDimitry Andric if (DumpRegUsage)
543ca95b02SDimitry Andric print(errs());
553ca95b02SDimitry Andric
563ca95b02SDimitry Andric RegMasks.shrink_and_clear();
573ca95b02SDimitry Andric return false;
583ca95b02SDimitry Andric }
593ca95b02SDimitry Andric
storeUpdateRegUsageInfo(const Function & FP,ArrayRef<uint32_t> RegMask)603ca95b02SDimitry Andric void PhysicalRegisterUsageInfo::storeUpdateRegUsageInfo(
614ba319b5SDimitry Andric const Function &FP, ArrayRef<uint32_t> RegMask) {
624ba319b5SDimitry Andric RegMasks[&FP] = RegMask;
633ca95b02SDimitry Andric }
643ca95b02SDimitry Andric
654ba319b5SDimitry Andric ArrayRef<uint32_t>
getRegUsageInfo(const Function & FP)664ba319b5SDimitry Andric PhysicalRegisterUsageInfo::getRegUsageInfo(const Function &FP) {
674ba319b5SDimitry Andric auto It = RegMasks.find(&FP);
683ca95b02SDimitry Andric if (It != RegMasks.end())
694ba319b5SDimitry Andric return makeArrayRef<uint32_t>(It->second);
704ba319b5SDimitry Andric return ArrayRef<uint32_t>();
713ca95b02SDimitry Andric }
723ca95b02SDimitry Andric
print(raw_ostream & OS,const Module * M) const733ca95b02SDimitry Andric void PhysicalRegisterUsageInfo::print(raw_ostream &OS, const Module *M) const {
74db17bf38SDimitry Andric using FuncPtrRegMaskPair = std::pair<const Function *, std::vector<uint32_t>>;
753ca95b02SDimitry Andric
763ca95b02SDimitry Andric SmallVector<const FuncPtrRegMaskPair *, 64> FPRMPairVector;
773ca95b02SDimitry Andric
783ca95b02SDimitry Andric // Create a vector of pointer to RegMasks entries
793ca95b02SDimitry Andric for (const auto &RegMask : RegMasks)
803ca95b02SDimitry Andric FPRMPairVector.push_back(&RegMask);
813ca95b02SDimitry Andric
823ca95b02SDimitry Andric // sort the vector to print analysis in alphabatic order of function name.
834ba319b5SDimitry Andric llvm::sort(
84*b5893f02SDimitry Andric FPRMPairVector,
853ca95b02SDimitry Andric [](const FuncPtrRegMaskPair *A, const FuncPtrRegMaskPair *B) -> bool {
863ca95b02SDimitry Andric return A->first->getName() < B->first->getName();
873ca95b02SDimitry Andric });
883ca95b02SDimitry Andric
893ca95b02SDimitry Andric for (const FuncPtrRegMaskPair *FPRMPair : FPRMPairVector) {
903ca95b02SDimitry Andric OS << FPRMPair->first->getName() << " "
913ca95b02SDimitry Andric << "Clobbered Registers: ";
924ba319b5SDimitry Andric const TargetRegisterInfo *TRI
934ba319b5SDimitry Andric = TM->getSubtarget<TargetSubtargetInfo>(*(FPRMPair->first))
943ca95b02SDimitry Andric .getRegisterInfo();
953ca95b02SDimitry Andric
963ca95b02SDimitry Andric for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) {
973ca95b02SDimitry Andric if (MachineOperand::clobbersPhysReg(&(FPRMPair->second[0]), PReg))
982cab237bSDimitry Andric OS << printReg(PReg, TRI) << " ";
993ca95b02SDimitry Andric }
1003ca95b02SDimitry Andric OS << "\n";
1013ca95b02SDimitry Andric }
1023ca95b02SDimitry Andric }
103