CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
104 lines
3.7 KiB
C++
104 lines
3.7 KiB
C++
//===- SPIRVPushConstantAccess.cpp - Translate CBuffer Loads ----*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This pass changes the types of all the globals in the PushConstant
|
|
// address space into a target extension type, and makes all references
|
|
// to this global go though a custom SPIR-V intrinsic.
|
|
//
|
|
// This allows the backend to properly lower the push constant struct type
|
|
// to a fully laid out type, and generate the proper OpAccessChain.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "SPIRVPushConstantAccess.h"
|
|
#include "SPIRV.h"
|
|
#include "SPIRVSubtarget.h"
|
|
#include "SPIRVTargetMachine.h"
|
|
#include "SPIRVUtils.h"
|
|
#include "llvm/Frontend/HLSL/CBuffer.h"
|
|
#include "llvm/IR/IRBuilder.h"
|
|
#include "llvm/IR/IntrinsicsSPIRV.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/IR/ReplaceConstant.h"
|
|
|
|
#define DEBUG_TYPE "spirv-pushconstant-access"
|
|
using namespace llvm;
|
|
|
|
static bool replacePushConstantAccesses(Module &M, SPIRVGlobalRegistry *GR) {
|
|
bool Changed = false;
|
|
for (GlobalVariable &GV : make_early_inc_range(M.globals())) {
|
|
if (GV.getAddressSpace() !=
|
|
storageClassToAddressSpace(SPIRV::StorageClass::PushConstant))
|
|
continue;
|
|
|
|
convertUsersOfConstantsToInstructions(
|
|
llvm::SmallVector<Constant *, 1>(1, &GV));
|
|
|
|
Type *PCType = llvm::TargetExtType::get(
|
|
M.getContext(), "spirv.PushConstant", {GV.getValueType()});
|
|
GlobalVariable *NewGV =
|
|
new GlobalVariable(M, PCType, GV.isConstant(), GV.getLinkage(),
|
|
/* initializer= */ nullptr, GV.getName(),
|
|
/* InsertBefore= */ &GV, GV.getThreadLocalMode(),
|
|
GV.getAddressSpace(), GV.isExternallyInitialized());
|
|
NewGV->setVisibility(GV.getVisibility());
|
|
|
|
for (User *U : make_early_inc_range(GV.users())) {
|
|
Instruction *I = cast<Instruction>(U);
|
|
IRBuilder<> Builder(I);
|
|
Value *GetPointerCall = Builder.CreateIntrinsic(
|
|
NewGV->getType(), Intrinsic::spv_pushconstant_getpointer, {NewGV});
|
|
GR->buildAssignPtr(Builder, GV.getValueType(), GetPointerCall);
|
|
|
|
I->replaceUsesOfWith(&GV, GetPointerCall);
|
|
}
|
|
|
|
GV.eraseFromParent();
|
|
Changed = true;
|
|
}
|
|
|
|
return Changed;
|
|
}
|
|
|
|
PreservedAnalyses SPIRVPushConstantAccess::run(Module &M,
|
|
ModuleAnalysisManager &AM) {
|
|
const SPIRVSubtarget *ST = TM.getSubtargetImpl();
|
|
SPIRVGlobalRegistry *GR = ST->getSPIRVGlobalRegistry();
|
|
return replacePushConstantAccesses(M, GR) ? PreservedAnalyses::none()
|
|
: PreservedAnalyses::all();
|
|
}
|
|
|
|
namespace {
|
|
class SPIRVPushConstantAccessLegacy : public ModulePass {
|
|
SPIRVTargetMachine *TM = nullptr;
|
|
|
|
public:
|
|
bool runOnModule(Module &M) override {
|
|
const SPIRVSubtarget *ST = TM->getSubtargetImpl();
|
|
SPIRVGlobalRegistry *GR = ST->getSPIRVGlobalRegistry();
|
|
return replacePushConstantAccesses(M, GR);
|
|
}
|
|
StringRef getPassName() const override {
|
|
return "SPIRV push constant Access";
|
|
}
|
|
SPIRVPushConstantAccessLegacy(SPIRVTargetMachine *TM)
|
|
: ModulePass(ID), TM(TM) {}
|
|
|
|
static char ID; // Pass identification.
|
|
};
|
|
char SPIRVPushConstantAccessLegacy::ID = 0;
|
|
} // end anonymous namespace
|
|
|
|
INITIALIZE_PASS(SPIRVPushConstantAccessLegacy, DEBUG_TYPE,
|
|
"SPIRV push constant Access", false, false)
|
|
|
|
ModulePass *
|
|
llvm::createSPIRVPushConstantAccessLegacyPass(SPIRVTargetMachine *TM) {
|
|
return new SPIRVPushConstantAccessLegacy(TM);
|
|
}
|