Path: blob/main/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUAnnotateKernelFeatures.cpp
35266 views
//===- AMDGPUAnnotateKernelFeaturesPass.cpp -------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8/// \file This pass propagates the uniform-work-group-size attribute from9/// kernels to leaf functions when possible. It also adds additional attributes10/// to hint ABI lowering optimizations later.11//12//===----------------------------------------------------------------------===//1314#include "AMDGPU.h"15#include "GCNSubtarget.h"16#include "llvm/Analysis/CallGraph.h"17#include "llvm/Analysis/CallGraphSCCPass.h"18#include "llvm/CodeGen/TargetPassConfig.h"19#include "llvm/IR/IntrinsicsAMDGPU.h"20#include "llvm/IR/IntrinsicsR600.h"21#include "llvm/Target/TargetMachine.h"2223#define DEBUG_TYPE "amdgpu-annotate-kernel-features"2425using namespace llvm;2627namespace {28class AMDGPUAnnotateKernelFeatures : public CallGraphSCCPass {29private:30const TargetMachine *TM = nullptr;3132bool addFeatureAttributes(Function &F);3334public:35static char ID;3637AMDGPUAnnotateKernelFeatures() : CallGraphSCCPass(ID) {}3839bool doInitialization(CallGraph &CG) override;40bool runOnSCC(CallGraphSCC &SCC) override;4142StringRef getPassName() const override {43return "AMDGPU Annotate Kernel Features";44}4546void getAnalysisUsage(AnalysisUsage &AU) const override {47AU.setPreservesAll();48CallGraphSCCPass::getAnalysisUsage(AU);49}50};5152} // end anonymous namespace5354char AMDGPUAnnotateKernelFeatures::ID = 0;5556char &llvm::AMDGPUAnnotateKernelFeaturesID = AMDGPUAnnotateKernelFeatures::ID;5758INITIALIZE_PASS(AMDGPUAnnotateKernelFeatures, DEBUG_TYPE,59"Add AMDGPU function attributes", false, false)6061bool AMDGPUAnnotateKernelFeatures::addFeatureAttributes(Function &F) {62bool HaveStackObjects = false;63bool Changed = false;64bool HaveCall = false;65bool IsFunc = !AMDGPU::isEntryFunctionCC(F.getCallingConv());6667for (BasicBlock &BB : F) {68for (Instruction &I : BB) {69if (isa<AllocaInst>(I)) {70HaveStackObjects = true;71continue;72}7374if (auto *CB = dyn_cast<CallBase>(&I)) {75const Function *Callee =76dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());7778// Note the occurrence of indirect call.79if (!Callee) {80if (!CB->isInlineAsm())81HaveCall = true;8283continue;84}8586Intrinsic::ID IID = Callee->getIntrinsicID();87if (IID == Intrinsic::not_intrinsic) {88HaveCall = true;89Changed = true;90}91}92}93}9495// TODO: We could refine this to captured pointers that could possibly be96// accessed by flat instructions. For now this is mostly a poor way of97// estimating whether there are calls before argument lowering.98if (!IsFunc && HaveCall) {99F.addFnAttr("amdgpu-calls");100Changed = true;101}102103if (HaveStackObjects) {104F.addFnAttr("amdgpu-stack-objects");105Changed = true;106}107108return Changed;109}110111bool AMDGPUAnnotateKernelFeatures::runOnSCC(CallGraphSCC &SCC) {112bool Changed = false;113114for (CallGraphNode *I : SCC) {115Function *F = I->getFunction();116// Ignore functions with graphics calling conventions, these are currently117// not allowed to have kernel arguments.118if (!F || F->isDeclaration() || AMDGPU::isGraphics(F->getCallingConv()))119continue;120// Add feature attributes121Changed |= addFeatureAttributes(*F);122}123124return Changed;125}126127bool AMDGPUAnnotateKernelFeatures::doInitialization(CallGraph &CG) {128auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();129if (!TPC)130report_fatal_error("TargetMachine is required");131132TM = &TPC->getTM<TargetMachine>();133return false;134}135136Pass *llvm::createAMDGPUAnnotateKernelFeaturesPass() {137return new AMDGPUAnnotateKernelFeatures();138}139140141