77// ===----------------------------------------------------------------------===//
88
99#include " DXILTranslateMetadata.h"
10+ #include " DXILRootSignature.h"
1011#include " DXILShaderFlags.h"
1112#include " DirectX.h"
13+ #include " llvm/ADT/STLExtras.h"
1214#include " llvm/ADT/SmallVector.h"
1315#include " llvm/ADT/Twine.h"
1416#include " llvm/Analysis/DXILMetadataAnalysis.h"
@@ -290,42 +292,84 @@ static MDTuple *emitTopLevelLibraryNode(Module &M, MDNode *RMD,
290292 return constructEntryMetadata (nullptr , nullptr , RMD, Properties, Ctx);
291293}
292294
293- // TODO: We might need to refactor this to be more generic,
294- // in case we need more metadata to be replaced.
295- static void translateBranchMetadata (Module &M) {
296- for (Function &F : M) {
297- for (BasicBlock &BB : F) {
298- Instruction *BBTerminatorInst = BB. getTerminator () ;
295+ static void translateBranchMetadata (Module &M, Instruction *BBTerminatorInst) {
296+ MDNode *HlslControlFlowMD =
297+ BBTerminatorInst-> getMetadata ( " hlsl.controlflow.hint " );
298+
299+ if (!HlslControlFlowMD)
300+ return ;
299301
300- MDNode * HlslControlFlowMD =
301- BBTerminatorInst-> getMetadata ( " hlsl.controlflow.hint" );
302+ assert ( HlslControlFlowMD-> getNumOperands () == 2 &&
303+ " invalid operands for hlsl.controlflow.hint" );
302304
303- if (!HlslControlFlowMD)
304- continue ;
305+ MDBuilder MDHelper (M.getContext ());
306+ ConstantInt *Op1 =
307+ mdconst::extract<ConstantInt>(HlslControlFlowMD->getOperand (1 ));
305308
306- assert (HlslControlFlowMD->getNumOperands () == 2 &&
307- " invalid operands for hlsl.controlflow.hint" );
309+ SmallVector<llvm::Metadata *, 2 > Vals (
310+ ArrayRef<Metadata *>{MDHelper.createString (" dx.controlflow.hints" ),
311+ MDHelper.createConstant (Op1)});
308312
309- MDBuilder MDHelper (M.getContext ());
310- ConstantInt *Op1 =
311- mdconst::extract<ConstantInt>(HlslControlFlowMD->getOperand (1 ));
313+ MDNode *MDNode = llvm::MDNode::get (M.getContext (), Vals);
312314
313- SmallVector<llvm::Metadata *, 2 > Vals (
314- ArrayRef<Metadata *>{MDHelper. createString ( " dx .controlflow.hints " ),
315- MDHelper. createConstant (Op1)});
315+ BBTerminatorInst-> setMetadata ( " dx.controlflow.hints " , MDNode);
316+ BBTerminatorInst-> setMetadata ( " hlsl .controlflow.hint " , nullptr );
317+ }
316318
317- MDNode *MDNode = llvm::MDNode::get (M.getContext (), Vals);
319+ static std::array<unsigned , 6 > getCompatibleInstructionMDs (llvm::Module &M) {
320+ return {
321+ M.getMDKindID (" dx.nonuniform" ), M.getMDKindID (" dx.controlflow.hints" ),
322+ M.getMDKindID (" dx.precise" ), llvm::LLVMContext::MD_range,
323+ llvm::LLVMContext::MD_alias_scope, llvm::LLVMContext::MD_noalias};
324+ }
318325
319- BBTerminatorInst->setMetadata (" dx.controlflow.hints" , MDNode);
320- BBTerminatorInst->setMetadata (" hlsl.controlflow.hint" , nullptr );
326+ static void translateInstructionMetadata (Module &M) {
327+ // construct allowlist of valid metadata node kinds
328+ std::array<unsigned , 6 > DXILCompatibleMDs = getCompatibleInstructionMDs (M);
329+
330+ for (Function &F : M) {
331+ for (BasicBlock &BB : F) {
332+ // This needs to be done first so that "hlsl.controlflow.hints" isn't
333+ // removed in the whitelist below
334+ if (auto *I = BB.getTerminator ())
335+ translateBranchMetadata (M, I);
336+
337+ for (auto &I : make_early_inc_range (BB)) {
338+ I.dropUnknownNonDebugMetadata (DXILCompatibleMDs);
339+ }
321340 }
322341 }
323342}
324343
325- static void translateMetadata (Module &M, DXILResourceMap &DRM,
326- DXILResourceTypeMap &DRTM,
327- const ModuleShaderFlags &ShaderFlags,
328- const ModuleMetadataInfo &MMDI) {
344+ static void cleanModuleFlags (Module &M) {
345+ NamedMDNode *MDFlags = M.getModuleFlagsMetadata ();
346+ if (!MDFlags)
347+ return ;
348+
349+ SmallVector<llvm::Module::ModuleFlagEntry> FlagEntries;
350+ M.getModuleFlagsMetadata (FlagEntries);
351+ bool Updated = false ;
352+ for (auto &Flag : FlagEntries) {
353+ // llvm 3.7 only supports behavior up to AppendUnique.
354+ if (Flag.Behavior <= Module::ModFlagBehavior::AppendUnique)
355+ continue ;
356+ Flag.Behavior = Module::ModFlagBehavior::Warning;
357+ Updated = true ;
358+ }
359+
360+ if (!Updated)
361+ return ;
362+
363+ MDFlags->eraseFromParent ();
364+
365+ for (auto &Flag : FlagEntries)
366+ M.addModuleFlag (Flag.Behavior , Flag.Key ->getString (), Flag.Val );
367+ }
368+
369+ static void translateGlobalMetadata (Module &M, DXILResourceMap &DRM,
370+ DXILResourceTypeMap &DRTM,
371+ const ModuleShaderFlags &ShaderFlags,
372+ const ModuleMetadataInfo &MMDI) {
329373 LLVMContext &Ctx = M.getContext ();
330374 IRBuilder<> IRB (Ctx);
331375 SmallVector<MDNode *> EntryFnMDNodes;
@@ -381,6 +425,14 @@ static void translateMetadata(Module &M, DXILResourceMap &DRM,
381425 M.getOrInsertNamedMetadata (" dx.entryPoints" );
382426 for (auto *Entry : EntryFnMDNodes)
383427 EntryPointsNamedMD->addOperand (Entry);
428+
429+ cleanModuleFlags (M);
430+
431+ // dx.rootsignatures will have been parsed from its metadata form as its
432+ // binary form as part of the RootSignatureAnalysisWrapper, so safely
433+ // remove it as it is not recognized in DXIL
434+ if (NamedMDNode *RootSignature = M.getNamedMetadata (" dx.rootsignatures" ))
435+ RootSignature->eraseFromParent ();
384436}
385437
386438PreservedAnalyses DXILTranslateMetadata::run (Module &M,
@@ -390,8 +442,8 @@ PreservedAnalyses DXILTranslateMetadata::run(Module &M,
390442 const ModuleShaderFlags &ShaderFlags = MAM.getResult <ShaderFlagsAnalysis>(M);
391443 const dxil::ModuleMetadataInfo MMDI = MAM.getResult <DXILMetadataAnalysis>(M);
392444
393- translateMetadata (M, DRM, DRTM, ShaderFlags, MMDI);
394- translateBranchMetadata (M);
445+ translateGlobalMetadata (M, DRM, DRTM, ShaderFlags, MMDI);
446+ translateInstructionMetadata (M);
395447
396448 return PreservedAnalyses::all ();
397449}
@@ -409,6 +461,8 @@ class DXILTranslateMetadataLegacy : public ModulePass {
409461 AU.addRequired <DXILResourceWrapperPass>();
410462 AU.addRequired <ShaderFlagsAnalysisWrapper>();
411463 AU.addRequired <DXILMetadataAnalysisWrapperPass>();
464+ AU.addRequired <RootSignatureAnalysisWrapper>();
465+ AU.addPreserved <RootSignatureAnalysisWrapper>();
412466 AU.addPreserved <DXILResourceWrapperPass>();
413467 AU.addPreserved <DXILMetadataAnalysisWrapperPass>();
414468 AU.addPreserved <ShaderFlagsAnalysisWrapper>();
@@ -425,8 +479,8 @@ class DXILTranslateMetadataLegacy : public ModulePass {
425479 dxil::ModuleMetadataInfo MMDI =
426480 getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata ();
427481
428- translateMetadata (M, DRM, DRTM, ShaderFlags, MMDI);
429- translateBranchMetadata (M);
482+ translateGlobalMetadata (M, DRM, DRTM, ShaderFlags, MMDI);
483+ translateInstructionMetadata (M);
430484 return true ;
431485 }
432486};
@@ -443,6 +497,7 @@ INITIALIZE_PASS_BEGIN(DXILTranslateMetadataLegacy, "dxil-translate-metadata",
443497 " DXIL Translate Metadata" , false , false )
444498INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
445499INITIALIZE_PASS_DEPENDENCY(ShaderFlagsAnalysisWrapper)
500+ INITIALIZE_PASS_DEPENDENCY(RootSignatureAnalysisWrapper)
446501INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
447502INITIALIZE_PASS_END(DXILTranslateMetadataLegacy, " dxil-translate-metadata" ,
448503 " DXIL Translate Metadata" , false , false )
0 commit comments