Skip to content
Open
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
5 changes: 5 additions & 0 deletions clang/include/clang/Options/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -9624,6 +9624,11 @@ def dxc_Fc : DXCJoinedOrSeparate<"Fc">,
HelpText<"Output assembly listing file">;
def dxc_Frs : DXCJoinedOrSeparate<"Frs">,
HelpText<"Output additional root signature object file">;
def dxc_source_in_debug_module
: Option<["/", "-"], "Qsource_in_debug_module", KIND_FLAG>,
Group<dxc_Group>,
Visibility<[DXCOption]>,
HelpText<"Embed source code into debug module on DirectX target">;
Comment on lines +9627 to +9631
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You can shorten this by using class DXCFlag like other flags do.

def dxil_validator_version : Option<["/", "-"], "validator-version", KIND_SEPARATE>,
Group<dxc_Group>, Flags<[HelpHidden]>,
Visibility<[DXCOption, ClangOption, CC1Option]>,
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3832,6 +3832,11 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
if (!Args.hasArg(options::OPT_dxc_no_stdinc) &&
!Args.hasArg(options::OPT_nostdinc))
CmdArgs.push_back("-finclude-default-header");

if (Args.hasArg(options::OPT_dxc_source_in_debug_module)) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("--dx-source-in-debug-module");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should we use a single dash for all llc options, just for the sake of consistency? I think most of the options are used like that.

Copy link
Copy Markdown
Contributor Author

@dzhidzhoev dzhidzhoev Jun 2, 2026

Choose a reason for hiding this comment

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

Should we use a single dash for all llc options, just for the sake of consistency?

AFAIK most of llc options (which are rather target-specific or pass-specific) use double dash (that's what I see in llc --help output):

PS D:\llvm\build\native> bin\llc --help | grep -v -- '--' | grep -c '\-\S' (estimate the number of lines with single dash options)
32
PS D:\llvm\build\native> bin\llc --help | grep -c '\--'
219 

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hm, I was judging by how they are usually forwarded in Clang.cpp, no idea why is it like that.

}
}

static void RenderOpenACCOptions(const Driver &D, const ArgList &Args,
Expand Down
6 changes: 6 additions & 0 deletions clang/test/Driver/dxc_source_in_debug_module.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// RUN: %clang_dxc -Tlib_6_7 -### /Zi /Qsource_in_debug_module %s 2>&1 | FileCheck %s
// RUN: %clang_dxc -Tlib_6_7 -### /Zi -Qsource_in_debug_module %s 2>&1 | FileCheck %s
// RUN: %clang_dxc -Tlib_6_7 -### /Zi %s 2>&1 | FileCheck %s --check-prefix=NOFLAG

// CHECK: "-mllvm" "--dx-source-in-debug-module"
// NOFLAG-NOT: --dx-source-in-debug-module
11 changes: 7 additions & 4 deletions llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,15 +514,18 @@ static void cleanModuleFlags(Module &M) {
M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val);
}

using GlobalMDList = std::array<StringLiteral, 7>;
using GlobalMDList = std::array<StringLiteral, 11>;

// The following are compatible with DXIL but not emit with clang, they can
// be added when applicable:
// dx.typeAnnotations, dx.viewIDState, dx.dxrPayloadAnnotations
static GlobalMDList CompatibleNamedModuleMDs = {
"llvm.ident", "llvm.module.flags", "dx.resources", "dx.valver",
"dx.shaderModel", "dx.version", "dx.entryPoints",
};
"llvm.ident", "llvm.module.flags",
"dx.resources", "dx.valver",
"dx.shaderModel", "dx.version",
"dx.entryPoints", "dx.source.contents",
"dx.source.defines", "dx.source.mainFileName",
"dx.source.args"};

static void translateGlobalMetadata(Module &M, DXILResourceMap &DRM,
DXILResourceTypeMap &DRTM,
Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,17 @@
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Alignment.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

using namespace llvm;
using namespace llvm::dxil;

static cl::opt<bool> SourceInDebugModule(
"dx-source-in-debug-module",
cl::desc("Embed source code into debug module on DirectX target"),
cl::init(false));

namespace {
class WriteDXILPass : public llvm::ModulePass {
raw_ostream &OS; // raw_ostream to print on
Expand Down Expand Up @@ -138,6 +144,16 @@ static void removeLifetimeIntrinsics(Module &M) {
}
}

static void replaceNamedMetadataArray(Module &M, StringRef Name,
ArrayRef<Metadata *> NewOps) {
NamedMDNode *NMD = M.getNamedMetadata(Name);
if (!NMD)
return;
NMD->eraseFromParent();
M.getOrInsertNamedMetadata(Name)->addOperand(
MDTuple::get(M.getContext(), NewOps));
}

class EmbedDXILPass : public llvm::ModulePass {
public:
static char ID; // Pass identification, replacement for typeid
Expand All @@ -155,6 +171,16 @@ class EmbedDXILPass : public llvm::ModulePass {
// fail the Module Verifier if performed in an earlier pass
legalizeLifetimeIntrinsics(M);

// Replace dx.source metadata nodes with stubs.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is this meant to be merged with the current upstream? I'm guessing it needs backend PDB functionality to fully implement, shouldn't it be added later?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It does not strictly require PDB emission functionality.
It would be nice to merge this on top of ILDB part emission patch, but it's not on review as for now. I can postpone sending this PR to LLVM repo if needed.

if (!SourceInDebugModule) {
LLVMContext &Ctx = M.getContext();
MDString *EmptyString = MDString::get(Ctx, "");
replaceNamedMetadataArray(M, "dx.source.contents",
{EmptyString, EmptyString});
replaceNamedMetadataArray(M, "dx.source.defines", {});
replaceNamedMetadataArray(M, "dx.source.mainFileName", {EmptyString});
replaceNamedMetadataArray(M, "dx.source.args", {});
}
const auto DIMap = DXILDebugInfoPass::run(M);
WriteDXILToFile(M, OS, DIMap);

Expand Down
56 changes: 56 additions & 0 deletions llvm/test/CodeGen/DirectX/ContainerData/SourceInfo-Strip.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
; Compare source info emission with and without --dx-source-in-debug-module flag.

; RUN: llc %s --filetype=obj -o %t.dxbc
; RUN: llvm-objcopy --dump-section=DXIL=%t.dxil.bc %t.dxbc
; RUN: llvm-dis %t.dxil.bc -o - | FileCheck %s --check-prefix=ILDB-DIS

; RUN: llc %s --filetype=obj -o %t.dxbc --dx-source-in-debug-module
; RUN: llvm-objcopy --dump-section=DXIL=%t.dxil.bc %t.dxbc
; RUN: llvm-dis %t.dxil.bc -o - | FileCheck %s --check-prefix=ILDB-SOURCE-DIS

; Without the flag, dx.source should be replaced with dummy metadata.
; ILDB-DIS: !dx.source.contents = !{![[CONTENTS:[0-9]+]]}
; ILDB-DIS: !dx.source.defines = !{![[EMPTY_ARR:[0-9]+]]}
; ILDB-DIS: !dx.source.mainFileName = !{![[MAIN:[0-9]+]]}
; ILDB-DIS: !dx.source.args = !{![[EMPTY_ARR]]}
; ILDB-DIS: ![[CONTENTS]] = !{!"", !""}
; ILDB-DIS: ![[EMPTY_ARR]] = !{}
; ILDB-DIS: ![[MAIN]] = !{!""}

; With the flag, dx.source should be be preserved.
; ILDB-SOURCE-DIS: !dx.source.args = !{![[ARGS:[0-9]+]]}
; ILDB-SOURCE-DIS: !dx.source.contents = !{![[FILE1:[0-9]+]], ![[FILE2:[0-9]+]], ![[FILE3:[0-9]+]]}
; ILDB-SOURCE-DIS: !dx.source.mainFileName = !{![[MAIN:[0-9]+]]}
; ILDB-SOURCE-DIS: !dx.source.defines = !{![[DEFINES:[0-9]+]]}
; ILDB-SOURCE-DIS: ![[FILE1]] = !{!"C:\\dx-source-metadata.hlsl",
; ILDB-SOURCE-DIS: ![[FILE2]] = !{!"C:\\a.hlsl"
; ILDB-SOURCE-DIS: ![[FILE3]] = !{!"C:\\b.hlsl"
; ILDB-SOURCE-DIS: ![[MAIN]] = !{!"C:\\dx-source-metadata.hlsl"}
; ILDB-SOURCE-DIS: ![[DEFINES]] = !{!"USER_DEF0=42", !"USER_DEF1=43"}

target triple = "dxilv1.3-pc-shadermodel6.3-library"

define float @_Z3fooff(float %a, float %b) {
entry:
%add = fadd float %a, %b
ret float %add
}

!llvm.dbg.cu = !{!4}
!llvm.module.flags = !{!6, !7}

!dx.source.args = !{!0}
!dx.source.contents = !{!1, !2, !3}
!dx.source.mainFileName = !{!8}
!dx.source.defines = !{!9}

!0 = !{!"-g", !"-Tlib_6_3", !"-DUSER_DEF0=42", !"-DUSER_DEF1=43", !"C:\\\\dx-source-metadata.hlsl"}
!1 = !{!"C:\\dx-source-metadata.hlsl", !"#include \22a.hlsl\22\0A#include \22b.hlsl\22\0A\0Afloat foo(float a, float b) {\0A return a + b;\0A}\0A"}
!2 = !{!"C:\\a.hlsl", !"#include \22b.hlsl\22\0A"}
!3 = !{!"C:\\b.hlsl", !"#include <c.hlsl>\0A"}
!4 = distinct !DICompileUnit(language: DW_LANG_C99, file: !5, emissionKind: FullDebug)
!5 = !DIFile(filename: "dx-source-metadata.hlsl", directory: "C:\\")
!6 = !{i32 2, !"Dwarf Version", i32 4}
!7 = !{i32 2, !"Debug Info Version", i32 3}
!8 = !{!"C:\\dx-source-metadata.hlsl"}
!9 = !{!"USER_DEF0=42", !"USER_DEF1=43"}