Skip to content

Commit 87c9f25

Browse files
inbelicLukacma
authored andcommitted
[NFC][DirectX] Refactor DXILPrepare/DXILTranslateMetadata (llvm#164285)
This pr updates `DXILPrepare` and `DXILTranslateMetadata` by moving all the removal of metadata from `DXILPrepare` to `DXILTranslateMetadata` to have a more consistent definition of what each pass is doing. It restricts the `DXILPrepare` to only update function attributes and insert bitcasts, and moves the removal of metadata to `DXILTranslateMetadata` so that all manipulation of metadata is done in a single pass.
1 parent e02ce7d commit 87c9f25

File tree

10 files changed

+126
-121
lines changed

10 files changed

+126
-121
lines changed

llvm/docs/DirectX/DXILArchitecture.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,10 @@ The passes to generate DXIL IR follow the flow:
118118
Each of these passes has a defined responsibility:
119119

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

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

llvm/lib/Target/DirectX/DXILPrepare.cpp

Lines changed: 16 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88
///
9-
/// \file This file contains pases and utilities to convert a modern LLVM
9+
/// \file This file contains passes and utilities to convert a modern LLVM
1010
/// module into a module compatible with the LLVM 3.7-based DirectX Intermediate
1111
/// Language (DXIL).
1212
//===----------------------------------------------------------------------===//
@@ -16,7 +16,6 @@
1616
#include "DirectX.h"
1717
#include "DirectXIRPasses/PointerTypeAnalysis.h"
1818
#include "llvm/ADT/STLExtras.h"
19-
#include "llvm/ADT/SmallVector.h"
2019
#include "llvm/ADT/StringSet.h"
2120
#include "llvm/Analysis/DXILMetadataAnalysis.h"
2221
#include "llvm/Analysis/DXILResource.h"
@@ -27,7 +26,6 @@
2726
#include "llvm/IR/Module.h"
2827
#include "llvm/InitializePasses.h"
2928
#include "llvm/Pass.h"
30-
#include "llvm/Support/Compiler.h"
3129
#include "llvm/Support/VersionTuple.h"
3230

3331
#define DEBUG_TYPE "dxil-prepare"
@@ -116,31 +114,6 @@ static void removeStringFunctionAttributes(Function &F,
116114
F.removeRetAttrs(DeadAttrs);
117115
}
118116

119-
static void cleanModuleFlags(Module &M) {
120-
NamedMDNode *MDFlags = M.getModuleFlagsMetadata();
121-
if (!MDFlags)
122-
return;
123-
124-
SmallVector<llvm::Module::ModuleFlagEntry> FlagEntries;
125-
M.getModuleFlagsMetadata(FlagEntries);
126-
bool Updated = false;
127-
for (auto &Flag : FlagEntries) {
128-
// llvm 3.7 only supports behavior up to AppendUnique.
129-
if (Flag.Behavior <= Module::ModFlagBehavior::AppendUnique)
130-
continue;
131-
Flag.Behavior = Module::ModFlagBehavior::Warning;
132-
Updated = true;
133-
}
134-
135-
if (!Updated)
136-
return;
137-
138-
MDFlags->eraseFromParent();
139-
140-
for (auto &Flag : FlagEntries)
141-
M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val);
142-
}
143-
144117
class DXILPrepareModule : public ModulePass {
145118

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

205-
static std::array<unsigned, 6> getCompatibleInstructionMDs(llvm::Module &M) {
206-
return {M.getMDKindID("dx.nonuniform"),
207-
M.getMDKindID("dx.controlflow.hints"),
208-
M.getMDKindID("dx.precise"),
209-
llvm::LLVMContext::MD_range,
210-
llvm::LLVMContext::MD_alias_scope,
211-
llvm::LLVMContext::MD_noalias};
212-
}
213-
214178
public:
215179
bool runOnModule(Module &M) override {
216180
PointerTypeMap PointerTypes = PointerTypeAnalysis::run(M);
@@ -224,30 +188,33 @@ class DXILPrepareModule : public ModulePass {
224188
const dxil::ModuleMetadataInfo MetadataInfo =
225189
getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
226190
VersionTuple ValVer = MetadataInfo.ValidatorVersion;
227-
bool SkipValidation = ValVer.getMajor() == 0 && ValVer.getMinor() == 0;
228-
229-
// construct allowlist of valid metadata node kinds
230-
std::array<unsigned, 6> DXILCompatibleMDs = getCompatibleInstructionMDs(M);
191+
bool AllowExperimental = ValVer.getMajor() == 0 && ValVer.getMinor() == 0;
231192

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

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

246-
I.dropUnknownNonDebugMetadata(DXILCompatibleMDs);
207+
if (auto *CB = dyn_cast<CallBase>(&I)) {
208+
CB->removeFnAttrs(AttrMask);
209+
CB->removeRetAttrs(AttrMask);
210+
for (size_t Idx = 0, End = CB->arg_size(); Idx < End; ++Idx)
211+
CB->removeParamAttrs(Idx, AttrMask);
212+
continue;
213+
}
247214

248215
// Emtting NoOp bitcast instructions allows the ValueEnumerator to be
249216
// unmodified as it reserves instruction IDs during contruction.
250-
if (auto LI = dyn_cast<LoadInst>(&I)) {
217+
if (auto *LI = dyn_cast<LoadInst>(&I)) {
251218
if (Value *NoOpBitcast = maybeGenerateBitcast(
252219
Builder, PointerTypes, I, LI->getPointerOperand(),
253220
LI->getType())) {
@@ -257,7 +224,7 @@ class DXILPrepareModule : public ModulePass {
257224
}
258225
continue;
259226
}
260-
if (auto SI = dyn_cast<StoreInst>(&I)) {
227+
if (auto *SI = dyn_cast<StoreInst>(&I)) {
261228
if (Value *NoOpBitcast = maybeGenerateBitcast(
262229
Builder, PointerTypes, I, SI->getPointerOperand(),
263230
SI->getValueOperand()->getType())) {
@@ -268,51 +235,28 @@ class DXILPrepareModule : public ModulePass {
268235
}
269236
continue;
270237
}
271-
if (auto GEP = dyn_cast<GetElementPtrInst>(&I)) {
238+
if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
272239
if (Value *NoOpBitcast = maybeGenerateBitcast(
273240
Builder, PointerTypes, I, GEP->getPointerOperand(),
274241
GEP->getSourceElementType()))
275242
GEP->setOperand(0, NoOpBitcast);
276243
continue;
277244
}
278-
if (auto *CB = dyn_cast<CallBase>(&I)) {
279-
CB->removeFnAttrs(AttrMask);
280-
CB->removeRetAttrs(AttrMask);
281-
for (size_t Idx = 0, End = CB->arg_size(); Idx < End; ++Idx)
282-
CB->removeParamAttrs(Idx, AttrMask);
283-
continue;
284-
}
285245
}
286246
}
287247
}
288-
// Remove flags not for DXIL.
289-
cleanModuleFlags(M);
290-
291-
// dx.rootsignatures will have been parsed from its metadata form as its
292-
// binary form as part of the RootSignatureAnalysisWrapper, so safely
293-
// remove it as it is not recognized in DXIL
294-
if (NamedMDNode *RootSignature = M.getNamedMetadata("dx.rootsignatures"))
295-
RootSignature->eraseFromParent();
296-
297-
// llvm.errno.tbaa was recently added but is not supported in LLVM 3.7 and
298-
// causes all tests using the DXIL Validator to fail.
299-
//
300-
// This is a temporary fix and should be replaced with a whitelist once
301-
// we have determined all metadata that the DXIL Validator allows
302-
if (NamedMDNode *ErrNo = M.getNamedMetadata("llvm.errno.tbaa"))
303-
ErrNo->eraseFromParent();
304248

305249
return true;
306250
}
307251

308252
DXILPrepareModule() : ModulePass(ID) {}
309253
void getAnalysisUsage(AnalysisUsage &AU) const override {
310254
AU.addRequired<DXILMetadataAnalysisWrapperPass>();
311-
AU.addRequired<RootSignatureAnalysisWrapper>();
312-
AU.addPreserved<RootSignatureAnalysisWrapper>();
313-
AU.addPreserved<ShaderFlagsAnalysisWrapper>();
255+
314256
AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
315257
AU.addPreserved<DXILResourceWrapperPass>();
258+
AU.addPreserved<RootSignatureAnalysisWrapper>();
259+
AU.addPreserved<ShaderFlagsAnalysisWrapper>();
316260
}
317261
static char ID; // Pass identification.
318262
};
@@ -323,7 +267,6 @@ char DXILPrepareModule::ID = 0;
323267
INITIALIZE_PASS_BEGIN(DXILPrepareModule, DEBUG_TYPE, "DXIL Prepare Module",
324268
false, false)
325269
INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
326-
INITIALIZE_PASS_DEPENDENCY(RootSignatureAnalysisWrapper)
327270
INITIALIZE_PASS_END(DXILPrepareModule, DEBUG_TYPE, "DXIL Prepare Module", false,
328271
false)
329272

0 commit comments

Comments
 (0)