--- /dev/null
+//===- DXILMetadata.cpp - DXIL Metadata helper objects --------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file This file contains helper objects for working with DXIL metadata.
+///
+//===----------------------------------------------------------------------===//
+
+#include "DXILMetadata.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/VersionTuple.h"
+
+using namespace llvm;
+using namespace llvm::dxil;
+
+ValidatorVersionMD::ValidatorVersionMD(Module &M)
+ : Entry(M.getOrInsertNamedMetadata("dx.valver")) {}
+
+void ValidatorVersionMD::update(VersionTuple ValidatorVer) {
+ auto &Ctx = Entry->getParent()->getContext();
+ IRBuilder<> B(Ctx);
+ Metadata *MDVals[2];
+
+ MDVals[0] = ConstantAsMetadata::get(B.getInt32(ValidatorVer.getMajor()));
+ MDVals[1] =
+ ConstantAsMetadata::get(B.getInt32(ValidatorVer.getMinor().value_or(0)));
+
+ if (isEmpty())
+ Entry->addOperand(MDNode::get(Ctx, MDVals));
+ else
+ Entry->setOperand(0, MDNode::get(Ctx, MDVals));
+}
+
+bool ValidatorVersionMD::isEmpty() { return Entry->getNumOperands() == 0; }
--- /dev/null
+//===- DXILMetadata.h - DXIL Metadata helper objects ----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file This file contains helper objects for working with DXIL metadata.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_DIRECTX_DXILMETADATA_H
+#define LLVM_TARGET_DIRECTX_DXILMETADATA_H
+
+namespace llvm {
+class Module;
+class NamedMDNode;
+class VersionTuple;
+namespace dxil {
+
+class ValidatorVersionMD {
+ NamedMDNode *Entry;
+
+public:
+ ValidatorVersionMD(Module &M);
+
+ void update(VersionTuple ValidatorVer);
+
+ bool isEmpty();
+};
+
+} // namespace dxil
+} // namespace llvm
+
+#endif // LLVM_TARGET_DIRECTX_DXILMETADATA_H
///
//===----------------------------------------------------------------------===//
+#include "DXILMetadata.h"
#include "DirectX.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Triple.h"
using namespace llvm;
-static uint32_t ConstMDToUint32(const MDOperand &MDO) {
- ConstantInt *pConst = mdconst::extract<ConstantInt>(MDO);
- return (uint32_t)pConst->getZExtValue();
-}
-
-static ConstantAsMetadata *Uint32ToConstMD(unsigned v, LLVMContext &Ctx) {
- return ConstantAsMetadata::get(
- Constant::getIntegerValue(IntegerType::get(Ctx, 32), APInt(32, v)));
-}
-
-constexpr StringLiteral ValVerKey = "dx.valver";
-constexpr unsigned DXILVersionNumFields = 2;
-
-static 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[0] = Uint32ToConstMD(ValidatorVer.getMajor(), Ctx);
- MDVals[1] = Uint32ToConstMD(ValidatorVer.getMinor().value_or(0), Ctx);
-
- DXILValidatorVersionMD->addOperand(MDNode::get(Ctx, MDVals));
-}
-
-static VersionTuple loadDXILValidatorVersion(MDNode *ValVerMD) {
- if (ValVerMD->getNumOperands() != DXILVersionNumFields)
- return VersionTuple();
-
- unsigned Major = ConstMDToUint32(ValVerMD->getOperand(0));
- unsigned Minor = ConstMDToUint32(ValVerMD->getOperand(1));
- return VersionTuple(Major, Minor);
-}
-
namespace {
class DXILTranslateMetadata : public ModulePass {
public:
static char ID; // Pass identification, replacement for typeid
- explicit DXILTranslateMetadata() : ModulePass(ID), ValidatorVer(1, 0) {}
+ explicit DXILTranslateMetadata() : ModulePass(ID) {}
StringRef getPassName() const override { return "DXIL Metadata Emit"; }
bool runOnModule(Module &M) override;
-
-private:
- VersionTuple ValidatorVer;
};
} // namespace
bool DXILTranslateMetadata::runOnModule(Module &M) {
- if (NamedMDNode *ValVerMD = M.getNamedMetadata(ValVerKey)) {
- VersionTuple ValVer = loadDXILValidatorVersion(ValVerMD->getOperand(0));
- if (!ValVer.empty())
- ValidatorVer = ValVer;
- }
- emitDXILValidatorVersion(M, ValidatorVer);
+
+ dxil::ValidatorVersionMD ValVerMD(M);
+ if (ValVerMD.isEmpty())
+ ValVerMD.update(VersionTuple(1, 0));
return false;
}