1fe6060f1SDimitry Andric //===- AMDGPUResourceUsageAnalysis.h ---- analysis of resources -*- C++ -*-===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric // 9fe6060f1SDimitry Andric /// \file 10fe6060f1SDimitry Andric /// \brief Analyzes how many registers and other resources are used by 11fe6060f1SDimitry Andric /// functions. 12fe6060f1SDimitry Andric /// 13fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 14fe6060f1SDimitry Andric 15fe6060f1SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPURESOURCEUSAGEANALYSIS_H 16fe6060f1SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_AMDGPURESOURCEUSAGEANALYSIS_H 17fe6060f1SDimitry Andric 18fe6060f1SDimitry Andric #include "llvm/Analysis/CallGraphSCCPass.h" 19fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 20fe6060f1SDimitry Andric 21fe6060f1SDimitry Andric namespace llvm { 22fe6060f1SDimitry Andric 23fe6060f1SDimitry Andric class GCNSubtarget; 24fe6060f1SDimitry Andric class MachineFunction; 25fe6060f1SDimitry Andric class TargetMachine; 26fe6060f1SDimitry Andric 2781ad6265SDimitry Andric struct AMDGPUResourceUsageAnalysis : public ModulePass { 28fe6060f1SDimitry Andric static char ID; 29fe6060f1SDimitry Andric 30fe6060f1SDimitry Andric public: 31fe6060f1SDimitry Andric // Track resource usage for callee functions. 32fe6060f1SDimitry Andric struct SIFunctionResourceInfo { 33fe6060f1SDimitry Andric // Track the number of explicitly used VGPRs. Special registers reserved at 34fe6060f1SDimitry Andric // the end are tracked separately. 35fe6060f1SDimitry Andric int32_t NumVGPR = 0; 36fe6060f1SDimitry Andric int32_t NumAGPR = 0; 37fe6060f1SDimitry Andric int32_t NumExplicitSGPR = 0; 38fe6060f1SDimitry Andric uint64_t PrivateSegmentSize = 0; 39fe6060f1SDimitry Andric bool UsesVCC = false; 40fe6060f1SDimitry Andric bool UsesFlatScratch = false; 41fe6060f1SDimitry Andric bool HasDynamicallySizedStack = false; 42fe6060f1SDimitry Andric bool HasRecursion = false; 43fe6060f1SDimitry Andric bool HasIndirectCall = false; 44fe6060f1SDimitry Andric 45fe6060f1SDimitry Andric int32_t getTotalNumSGPRs(const GCNSubtarget &ST) const; 46349cc55cSDimitry Andric // Total number of VGPRs is actually a combination of AGPR and VGPR 47349cc55cSDimitry Andric // depending on architecture - and some alignment constraints 48349cc55cSDimitry Andric int32_t getTotalNumVGPRs(const GCNSubtarget &ST, int32_t NumAGPR, 49349cc55cSDimitry Andric int32_t NumVGPR) const; 50fe6060f1SDimitry Andric int32_t getTotalNumVGPRs(const GCNSubtarget &ST) const; 51fe6060f1SDimitry Andric }; 52fe6060f1SDimitry Andric AMDGPUResourceUsageAnalysisAMDGPUResourceUsageAnalysis5381ad6265SDimitry Andric AMDGPUResourceUsageAnalysis() : ModulePass(ID) {} 54fe6060f1SDimitry Andric doInitializationAMDGPUResourceUsageAnalysis5581ad6265SDimitry Andric bool doInitialization(Module &M) override { 56fe6060f1SDimitry Andric CallGraphResourceInfo.clear(); 5781ad6265SDimitry Andric return ModulePass::doInitialization(M); 58fe6060f1SDimitry Andric } 59fe6060f1SDimitry Andric 6081ad6265SDimitry Andric bool runOnModule(Module &M) override; 6181ad6265SDimitry Andric getAnalysisUsageAMDGPUResourceUsageAnalysis62fe6060f1SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 63fe6060f1SDimitry Andric AU.addRequired<MachineModuleInfoWrapperPass>(); 64fe6060f1SDimitry Andric AU.setPreservesAll(); 65fe6060f1SDimitry Andric } 66fe6060f1SDimitry Andric getResourceInfoAMDGPUResourceUsageAnalysis67fe6060f1SDimitry Andric const SIFunctionResourceInfo &getResourceInfo(const Function *F) const { 68fe6060f1SDimitry Andric auto Info = CallGraphResourceInfo.find(F); 69fe6060f1SDimitry Andric assert(Info != CallGraphResourceInfo.end() && 70fe6060f1SDimitry Andric "Failed to find resource info for function"); 71fe6060f1SDimitry Andric return Info->getSecond(); 72fe6060f1SDimitry Andric } 73fe6060f1SDimitry Andric 74fe6060f1SDimitry Andric private: 75*0fca6ea1SDimitry Andric SIFunctionResourceInfo 76*0fca6ea1SDimitry Andric analyzeResourceUsage(const MachineFunction &MF, const TargetMachine &TM, 77*0fca6ea1SDimitry Andric uint32_t AssumedStackSizeForDynamicSizeObjects, 78*0fca6ea1SDimitry Andric uint32_t AssumedStackSizeForExternalCall) const; 79fe6060f1SDimitry Andric void propagateIndirectCallRegisterUsage(); 80fe6060f1SDimitry Andric 81fe6060f1SDimitry Andric DenseMap<const Function *, SIFunctionResourceInfo> CallGraphResourceInfo; 82fe6060f1SDimitry Andric }; 83fe6060f1SDimitry Andric } // namespace llvm 84fe6060f1SDimitry Andric #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPURESOURCEUSAGEANALYSIS_H 85