Path: blob/main/contrib/llvm-project/llvm/lib/Target/DirectX/DXILForwardHandleAccesses.cpp
213799 views
//===- DXILForwardHandleAccesses.cpp - Cleanup Handles --------------------===//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//===----------------------------------------------------------------------===//78#include "DXILForwardHandleAccesses.h"9#include "DXILShaderFlags.h"10#include "DirectX.h"11#include "llvm/Analysis/DXILResource.h"12#include "llvm/Analysis/Loads.h"13#include "llvm/IR/DiagnosticInfo.h"14#include "llvm/IR/Dominators.h"15#include "llvm/IR/IntrinsicInst.h"16#include "llvm/IR/Intrinsics.h"17#include "llvm/IR/IntrinsicsDirectX.h"18#include "llvm/IR/Module.h"19#include "llvm/InitializePasses.h"20#include "llvm/Pass.h"21#include "llvm/Transforms/Utils/Local.h"2223#define DEBUG_TYPE "dxil-forward-handle-accesses"2425using namespace llvm;2627static void diagnoseAmbiguousHandle(IntrinsicInst *NewII,28IntrinsicInst *PrevII) {29Function *F = NewII->getFunction();30LLVMContext &Context = F->getParent()->getContext();31Context.diagnose(DiagnosticInfoGeneric(32Twine("Handle at \"") + NewII->getName() + "\" overwrites handle at \"" +33PrevII->getName() + "\""));34}3536static void diagnoseHandleNotFound(LoadInst *LI) {37Function *F = LI->getFunction();38LLVMContext &Context = F->getParent()->getContext();39Context.diagnose(DiagnosticInfoGeneric(40LI, Twine("Load of \"") + LI->getPointerOperand()->getName() +41"\" is not a global resource handle"));42}4344static void diagnoseUndominatedLoad(LoadInst *LI, IntrinsicInst *Handle) {45Function *F = LI->getFunction();46LLVMContext &Context = F->getParent()->getContext();47Context.diagnose(DiagnosticInfoGeneric(48LI, Twine("Load at \"") + LI->getName() +49"\" is not dominated by handle creation at \"" +50Handle->getName() + "\""));51}5253static void54processHandle(IntrinsicInst *II,55DenseMap<GlobalVariable *, IntrinsicInst *> &HandleMap) {56for (User *U : II->users())57if (auto *SI = dyn_cast<StoreInst>(U))58if (auto *GV = dyn_cast<GlobalVariable>(SI->getPointerOperand())) {59auto Entry = HandleMap.try_emplace(GV, II);60if (Entry.second)61LLVM_DEBUG(dbgs() << "Added " << GV->getName() << " to handle map\n");62else63diagnoseAmbiguousHandle(II, Entry.first->second);64}65}6667static bool forwardHandleAccesses(Function &F, DominatorTree &DT) {68bool Changed = false;6970DenseMap<GlobalVariable *, IntrinsicInst *> HandleMap;71SmallVector<LoadInst *> LoadsToProcess;72for (BasicBlock &BB : F)73for (Instruction &Inst : BB)74if (auto *II = dyn_cast<IntrinsicInst>(&Inst)) {75switch (II->getIntrinsicID()) {76case Intrinsic::dx_resource_handlefrombinding:77case Intrinsic::dx_resource_handlefromimplicitbinding:78processHandle(II, HandleMap);79break;80default:81continue;82}83} else if (auto *LI = dyn_cast<LoadInst>(&Inst))84if (isa<dxil::AnyResourceExtType>(LI->getType()))85LoadsToProcess.push_back(LI);8687for (LoadInst *LI : LoadsToProcess) {88Value *V = LI->getPointerOperand();89auto *GV = dyn_cast<GlobalVariable>(LI->getPointerOperand());9091// If we didn't find the global, we may need to walk through a level of92// indirection. This generally happens at -O0.93if (!GV)94if (auto *NestedLI = dyn_cast<LoadInst>(V)) {95BasicBlock::iterator BBI(NestedLI);96Value *Loaded = FindAvailableLoadedValue(97NestedLI, NestedLI->getParent(), BBI, 0, nullptr, nullptr);98GV = dyn_cast_or_null<GlobalVariable>(Loaded);99}100101auto It = HandleMap.find(GV);102if (It == HandleMap.end()) {103diagnoseHandleNotFound(LI);104continue;105}106Changed = true;107108if (!DT.dominates(It->second, LI)) {109diagnoseUndominatedLoad(LI, It->second);110continue;111}112113LLVM_DEBUG(dbgs() << "Replacing uses of " << GV->getName() << " at "114<< LI->getName() << " with " << It->second->getName()115<< "\n");116LI->replaceAllUsesWith(It->second);117LI->eraseFromParent();118}119120return Changed;121}122123PreservedAnalyses DXILForwardHandleAccesses::run(Function &F,124FunctionAnalysisManager &AM) {125PreservedAnalyses PA;126127DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);128bool Changed = forwardHandleAccesses(F, *DT);129130if (!Changed)131return PreservedAnalyses::all();132return PA;133}134135namespace {136class DXILForwardHandleAccessesLegacy : public FunctionPass {137public:138bool runOnFunction(Function &F) override {139DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();140return forwardHandleAccesses(F, *DT);141}142StringRef getPassName() const override {143return "DXIL Forward Handle Accesses";144}145146void getAnalysisUsage(AnalysisUsage &AU) const override {147AU.addRequired<DominatorTreeWrapperPass>();148}149150DXILForwardHandleAccessesLegacy() : FunctionPass(ID) {}151152static char ID; // Pass identification.153};154char DXILForwardHandleAccessesLegacy::ID = 0;155} // end anonymous namespace156157INITIALIZE_PASS_BEGIN(DXILForwardHandleAccessesLegacy, DEBUG_TYPE,158"DXIL Forward Handle Accesses", false, false)159INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)160INITIALIZE_PASS_END(DXILForwardHandleAccessesLegacy, DEBUG_TYPE,161"DXIL Forward Handle Accesses", false, false)162163FunctionPass *llvm::createDXILForwardHandleAccessesLegacyPass() {164return new DXILForwardHandleAccessesLegacy();165}166167168