Skip to content
Merged
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
7 changes: 4 additions & 3 deletions llvm/docs/DirectX/DXILArchitecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,10 @@ The passes to generate DXIL IR follow the flow:
Each of these passes has a defined responsibility:

#. DXILOpLowering translates LLVM intrinsic calls to dx.op calls.
#. DXILPrepare transforms the DXIL IR to be compatible with LLVM 3.7, and
inserts bitcasts to allow typed pointers to be inserted.
#. DXILTranslateMetadata emits the DXIL Metadata structures.
#. DXILPrepare updates functions in the DXIL IR to be compatible with LLVM 3.7,
namely removing attributes, and inserting bitcasts to allow typed pointers
to be inserted.
#. DXILTranslateMetadata transforms and emits all recognized DXIL Metadata.

The passes to encode DXIL to binary in the DX Container follow the flow:

Expand Down
89 changes: 16 additions & 73 deletions llvm/lib/Target/DirectX/DXILPrepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
///
/// \file This file contains pases and utilities to convert a modern LLVM
/// \file This file contains passes and utilities to convert a modern LLVM
/// module into a module compatible with the LLVM 3.7-based DirectX Intermediate
/// Language (DXIL).
//===----------------------------------------------------------------------===//
Expand All @@ -16,7 +16,6 @@
#include "DirectX.h"
#include "DirectXIRPasses/PointerTypeAnalysis.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Analysis/DXILMetadataAnalysis.h"
#include "llvm/Analysis/DXILResource.h"
Expand All @@ -27,7 +26,6 @@
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/VersionTuple.h"

#define DEBUG_TYPE "dxil-prepare"
Expand Down Expand Up @@ -116,31 +114,6 @@ static void removeStringFunctionAttributes(Function &F,
F.removeRetAttrs(DeadAttrs);
}

static void cleanModuleFlags(Module &M) {
NamedMDNode *MDFlags = M.getModuleFlagsMetadata();
if (!MDFlags)
return;

SmallVector<llvm::Module::ModuleFlagEntry> FlagEntries;
M.getModuleFlagsMetadata(FlagEntries);
bool Updated = false;
for (auto &Flag : FlagEntries) {
// llvm 3.7 only supports behavior up to AppendUnique.
if (Flag.Behavior <= Module::ModFlagBehavior::AppendUnique)
continue;
Flag.Behavior = Module::ModFlagBehavior::Warning;
Updated = true;
}

if (!Updated)
return;

MDFlags->eraseFromParent();

for (auto &Flag : FlagEntries)
M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val);
}

class DXILPrepareModule : public ModulePass {

static Value *maybeGenerateBitcast(IRBuilder<> &Builder,
Expand Down Expand Up @@ -202,15 +175,6 @@ class DXILPrepareModule : public ModulePass {
Builder.getPtrTy(PtrTy->getAddressSpace())));
}

static std::array<unsigned, 6> getCompatibleInstructionMDs(llvm::Module &M) {
return {M.getMDKindID("dx.nonuniform"),
M.getMDKindID("dx.controlflow.hints"),
M.getMDKindID("dx.precise"),
llvm::LLVMContext::MD_range,
llvm::LLVMContext::MD_alias_scope,
llvm::LLVMContext::MD_noalias};
}

public:
bool runOnModule(Module &M) override {
PointerTypeMap PointerTypes = PointerTypeAnalysis::run(M);
Expand All @@ -224,30 +188,33 @@ class DXILPrepareModule : public ModulePass {
const dxil::ModuleMetadataInfo MetadataInfo =
getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
VersionTuple ValVer = MetadataInfo.ValidatorVersion;
bool SkipValidation = ValVer.getMajor() == 0 && ValVer.getMinor() == 0;

// construct allowlist of valid metadata node kinds
std::array<unsigned, 6> DXILCompatibleMDs = getCompatibleInstructionMDs(M);
bool AllowExperimental = ValVer.getMajor() == 0 && ValVer.getMinor() == 0;

for (auto &F : M.functions()) {
F.removeFnAttrs(AttrMask);
F.removeRetAttrs(AttrMask);
// Only remove string attributes if we are not skipping validation.
// This will reserve the experimental attributes when validation version
// is 0.0 for experiment mode.
removeStringFunctionAttributes(F, SkipValidation);
removeStringFunctionAttributes(F, AllowExperimental);
for (size_t Idx = 0, End = F.arg_size(); Idx < End; ++Idx)
F.removeParamAttrs(Idx, AttrMask);

for (auto &BB : F) {
IRBuilder<> Builder(&BB);
for (auto &I : make_early_inc_range(BB)) {

I.dropUnknownNonDebugMetadata(DXILCompatibleMDs);
if (auto *CB = dyn_cast<CallBase>(&I)) {
CB->removeFnAttrs(AttrMask);
CB->removeRetAttrs(AttrMask);
for (size_t Idx = 0, End = CB->arg_size(); Idx < End; ++Idx)
CB->removeParamAttrs(Idx, AttrMask);
continue;
}
Comment on lines +207 to +213
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just moved for clarity? I don't see an obvious reason the order matters here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, it is just a cosmetic move to group all the attr/bitcast together


// Emtting NoOp bitcast instructions allows the ValueEnumerator to be
// unmodified as it reserves instruction IDs during contruction.
if (auto LI = dyn_cast<LoadInst>(&I)) {
if (auto *LI = dyn_cast<LoadInst>(&I)) {
if (Value *NoOpBitcast = maybeGenerateBitcast(
Builder, PointerTypes, I, LI->getPointerOperand(),
LI->getType())) {
Expand All @@ -257,7 +224,7 @@ class DXILPrepareModule : public ModulePass {
}
continue;
}
if (auto SI = dyn_cast<StoreInst>(&I)) {
if (auto *SI = dyn_cast<StoreInst>(&I)) {
if (Value *NoOpBitcast = maybeGenerateBitcast(
Builder, PointerTypes, I, SI->getPointerOperand(),
SI->getValueOperand()->getType())) {
Expand All @@ -268,51 +235,28 @@ class DXILPrepareModule : public ModulePass {
}
continue;
}
if (auto GEP = dyn_cast<GetElementPtrInst>(&I)) {
if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
if (Value *NoOpBitcast = maybeGenerateBitcast(
Builder, PointerTypes, I, GEP->getPointerOperand(),
GEP->getSourceElementType()))
GEP->setOperand(0, NoOpBitcast);
continue;
}
if (auto *CB = dyn_cast<CallBase>(&I)) {
CB->removeFnAttrs(AttrMask);
CB->removeRetAttrs(AttrMask);
for (size_t Idx = 0, End = CB->arg_size(); Idx < End; ++Idx)
CB->removeParamAttrs(Idx, AttrMask);
continue;
}
}
}
}
// Remove flags not for DXIL.
cleanModuleFlags(M);

// dx.rootsignatures will have been parsed from its metadata form as its
// binary form as part of the RootSignatureAnalysisWrapper, so safely
// remove it as it is not recognized in DXIL
if (NamedMDNode *RootSignature = M.getNamedMetadata("dx.rootsignatures"))
RootSignature->eraseFromParent();

// llvm.errno.tbaa was recently added but is not supported in LLVM 3.7 and
// causes all tests using the DXIL Validator to fail.
//
// This is a temporary fix and should be replaced with a whitelist once
// we have determined all metadata that the DXIL Validator allows
if (NamedMDNode *ErrNo = M.getNamedMetadata("llvm.errno.tbaa"))
ErrNo->eraseFromParent();

return true;
}

DXILPrepareModule() : ModulePass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<DXILMetadataAnalysisWrapperPass>();
AU.addRequired<RootSignatureAnalysisWrapper>();
AU.addPreserved<RootSignatureAnalysisWrapper>();
AU.addPreserved<ShaderFlagsAnalysisWrapper>();

AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
AU.addPreserved<DXILResourceWrapperPass>();
AU.addPreserved<RootSignatureAnalysisWrapper>();
AU.addPreserved<ShaderFlagsAnalysisWrapper>();
}
static char ID; // Pass identification.
};
Expand All @@ -323,7 +267,6 @@ char DXILPrepareModule::ID = 0;
INITIALIZE_PASS_BEGIN(DXILPrepareModule, DEBUG_TYPE, "DXIL Prepare Module",
false, false)
INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(RootSignatureAnalysisWrapper)
INITIALIZE_PASS_END(DXILPrepareModule, DEBUG_TYPE, "DXIL Prepare Module", false,
false)

Expand Down
Loading