Skip to content

Emit dxil version metadata. #4

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: emit_val_ver2
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
58 changes: 42 additions & 16 deletions llvm/lib/Target/DirectX/DxilEmitMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,35 @@ ConstantAsMetadata *Uint32ToConstMD(unsigned v, LLVMContext &Ctx) {
return ConstantAsMetadata::get(
Constant::getIntegerValue(IntegerType::get(Ctx, 32), APInt(32, v)));
}

const StringRef ValVerKey = "dx.valver";
const StringRef DxilVerKey = "dx.version";
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);
const unsigned OfflineLibMinor = 0xF;
const unsigned MaxDXILMinor = 7;

DxilValidatorVersionMD = M.getOrInsertNamedMetadata(ValVerKey);

auto &Ctx = M.getContext();
void emitVersion(NamedMDNode *MD, VersionTuple &Ver, LLVMContext &Ctx) {
Metadata *MDVals[DxilVersionNumFields];
MDVals[DxilVersionMajorIdx] = Uint32ToConstMD(ValidatorVer.getMajor(), Ctx);
MDVals[DxilVersionMajorIdx] = Uint32ToConstMD(Ver.getMajor(), Ctx);
MDVals[DxilVersionMinorIdx] =
Uint32ToConstMD(ValidatorVer.getMinor().getValueOr(0), Ctx);
Uint32ToConstMD(Ver.getMinor().getValueOr(0), Ctx);

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

void emitDxilVersion(Module &M, StringRef Key, VersionTuple &DxilVer) {
NamedMDNode *DxilVersionMD = M.getNamedMetadata(Key);
// Clear if already exist.
if (DxilVersionMD)
M.eraseNamedMetadata(DxilVersionMD);

DxilValidatorVersionMD->addOperand(MDNode::get(Ctx, MDVals));
DxilVersionMD = M.getOrInsertNamedMetadata(Key);

auto &Ctx = M.getContext();
emitVersion(DxilVersionMD, DxilVer, Ctx);
}

VersionTuple loadDxilValidatorVersion(MDNode *ValVerMD) {
Expand All @@ -58,6 +65,15 @@ VersionTuple loadDxilValidatorVersion(MDNode *ValVerMD) {
return VersionTuple(Major, Minor);
}

VersionTuple getDxilVersion(VersionTuple &ShaderModel) {
unsigned Major = 1;
unsigned Minor = ShaderModel.getMinor().getValueOr(0);
if (Minor == OfflineLibMinor) {
Minor = MaxDXILMinor;
}
return VersionTuple(Major, Minor);
}

void cleanModule(Module &M) {
M.getOrInsertModuleFlagsMetadata()->eraseFromParent();
}
Expand All @@ -67,24 +83,34 @@ namespace {
class DxilEmitMetadata : public ModulePass {
public:
static char ID; // Pass identification, replacement for typeid
explicit DxilEmitMetadata() : ModulePass(ID), ValidatorVer(1, 0) {}
explicit DxilEmitMetadata() : ModulePass(ID) {}

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) {
Triple Triple(M.getTargetTriple());
VersionTuple ShaderModel = Triple.getOSVersion();
VersionTuple DxilVer = getDxilVersion(ShaderModel);
emitDxilVersion(M, DxilVerKey, DxilVer);
VersionTuple ValidatorVer(1, 0);
if (MDNode *ValVerMD = cast_or_null<MDNode>(M.getModuleFlag(ValVerKey))) {
auto ValVer = loadDxilValidatorVersion(ValVerMD);
if (!ValVer.empty())
ValidatorVer = ValVer;
}
emitDxilValidatorVersion(M, ValidatorVer);
unsigned ShaderModelMinor = ShaderModel.getMinor().getValueOr(0);
if (ShaderModelMinor == OfflineLibMinor) {
ValidatorVer = VersionTuple(0, 0);
} else if (ValidatorVer < DxilVer) {
ValidatorVer = DxilVer;
}
emitDxilVersion(M, ValVerKey, ValidatorVer);
cleanModule(M);
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/DirectX/dxil_ver.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32
target triple = "dxil-pc-shadermodel6.3-library"

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

!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}
!2 = !{i32 1, i32 5}
!3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 71de12113a0661649ecb2f533fba4a2818a1ad68)"}
15 changes: 15 additions & 0 deletions llvm/test/CodeGen/DirectX/dxil_ver_lib6x.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
; RUN: llc %s -mtriple dxil-pc-shadermodel6.15-library --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"

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

!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 5}
!3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 71de12113a0661649ecb2f533fba4a2818a1ad68)"}