brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 5624532 Raw
93 lines · cpp
1//===- DXILCBufferAccess.cpp - Translate CBuffer Loads --------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "DXILCBufferAccess.h"10#include "DirectX.h"11#include "llvm/Analysis/DXILResource.h"12#include "llvm/Frontend/HLSL/CBuffer.h"13#include "llvm/Frontend/HLSL/HLSLResource.h"14#include "llvm/IR/IRBuilder.h"15#include "llvm/IR/IntrinsicInst.h"16#include "llvm/IR/IntrinsicsDirectX.h"17#include "llvm/IR/ReplaceConstant.h"18#include "llvm/InitializePasses.h"19#include "llvm/Pass.h"20#include "llvm/Support/FormatVariadic.h"21#include "llvm/Transforms/Utils/Local.h"22 23#define DEBUG_TYPE "dxil-cbuffer-access"24using namespace llvm;25 26static void replaceUsersOfGlobal(GlobalVariable *Global,27                                 GlobalVariable *HandleGV, size_t Offset) {28  for (Use &U : make_early_inc_range(Global->uses())) {29    auto UseInst = dyn_cast<Instruction>(U.getUser());30    // TODO: Constants? Metadata?31    assert(UseInst && "Non-instruction use of cbuffer");32 33    IRBuilder<> Builder(UseInst);34    LoadInst *Handle = Builder.CreateLoad(HandleGV->getValueType(), HandleGV,35                                          HandleGV->getName());36    Value *Ptr = Builder.CreateIntrinsic(37        Global->getType(), Intrinsic::dx_resource_getpointer,38        ArrayRef<Value *>{Handle,39                          ConstantInt::get(Builder.getInt32Ty(), Offset)});40    U.set(Ptr);41  }42 43  Global->removeFromParent();44}45 46static bool replaceCBufferAccesses(Module &M) {47  std::optional<hlsl::CBufferMetadata> CBufMD = hlsl::CBufferMetadata::get(48      M, [](Type *Ty) { return isa<llvm::dxil::PaddingExtType>(Ty); });49  if (!CBufMD)50    return false;51 52  SmallVector<Constant *> CBufferGlobals;53  for (const hlsl::CBufferMapping &Mapping : *CBufMD)54    for (const hlsl::CBufferMember &Member : Mapping.Members)55      CBufferGlobals.push_back(Member.GV);56  convertUsersOfConstantsToInstructions(CBufferGlobals);57 58  for (const hlsl::CBufferMapping &Mapping : *CBufMD)59    for (const hlsl::CBufferMember &Member : Mapping.Members)60      replaceUsersOfGlobal(Member.GV, Mapping.Handle, Member.Offset);61 62  CBufMD->eraseFromModule();63  return true;64}65 66PreservedAnalyses DXILCBufferAccess::run(Module &M, ModuleAnalysisManager &AM) {67  PreservedAnalyses PA;68  bool Changed = replaceCBufferAccesses(M);69 70  if (!Changed)71    return PreservedAnalyses::all();72  return PA;73}74 75namespace {76class DXILCBufferAccessLegacy : public ModulePass {77public:78  bool runOnModule(Module &M) override { return replaceCBufferAccesses(M); }79  StringRef getPassName() const override { return "DXIL CBuffer Access"; }80  DXILCBufferAccessLegacy() : ModulePass(ID) {}81 82  static char ID; // Pass identification.83};84char DXILCBufferAccessLegacy::ID = 0;85} // end anonymous namespace86 87INITIALIZE_PASS(DXILCBufferAccessLegacy, DEBUG_TYPE, "DXIL CBuffer Access",88                false, false)89 90ModulePass *llvm::createDXILCBufferAccessLegacyPass() {91  return new DXILCBufferAccessLegacy();92}93