Skip to content

Commit f63d3b1

Browse files
author
Xiang Li
committed
Emit dxil metadata for validator version.
1 parent 437889a commit f63d3b1

File tree

5 files changed

+126
-0
lines changed

5 files changed

+126
-0
lines changed

llvm/lib/Target/DirectX/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_public_tablegen_target(DirectXCommonTableGen)
99
add_llvm_target(DirectXCodeGen
1010
DirectXSubtarget.cpp
1111
DirectXTargetMachine.cpp
12+
DxilEmitMetadata.cpp
1213
DXILPrepare.cpp
1314

1415
LINK_COMPONENTS

llvm/lib/Target/DirectX/DirectX.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ void initializeDXILPrepareModulePass(PassRegistry &);
2020

2121
/// Pass to convert modules into DXIL-compatable modules
2222
ModulePass *createDXILPrepareModulePass();
23+
24+
/// Initializer for DxilEmitMetadata.
25+
void initializeDxilEmitMetadataPass(PassRegistry &);
26+
27+
/// Pass to emit metadata for DXIL.
28+
ModulePass *createDxilEmitMetadataPass();
2329
} // namespace llvm
2430

2531
#endif // LLVM_LIB_TARGET_DIRECTX_DIRECTX_H

llvm/lib/Target/DirectX/DirectXTargetMachine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
3434
RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
3535
auto *PR = PassRegistry::getPassRegistry();
3636
initializeDXILPrepareModulePass(*PR);
37+
initializeDxilEmitMetadataPass(*PR);
3738
}
3839

3940
class DXILTargetObjectFile : public TargetLoweringObjectFile {
@@ -85,6 +86,7 @@ bool DirectXTargetMachine::addPassesToEmitFile(
8586
CodeGenFileType FileType, bool DisableVerify,
8687
MachineModuleInfoWrapperPass *MMIWP) {
8788
PM.add(createDXILPrepareModulePass());
89+
PM.add(createDxilEmitMetadataPass());
8890
switch (FileType) {
8991
case CGFT_AssemblyFile:
9092
PM.add(createPrintModulePass(Out, "", true));
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//===- DxilEmitMetadata.cpp - Pass to emit dxil metadata --------*- C++ -*-===//
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-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
//===----------------------------------------------------------------------===//
10+
11+
#include "DirectX.h"
12+
#include "llvm/ADT/Triple.h"
13+
#include "llvm/IR/Constants.h"
14+
#include "llvm/IR/Module.h"
15+
#include "llvm/Pass.h"
16+
17+
using namespace llvm;
18+
19+
namespace {
20+
unsigned ConstMDToUint32(const MDOperand &MDO) {
21+
ConstantInt *pConst = mdconst::extract<ConstantInt>(MDO);
22+
return (unsigned)pConst->getZExtValue();
23+
}
24+
ConstantAsMetadata *Uint32ToConstMD(unsigned v, LLVMContext &Ctx) {
25+
return ConstantAsMetadata::get(
26+
Constant::getIntegerValue(IntegerType::get(Ctx, 32), APInt(32, v)));
27+
}
28+
const StringRef ValVerKey = "dx.valver";
29+
const unsigned DxilVersionNumFields = 2;
30+
const unsigned DxilVersionMajorIdx = 0; // DXIL version major.
31+
const unsigned DxilVersionMinorIdx = 1; // DXIL version minor.
32+
33+
void emitDxilValidatorVersion(Module &M, VersionTuple &ValidatorVer) {
34+
NamedMDNode *DxilValidatorVersionMD = M.getNamedMetadata(ValVerKey);
35+
36+
// Allow re-writing the validator version, since this can be changed at
37+
// later points.
38+
if (DxilValidatorVersionMD)
39+
M.eraseNamedMetadata(DxilValidatorVersionMD);
40+
41+
DxilValidatorVersionMD = M.getOrInsertNamedMetadata(ValVerKey);
42+
43+
auto &Ctx = M.getContext();
44+
Metadata *MDVals[DxilVersionNumFields];
45+
MDVals[DxilVersionMajorIdx] = Uint32ToConstMD(ValidatorVer.getMajor(), Ctx);
46+
MDVals[DxilVersionMinorIdx] =
47+
Uint32ToConstMD(ValidatorVer.getMinor().getValueOr(0), Ctx);
48+
49+
DxilValidatorVersionMD->addOperand(MDNode::get(Ctx, MDVals));
50+
}
51+
52+
VersionTuple loadDxilValidatorVersion(MDNode *ValVerMD) {
53+
if (ValVerMD->getNumOperands() != DxilVersionNumFields)
54+
return VersionTuple();
55+
56+
unsigned Major = ConstMDToUint32(ValVerMD->getOperand(DxilVersionMajorIdx));
57+
unsigned Minor = ConstMDToUint32(ValVerMD->getOperand(DxilVersionMinorIdx));
58+
return VersionTuple(Major, Minor);
59+
}
60+
61+
void cleanModule(Module &M) {
62+
M.getOrInsertModuleFlagsMetadata()->eraseFromParent();
63+
}
64+
} // namespace
65+
66+
namespace {
67+
class DxilEmitMetadata : public ModulePass {
68+
public:
69+
static char ID; // Pass identification, replacement for typeid
70+
explicit DxilEmitMetadata() : ModulePass(ID), ValidatorVer(1, 0) {}
71+
72+
StringRef getPassName() const override { return "HLSL DXIL Metadata Emit"; }
73+
74+
bool runOnModule(Module &M) override;
75+
76+
private:
77+
VersionTuple ValidatorVer;
78+
void emitDXILVersion(Module &M);
79+
};
80+
81+
bool DxilEmitMetadata::runOnModule(Module &M) {
82+
if (MDNode *ValVerMD = cast_or_null<MDNode>(M.getModuleFlag(ValVerKey))) {
83+
auto ValVer = loadDxilValidatorVersion(ValVerMD);
84+
if (!ValVer.empty())
85+
ValidatorVer = ValVer;
86+
}
87+
emitDxilValidatorVersion(M, ValidatorVer);
88+
cleanModule(M);
89+
return false;
90+
}
91+
92+
void DxilEmitMetadata::emitDXILVersion(Module &M) {}
93+
94+
} // namespace
95+
96+
char DxilEmitMetadata::ID = 0;
97+
98+
ModulePass *llvm::createDxilEmitMetadataPass() {
99+
return new DxilEmitMetadata();
100+
}
101+
102+
INITIALIZE_PASS(DxilEmitMetadata, "hlsl-dxilemit", "HLSL DXIL Metadata Emit",
103+
false, false)

llvm/test/CodeGen/DirectX/dxil_ver.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; RUN: llc %s --filetype=asm -o - | FileCheck %s
2+
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"
3+
target triple = "dxil-pc-shadermodel6.3-library"
4+
5+
; CHECK:!dx.valver = !{![[valver:[0-9]+]]}
6+
; CHECK:![[valver]] = !{i32 1, i32 1}
7+
8+
!llvm.module.flags = !{!0, !1}
9+
!llvm.ident = !{!3}
10+
11+
!0 = !{i32 1, !"wchar_size", i32 4}
12+
!1 = !{i32 6, !"dx.valver", !2}
13+
!2 = !{i32 1, i32 1}
14+
!3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 71de12113a0661649ecb2f533fba4a2818a1ad68)"}

0 commit comments

Comments
 (0)