xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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