Skip to content

Commit 83febf9

Browse files
authored
[SYCL] Fix debug info generation when integration footer is present (#6774)
This patch is to fix two known issues with debugging caused by integration footer presence, without redesigning the integration footer approach. One issue is the missing checksum for the main file on Windows. This causes the breakpoints not being hit. The other issue being that the host compilation's DICompileUnit points to the temporary file created instead of the original source file. So file names and checksums are different for host and compilation. The changes made to fix the issues are: 1. Driver passes an absolute path to an original source file through -main-file-name if integration footer is enabled. 2. Driver passes a full path to the original source file through -full-main-file-name. 3. Clang CodeGen uses the file specified through -main-file-name and full-main-file-name to calculate checksums and file names for the main file. Joint work with @AlexeySachkov Signed-off-by: Zahira Ammarguellat <[email protected]>
1 parent 436798f commit 83febf9

File tree

10 files changed

+149
-6
lines changed

10 files changed

+149
-6
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,10 @@ CODEGENOPT(SkipRaxSetup, 1, 0)
488488
ENUM_CODEGENOPT(ZeroCallUsedRegs, llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind,
489489
5, llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip)
490490

491+
/// Whether to expect -main-file-name to be an absolute path to use it for
492+
/// checksum calculations or not.
493+
CODEGENOPT(SYCLUseMainFileName, 1, 0)
494+
491495
/// Whether to use opaque pointers.
492496
CODEGENOPT(OpaquePointers, 1, 0)
493497

clang/include/clang/Basic/CodeGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
220220
/// file, for example with -save-temps.
221221
std::string MainFileName;
222222

223+
/// The user provided name for the "main file", with its full path.
224+
std::string FullMainFileName;
225+
223226
/// The name for the split debug info file used for the DW_AT_[GNU_]dwo_name
224227
/// attribute in the skeleton CU.
225228
std::string SplitDwarfFile;

clang/include/clang/Driver/Options.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6156,6 +6156,10 @@ def main_file_name : Separate<["-"], "main-file-name">,
61566156
HelpText<"Main file name to use for debug info and source if missing">,
61576157
Flags<[CC1Option, CC1AsOption, NoDriverOption]>,
61586158
MarshallingInfoString<CodeGenOpts<"MainFileName">>;
6159+
def full_main_file_name : Separate<["-"], "full-main-file-name">,
6160+
HelpText<"File name with full path to use for debug info during host and device compile">,
6161+
Flags<[CC1Option, CC1AsOption, NoDriverOption]>,
6162+
MarshallingInfoString<CodeGenOpts<"FullMainFileName">>;
61596163
def split_dwarf_output : Separate<["-"], "split-dwarf-output">,
61606164
HelpText<"File name to use for split dwarf debug info output">,
61616165
Flags<[CC1Option, CC1AsOption, NoDriverOption]>,
@@ -6517,6 +6521,10 @@ def fsycl_disable_range_rounding : Flag<["-"], "fsycl-disable-range-rounding">,
65176521
def fsycl_enable_int_header_diags: Flag<["-"], "fsycl-enable-int-header-diags">,
65186522
HelpText<"Enable diagnostics that require the SYCL integration header.">,
65196523
MarshallingInfoFlag<LangOpts<"SYCLEnableIntHeaderDiags">>;
6524+
def fsycl_use_main_file_name : Flag<["-"], "fsycl-use-main-file-name">,
6525+
HelpText<"Tells compiler that -main-file-name contains an absolute path and "
6526+
"file specified there should be used for checksum calculation.">,
6527+
MarshallingInfoFlag<CodeGenOpts<"SYCLUseMainFileName">>;
65206528

65216529
} // let Flags = [CC1Option, NoDriverOption]
65226530

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,19 @@ Optional<StringRef> CGDebugInfo::getSource(const SourceManager &SM,
376376
return Source;
377377
}
378378

379+
// Compute valid FID for FileName.
380+
FileID ComputeValidFileID(SourceManager &SM, StringRef FileName) {
381+
FileID MainFileID = SM.getMainFileID();
382+
// Find the filename FileName and load it.
383+
llvm::Expected<FileEntryRef> ExpectedFileRef =
384+
SM.getFileManager().getFileRef(FileName);
385+
if (ExpectedFileRef) {
386+
MainFileID = SM.getOrCreateFileID(ExpectedFileRef.get(),
387+
SrcMgr::CharacteristicKind::C_User);
388+
}
389+
return MainFileID;
390+
}
391+
379392
llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
380393
SourceManager &SM = CGM.getContext().getSourceManager();
381394
StringRef FileName;
@@ -408,6 +421,13 @@ llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
408421

409422
SmallString<32> Checksum;
410423

424+
if (SM.getFileEntryForID(SM.getMainFileID()) &&
425+
CGM.getCodeGenOpts().SYCLUseMainFileName && FID.isInvalid())
426+
// When an integration footer is involved, the main file is a temporary
427+
// file generated by the compiler. FileName is pointing to original user
428+
// source file. We use it here to properly calculate its checksum.
429+
FID = ComputeValidFileID(SM, FileName);
430+
411431
Optional<llvm::DIFile::ChecksumKind> CSKind = computeChecksum(FID, Checksum);
412432
Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
413433
if (CSKind)
@@ -514,22 +534,37 @@ void CGDebugInfo::CreateCompileUnit() {
514534
// Get absolute path name.
515535
SourceManager &SM = CGM.getContext().getSourceManager();
516536
std::string MainFileName = CGM.getCodeGenOpts().MainFileName;
537+
std::string FullMainFileName = CGM.getCodeGenOpts().FullMainFileName;
517538
if (MainFileName.empty())
518539
MainFileName = "<stdin>";
519540

520541
// The main file name provided via the "-main-file-name" option contains just
521542
// the file name itself with no path information. This file name may have had
522543
// a relative path, so we look into the actual file entry for the main
523544
// file to determine the real absolute path for the file.
545+
// An exception here is workflow when integration footer is involved: in that
546+
// case driver passes an absolute path to the original user-provided source
547+
// file, whilst main file corresponds to a temporary file generated by the
548+
// compiler.
524549
std::string MainFileDir;
525550
if (Optional<FileEntryRef> MainFile =
526551
SM.getFileEntryRefForID(SM.getMainFileID())) {
527552
MainFileDir = std::string(MainFile->getDir().getName());
528-
if (!llvm::sys::path::is_absolute(MainFileName)) {
553+
FileID MainFileID = SM.getMainFileID();
554+
if (!llvm::sys::path::is_absolute(MainFileName) &&
555+
!CGM.getCodeGenOpts().SYCLUseMainFileName) {
529556
llvm::SmallString<1024> MainFileDirSS(MainFileDir);
530557
llvm::sys::path::append(MainFileDirSS, MainFileName);
531558
MainFileName =
532559
std::string(llvm::sys::path::remove_leading_dotslash(MainFileDirSS));
560+
} else if (CGM.getCodeGenOpts().SYCLUseMainFileName) {
561+
// When an integration footer is involved, the main file is a temporary
562+
// file generated by the compiler. FullMainFileName is pointing to
563+
// original user source file. We use it here to properly calculate its
564+
// checksum.
565+
MainFileID = ComputeValidFileID(SM, FullMainFileName);
566+
// Make sure the filename points to the original user source filename.
567+
MainFileName = FullMainFileName;
533568
}
534569
// If the main file name provided is identical to the input file name, and
535570
// if the input file is a preprocessed source, use the module name for
@@ -541,7 +576,7 @@ void CGDebugInfo::CreateCompileUnit() {
541576
.isPreprocessed())
542577
MainFileName = CGM.getModule().getName().str();
543578

544-
CSKind = computeChecksum(SM.getMainFileID(), Checksum);
579+
CSKind = computeChecksum(MainFileID, Checksum);
545580
}
546581

547582
llvm::dwarf::SourceLanguage LangTag;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5449,8 +5449,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
54495449
// Set the main file name, so that debug info works even with
54505450
// -save-temps.
54515451
CmdArgs.push_back("-main-file-name");
5452-
CmdArgs.push_back(getBaseInputName(Args, Input));
5452+
if (!IsSYCL || Args.hasArg(options::OPT_fno_sycl_use_footer)) {
5453+
CmdArgs.push_back(getBaseInputName(Args, Input));
5454+
} else {
5455+
SmallString<256> AbsPath = llvm::StringRef(Input.getBaseInput());
5456+
D.getVFS().makeAbsolute(AbsPath);
5457+
CmdArgs.push_back(
5458+
Args.MakeArgString(llvm::sys::path::filename(Input.getBaseInput())));
5459+
CmdArgs.push_back("-fsycl-use-main-file-name");
5460+
}
54535461

5462+
if (IsSYCL || Args.hasArg(options::OPT_fsycl_footer_path_EQ)) {
5463+
CmdArgs.push_back("-full-main-file-name");
5464+
CmdArgs.push_back(Input.getBaseInput());
5465+
}
54545466
// Some flags which affect the language (via preprocessor
54555467
// defines).
54565468
if (Args.hasArg(options::OPT_static))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
int main() {
2+
int x = 0;
3+
return x + 1;
4+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include "Inputs/sycl.hpp"
2+
3+
int main() {
4+
sycl::sampler Sampler;
5+
sycl::kernel_single_task<class use_kernel_for_test>([=]() {
6+
Sampler.use();
7+
});
8+
return 0;
9+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// This file attempts to emulate content of a file, which is passed to host
2+
// compiler when integration footer is used: this file is considered to be a
3+
// main file and Inputs/debug-info-checksum.cpp serves as integration footer.
4+
//
5+
// The file is specifically named debug-info-checksum-temp-name.cpp to emulate
6+
// the temporary file name, which is generated by the compiler driver for the
7+
// host .cpp file after appending footer to it.
8+
//
9+
// The command line executed is based on what is actually invoked by the
10+
// compiler driver and we explicitly pass 'Inputs/debug-info-checksum.cpp' as
11+
// a main file name to ensure that we can instruct the compiler to emit the
12+
// correct debug info (paths and checksums), even though the input file is not
13+
// exactly what user specified on the command line.
14+
//
15+
// RUN: %clang_cc1 -fsycl-is-host -I %S %S/Inputs/debug-info-checksum.cpp \
16+
// RUN: -triple x86_64-unknown-linux-gpu \
17+
// RUN: -main-file-name "%S/Inputs/debug-info-checksum.cpp" \
18+
// RUN: -full-main-file-name "%S/Inputs/debug-info-checksum.cpp" \
19+
// RUN: -fsycl-use-main-file-name -dwarf-version=5 -S -emit-llvm \
20+
// RUN: -O0 -debug-info-kind=constructor -o - | FileCheck %s
21+
//
22+
// Verify that DICompileUnit points to a correct file and that checksum is also
23+
// correct.
24+
//
25+
// CHECK: !DICompileUnit({{.*}} file: ![[#FILE:]]
26+
// CHECK: ![[#FILE]] = !DIFile(filename: "{{.*}}clang{{.+}}test{{.+}}CodeGenSYCL{{.+}}Inputs{{.+}}debug-info-checksum.cpp"
27+
// CHECK-SAME: checksumkind: CSK_MD5, checksum: "f1fb5d68350b47d90a53968ac8c40529"
28+
29+
#include "Inputs/debug-info-checksum.cpp"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// This test checks that a checksum is created correctly for the compiled file,
2+
// and that the same checksum is generated for host and target compilation.
3+
// It also checks that DICompileUnit in host and target compilation is referring
4+
// to the original source file name (not the temporary file created by the
5+
// compilation process) .
6+
7+
// RUN: %clang_cc1 -triple spir64-unknown-unknown -fsycl-is-device \
8+
// RUN: -fsycl-int-header=%t.header.h -fsycl-int-footer=%t.footer.h \
9+
// RUN: -main-file-name %S/Inputs/checksum.cpp -fsycl-use-main-file-name \
10+
// RUN: -full-main-file-name "%S/Inputs/checksum.cpp" \
11+
// RUN: -gcodeview -debug-info-kind=limited -emit-llvm -O0 -o - "%S/Inputs/checksum.cpp" \
12+
// RUN: | FileCheck %s -check-prefix=COMP1
13+
14+
// RUN: append-file "%S/Inputs/checksum.cpp" \
15+
// RUN: --append=%t.footer.h \
16+
// RUN: --orig-filename="%S/Inputs/checksum.cpp" \
17+
// RUN: --output=%t.checksum.cpp --use-include
18+
19+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsycl-is-host \
20+
// RUN: -include %t.header.h -dependency-filter %t.header.h \
21+
// RUN: -main-file-name %S/Inputs/checksum.cpp -fsycl-use-main-file-name \
22+
// RUN: -full-main-file-name %S/Inputs/checksum.cpp \
23+
// RUN: -gcodeview -debug-info-kind=limited -emit-llvm -O0 -o - \
24+
// RUN: %t.checksum.cpp \
25+
// RUN: | FileCheck %s -check-prefix=COMP2
26+
27+
// COMP1: !DICompileUnit({{.*}} file: ![[#FILE1:]]
28+
// COMP1: ![[#FILE1]] = !DIFile(filename: "{{.*}}clang{{.+}}test{{.+}}CodeGenSYCL{{.+}}checksum.cpp"
29+
// COMP1-SAME: checksumkind: CSK_MD5, checksum: "259269f735d83ec32c46a11352458493")
30+
31+
// COMP2: !DICompileUnit({{.*}} file: ![[#FILE2:]]
32+
// COMP2: ![[#FILE2]] = !DIFile(filename: "{{.*}}clang{{.+}}test{{.+}}CodeGenSYCL{{.+}}checksum.cpp"
33+
// COMP2-SAME: checksumkind: CSK_MD5, checksum: "259269f735d83ec32c46a11352458493")

clang/test/Driver/sycl-int-footer.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// RUN: | FileCheck -check-prefix FOOTER %s -DSRCDIR=%/S -DCMDDIR=cmdline/dir
44
// FOOTER: clang{{.*}} "-fsycl-is-device"{{.*}} "-fsycl-int-header=[[INTHEADER:.+\.h]]" "-fsycl-int-footer=[[INTFOOTER:.+\h]]" "-sycl-std={{.*}}"{{.*}} "-include" "dummy.h"
55
// FOOTER: append-file{{.*}} "[[INPUTFILE:.+\.cpp]]" "--append=[[INTFOOTER]]" "--orig-filename=[[INPUTFILE]]" "--output=[[APPENDEDSRC:.+\.cpp]]"
6-
// FOOTER: clang{{.*}} "-include" "[[INTHEADER]]"{{.*}} "-fsycl-is-host"{{.*}} "-include" "dummy.h"{{.*}} "-iquote" "[[SRCDIR]]" "-I" "cmdline/dir"
6+
// FOOTER: clang{{.*}} "-include" "[[INTHEADER]]"{{.*}} "-fsycl-is-host"{{.*}} "-main-file-name" "[[SRCFILE:.+\cpp]]" "-fsycl-use-main-file-name{{.*}} "-include" "dummy.h"{{.*}} "-iquote" "[[SRCDIR]]" "-I" "cmdline/dir"
77
// FOOTER-NOT: "-include" "[[INTHEADER]]"
88

99
/// Preprocessed file creation with integration footer
@@ -24,9 +24,15 @@
2424

2525
/// Check that integration footer can be disabled
2626
// RUN: %clangxx -fsycl -fno-sycl-use-footer %s -### 2>&1 \
27-
// RUN: | FileCheck -check-prefix NO-FOOTER --implicit-check-not "-fsycl-int-footer" %s
27+
// RUN: | FileCheck -check-prefix NO-FOOTER --implicit-check-not "-fsycl-int-footer" --implicit-check-not "-fsycl-use-main-file-name" %s
2828
// NO-FOOTER: clang{{.*}} "-fsycl-is-device"{{.*}} "-fsycl-int-header=[[INTHEADER:.+\.h]]" "-sycl-std={{.*}}"
29-
// NO-FOOTER: clang{{.*}} "-include" "[[INTHEADER]]"{{.*}} "-fsycl-is-host"{{.*}} "-o"
29+
// NO-FOOTER: clang{{.*}} "-include" "[[INTHEADER]]"{{.*}} "-fsycl-is-host"{{.*}} "-main-file-name" "sycl-int-footer.cpp"{{.*}} "-o"
30+
31+
// Test that -fsycl-use-main-file-name is not passed if -fsycl is not passed.
32+
// This test is located here, because -fsycl-use-main-file-name is tightly
33+
// connected to the integration footer.
34+
// RUN: %clangxx %s -### 2>&1 | FileCheck %s --check-prefix NO-FSYCL --implicit-check-not "-fsycl-use-main-file-name"
35+
// NO-FSYCL: clang{{.*}} "-main-file-name" "sycl-int-footer.cpp"
3036

3137
/// Check phases without integration footer
3238
// RUN: %clangxx -fsycl -fno-sycl-instrument-device-code -fno-sycl-device-lib=all -fno-sycl-use-footer -target x86_64-unknown-linux-gnu %s -ccc-print-phases 2>&1 \

0 commit comments

Comments
 (0)