Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUAnnotateKernelFeatures.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- AMDGPUAnnotateKernelFeaturesPass.cpp -------------------------------===//
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
/// \file This pass propagates the uniform-work-group-size attribute from
10
/// kernels to leaf functions when possible. It also adds additional attributes
11
/// to hint ABI lowering optimizations later.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "AMDGPU.h"
16
#include "GCNSubtarget.h"
17
#include "llvm/Analysis/CallGraph.h"
18
#include "llvm/Analysis/CallGraphSCCPass.h"
19
#include "llvm/CodeGen/TargetPassConfig.h"
20
#include "llvm/IR/IntrinsicsAMDGPU.h"
21
#include "llvm/IR/IntrinsicsR600.h"
22
#include "llvm/Target/TargetMachine.h"
23
24
#define DEBUG_TYPE "amdgpu-annotate-kernel-features"
25
26
using namespace llvm;
27
28
namespace {
29
class AMDGPUAnnotateKernelFeatures : public CallGraphSCCPass {
30
private:
31
  const TargetMachine *TM = nullptr;
32
33
  bool addFeatureAttributes(Function &F);
34
35
public:
36
  static char ID;
37
38
0
  AMDGPUAnnotateKernelFeatures() : CallGraphSCCPass(ID) {}
39
40
  bool doInitialization(CallGraph &CG) override;
41
  bool runOnSCC(CallGraphSCC &SCC) override;
42
43
0
  StringRef getPassName() const override {
44
0
    return "AMDGPU Annotate Kernel Features";
45
0
  }
46
47
0
  void getAnalysisUsage(AnalysisUsage &AU) const override {
48
0
    AU.setPreservesAll();
49
0
    CallGraphSCCPass::getAnalysisUsage(AU);
50
0
  }
51
};
52
53
} // end anonymous namespace
54
55
char AMDGPUAnnotateKernelFeatures::ID = 0;
56
57
char &llvm::AMDGPUAnnotateKernelFeaturesID = AMDGPUAnnotateKernelFeatures::ID;
58
59
INITIALIZE_PASS(AMDGPUAnnotateKernelFeatures, DEBUG_TYPE,
60
                "Add AMDGPU function attributes", false, false)
61
62
0
bool AMDGPUAnnotateKernelFeatures::addFeatureAttributes(Function &F) {
63
0
  bool HaveStackObjects = false;
64
0
  bool Changed = false;
65
0
  bool HaveCall = false;
66
0
  bool IsFunc = !AMDGPU::isEntryFunctionCC(F.getCallingConv());
67
68
0
  for (BasicBlock &BB : F) {
69
0
    for (Instruction &I : BB) {
70
0
      if (isa<AllocaInst>(I)) {
71
0
        HaveStackObjects = true;
72
0
        continue;
73
0
      }
74
75
0
      if (auto *CB = dyn_cast<CallBase>(&I)) {
76
0
        const Function *Callee =
77
0
            dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
78
79
        // Note the occurrence of indirect call.
80
0
        if (!Callee) {
81
0
          if (!CB->isInlineAsm())
82
0
            HaveCall = true;
83
84
0
          continue;
85
0
        }
86
87
0
        Intrinsic::ID IID = Callee->getIntrinsicID();
88
0
        if (IID == Intrinsic::not_intrinsic) {
89
0
          HaveCall = true;
90
0
          Changed = true;
91
0
        }
92
0
      }
93
0
    }
94
0
  }
95
96
  // TODO: We could refine this to captured pointers that could possibly be
97
  // accessed by flat instructions. For now this is mostly a poor way of
98
  // estimating whether there are calls before argument lowering.
99
0
  if (!IsFunc && HaveCall) {
100
0
    F.addFnAttr("amdgpu-calls");
101
0
    Changed = true;
102
0
  }
103
104
0
  if (HaveStackObjects) {
105
0
    F.addFnAttr("amdgpu-stack-objects");
106
0
    Changed = true;
107
0
  }
108
109
0
  return Changed;
110
0
}
111
112
0
bool AMDGPUAnnotateKernelFeatures::runOnSCC(CallGraphSCC &SCC) {
113
0
  bool Changed = false;
114
115
0
  for (CallGraphNode *I : SCC) {
116
0
    Function *F = I->getFunction();
117
    // Ignore functions with graphics calling conventions, these are currently
118
    // not allowed to have kernel arguments.
119
0
    if (!F || F->isDeclaration() || AMDGPU::isGraphics(F->getCallingConv()))
120
0
      continue;
121
    // Add feature attributes
122
0
    Changed |= addFeatureAttributes(*F);
123
0
  }
124
125
0
  return Changed;
126
0
}
127
128
0
bool AMDGPUAnnotateKernelFeatures::doInitialization(CallGraph &CG) {
129
0
  auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
130
0
  if (!TPC)
131
0
    report_fatal_error("TargetMachine is required");
132
133
0
  TM = &TPC->getTM<TargetMachine>();
134
0
  return false;
135
0
}
136
137
0
Pass *llvm::createAMDGPUAnnotateKernelFeaturesPass() {
138
0
  return new AMDGPUAnnotateKernelFeatures();
139
0
}