Put DXIL validation version into separate NamedMetadata to avoid update ModuleFlags. Currently DXIL validation version is saved in ModuleFlags in clang codeGen. Then in DirectX backend, the data will be extracted from ModuleFlags and cause rebuild of ModuleFlags. This patch will build NamedMetadata for DXIL validation version and remove the code to rebuild ModuleFlags. Reviewed By: beanz Differential Revision: https://reviews.llvm.org/D130207
95 lines
3.0 KiB
C++
95 lines
3.0 KiB
C++
//===- DXILTranslateMetadata.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/StringSet.h"
|
|
#include "llvm/ADT/Triple.h"
|
|
#include "llvm/IR/Constants.h"
|
|
#include "llvm/IR/Metadata.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/Pass.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) {}
|
|
|
|
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);
|
|
return false;
|
|
}
|
|
|
|
char DXILTranslateMetadata::ID = 0;
|
|
|
|
ModulePass *llvm::createDXILTranslateMetadataPass() {
|
|
return new DXILTranslateMetadata();
|
|
}
|
|
|
|
INITIALIZE_PASS(DXILTranslateMetadata, "dxil-metadata-emit",
|
|
"DXIL Metadata Emit", false, false)
|