Skip to content

Emit dxil metadata for validator version. #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: val_ver
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm/lib/Target/DirectX/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_public_tablegen_target(DirectXCommonTableGen)
add_llvm_target(DirectXCodeGen
DirectXSubtarget.cpp
DirectXTargetMachine.cpp
DxilEmitMetadata.cpp
DXILPrepare.cpp

LINK_COMPONENTS
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/DirectX/DirectX.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ void initializeDXILPrepareModulePass(PassRegistry &);

/// Pass to convert modules into DXIL-compatable modules
ModulePass *createDXILPrepareModulePass();

/// Initializer for DxilEmitMetadata.
void initializeDxilEmitMetadataPass(PassRegistry &);

/// Pass to emit metadata for DXIL.
ModulePass *createDxilEmitMetadataPass();
} // namespace llvm

#endif // LLVM_LIB_TARGET_DIRECTX_DIRECTX_H
2 changes: 2 additions & 0 deletions llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
auto *PR = PassRegistry::getPassRegistry();
initializeDXILPrepareModulePass(*PR);
initializeDxilEmitMetadataPass(*PR);
}

class DXILTargetObjectFile : public TargetLoweringObjectFile {
Expand Down Expand Up @@ -85,6 +86,7 @@ bool DirectXTargetMachine::addPassesToEmitFile(
CodeGenFileType FileType, bool DisableVerify,
MachineModuleInfoWrapperPass *MMIWP) {
PM.add(createDXILPrepareModulePass());
PM.add(createDxilEmitMetadataPass());
switch (FileType) {
case CGFT_AssemblyFile:
PM.add(createPrintModulePass(Out, "", true));
Expand Down
103 changes: 103 additions & 0 deletions llvm/lib/Target/DirectX/DxilEmitMetadata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//===- DxilEmitMetadata.cpp - Pass to emit dxil metadata --------*- 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
//
//===----------------------------------------------------------------------===//
///
//===----------------------------------------------------------------------===//

#include "DirectX.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"

using namespace llvm;

namespace {
unsigned ConstMDToUint32(const MDOperand &MDO) {
ConstantInt *pConst = mdconst::extract<ConstantInt>(MDO);
return (unsigned)pConst->getZExtValue();
}
ConstantAsMetadata *Uint32ToConstMD(unsigned v, LLVMContext &Ctx) {
return ConstantAsMetadata::get(
Constant::getIntegerValue(IntegerType::get(Ctx, 32), APInt(32, v)));
}
const StringRef ValVerKey = "dx.valver";
const unsigned DxilVersionNumFields = 2;
const unsigned DxilVersionMajorIdx = 0; // DXIL version major.
const unsigned DxilVersionMinorIdx = 1; // DXIL version minor.

void emitDxilValidatorVersion(Module &M, VersionTuple &ValidatorVer) {
NamedMDNode *DxilValidatorVersionMD = M.getNamedMetadata(ValVerKey);

// Allow re-writing the validator version, since this can be changed at
// later points.
if (DxilValidatorVersionMD)
M.eraseNamedMetadata(DxilValidatorVersionMD);

DxilValidatorVersionMD = M.getOrInsertNamedMetadata(ValVerKey);

auto &Ctx = M.getContext();
Metadata *MDVals[DxilVersionNumFields];
MDVals[DxilVersionMajorIdx] = Uint32ToConstMD(ValidatorVer.getMajor(), Ctx);
MDVals[DxilVersionMinorIdx] =
Uint32ToConstMD(ValidatorVer.getMinor().getValueOr(0), Ctx);

DxilValidatorVersionMD->addOperand(MDNode::get(Ctx, MDVals));
}

VersionTuple loadDxilValidatorVersion(MDNode *ValVerMD) {
if (ValVerMD->getNumOperands() != DxilVersionNumFields)
return VersionTuple();

unsigned Major = ConstMDToUint32(ValVerMD->getOperand(DxilVersionMajorIdx));
unsigned Minor = ConstMDToUint32(ValVerMD->getOperand(DxilVersionMinorIdx));
return VersionTuple(Major, Minor);
}

void cleanModule(Module &M) {
M.getOrInsertModuleFlagsMetadata()->eraseFromParent();
}
} // namespace

namespace {
class DxilEmitMetadata : public ModulePass {
public:
static char ID; // Pass identification, replacement for typeid
explicit DxilEmitMetadata() : ModulePass(ID), ValidatorVer(1, 0) {}

StringRef getPassName() const override { return "HLSL DXIL Metadata Emit"; }

bool runOnModule(Module &M) override;

private:
VersionTuple ValidatorVer;
void emitDXILVersion(Module &M);
};

bool DxilEmitMetadata::runOnModule(Module &M) {
if (MDNode *ValVerMD = cast_or_null<MDNode>(M.getModuleFlag(ValVerKey))) {
auto ValVer = loadDxilValidatorVersion(ValVerMD);
if (!ValVer.empty())
ValidatorVer = ValVer;
}
emitDxilValidatorVersion(M, ValidatorVer);
cleanModule(M);
return false;
}

void DxilEmitMetadata::emitDXILVersion(Module &M) {}

} // namespace

char DxilEmitMetadata::ID = 0;

ModulePass *llvm::createDxilEmitMetadataPass() {
return new DxilEmitMetadata();
}

INITIALIZE_PASS(DxilEmitMetadata, "hlsl-dxilemit", "HLSL DXIL Metadata Emit",
false, false)
14 changes: 14 additions & 0 deletions llvm/test/CodeGen/DirectX/dxil_ver.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; RUN: llc %s --filetype=asm -o - | FileCheck %s
target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-pc-shadermodel6.3-library"

; CHECK:!dx.valver = !{![[valver:[0-9]+]]}
; CHECK:![[valver]] = !{i32 1, i32 1}

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!3}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 6, !"dx.valver", !2}
!2 = !{i32 1, i32 1}
!3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 71de12113a0661649ecb2f533fba4a2818a1ad68)"}