Skip to content

Commit b6d5a10

Browse files
authored
[SYCL][thinLTO] Split early when thinLTO is enabled (#14259)
This change implements driver changes to call `sycl-post-link` during `-c` when thinLTO is enabled, and updates `clang-offload-packager` to accept response files (same format as temp file list), which will be generated when we call `clang` on each output of `sycl-post-link`. I will add a test for the `clang-offload-packager` changes later, because we rely on changes in other PRs to test the full flow. However, the code is already being hit because we compile `libdevice` with thinLTO when compiling for the new offload model. For a given file `a.cpp` that results in two total splits, the following will happen: 1) We call `sycl-post-link` on `a.bc` 2) We extract the "Code" column from the table output of `sycl-post-link` 3) We call `llvm-foreach` with the regular backend job that would be called normally on each `bc` file from 2) 4) We call `clang-offload-packager` with the output of 3 which is a list of the `bc` files from each `clang` run, with a '@' appended to the file path 5) `clang-offload-packager` reads each entry inside 4) and adds each to the fat object 6) `clang-linker-wrapper` extracts the fat object from 5) and finds all of the files 7) ... to be implemented --------- Signed-off-by: Sarnie, Nick <[email protected]>
1 parent d2c811b commit b6d5a10

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8190,6 +8190,37 @@ Action *Driver::ConstructPhaseAction(
81908190
TargetDeviceOffloadKind != Action::OFK_None) {
81918191
types::ID Output =
81928192
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
8193+
if (getUseNewOffloadingDriver() &&
8194+
getLTOMode(/*IsDeviceOffloadAction=*/true) == LTOK_Thin &&
8195+
TargetDeviceOffloadKind == Action::OFK_SYCL) {
8196+
// For SYCL with thinLTO, run sycl-post-link, extract the BC files from
8197+
// the output table, run the backend on each output table.
8198+
llvm::Triple OffloadTriple =
8199+
Input->getOffloadingToolChain()->getTriple();
8200+
SYCLPostLinkJobAction *TypedPostLinkAction =
8201+
C.MakeAction<SYCLPostLinkJobAction>(Input, types::TY_Tempfiletable,
8202+
types::TY_Tempfiletable);
8203+
TypedPostLinkAction->setRTSetsSpecConstants(
8204+
OffloadTriple.isSPIROrSPIRV() && !OffloadTriple.isSPIRAOT());
8205+
auto *TypedExtractIRFilesAction = C.MakeAction<FileTableTformJobAction>(
8206+
TypedPostLinkAction, types::TY_Tempfilelist,
8207+
types::TY_Tempfilelist);
8208+
8209+
TypedExtractIRFilesAction->addExtractColumnTform(
8210+
FileTableTformJobAction::COL_CODE, false /*drop titles*/);
8211+
auto *OutputAction =
8212+
C.MakeAction<BackendJobAction>(TypedExtractIRFilesAction, Output);
8213+
8214+
auto *ForEach = C.MakeAction<ForEachWrappingAction>(
8215+
TypedExtractIRFilesAction, OutputAction);
8216+
// This final job is mostly a no-op, but we need it to set the Action
8217+
// type to Tempfilelist which is expected by clang-offload-packager.
8218+
auto *ExtractBCFiles = C.MakeAction<FileTableTformJobAction>(
8219+
ForEach, types::TY_Tempfilelist, types::TY_Tempfilelist);
8220+
ExtractBCFiles->addExtractColumnTform(FileTableTformJobAction::COL_ZERO,
8221+
false /*drop titles*/);
8222+
return ExtractBCFiles;
8223+
}
81938224
return C.MakeAction<BackendJobAction>(Input, Output);
81948225
}
81958226
if (Args.hasArg(options::OPT_emit_llvm) ||

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,11 @@ static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
593593
if (Args.hasArg(options::OPT_verify_pch) && Input.getType() == types::TY_PCH)
594594
return;
595595

596+
// If the input is a Tempfilelist, this call is part for a
597+
// llvm-foreach call and we should infer the type from the file extension.
598+
if (Input.getType() == types::TY_Tempfilelist)
599+
return;
600+
596601
CmdArgs.push_back("-x");
597602
if (Args.hasArg(options::OPT_rewrite_objc))
598603
CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
@@ -10250,6 +10255,13 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA,
1025010255
C.getArgsForToolChain(TC, OffloadAction->getOffloadingArch(),
1025110256
OffloadAction->getOffloadingDeviceKind());
1025210257
StringRef File = C.getArgs().MakeArgString(TC->getInputFilename(Input));
10258+
10259+
// If the input is a Tempfilelist, it is a response file
10260+
// which internally contains a list of files to be processed.
10261+
// Add an '@' so the tool knows to expand the response file.
10262+
if (Input.getType() == types::TY_Tempfilelist)
10263+
File = C.getArgs().MakeArgString("@" + File);
10264+
1025310265
StringRef Arch = OffloadAction->getOffloadingArch()
1025410266
? OffloadAction->getOffloadingArch()
1025510267
: TCArgs.getLastArgValue(options::OPT_march_EQ);

clang/test/Driver/sycl-lto.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
// RUN: not %clangxx -fsycl --offload-new-driver -foffload-lto=thin -fsycl-device-code-split=off %s -### 2>&1 | FileCheck -check-prefix=CHECK_SPLIT_ERROR %s
99
// CHECK_SPLIT_ERROR: '-fsycl-device-code-split=off' is not supported when '-foffload-lto=thin' is set with '-fsycl'
1010

11-
// Verify there's no error and we see the expected cc1 flags with the new offload driver.
11+
// Verify there's no error and we see the expected cc1 flags and tool invocations with the new offload driver.
1212
// RUN: %clangxx -fsycl --offload-new-driver -foffload-lto=thin %s -### 2>&1 | FileCheck -check-prefix=CHECK_SUPPORTED %s
1313
// CHECK_SUPPORTED: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown" {{.*}} "-flto=thin" "-flto-unit"
14+
// CHECK_SUPPORTED: sycl-post-link{{.*}}
15+
// CHECK_SUPPORTED-NEXT: file-table-tform{{.*}}
16+
// CHECK_SUPPORTED-NEXT: llvm-foreach{{.*}} "--" {{.*}}clang{{.*}} "-fsycl-is-device"{{.*}} "-flto=thin" "-flto-unit"
17+
// CHECK_SUPPORTED-NEXT: file-table-tform{{.*}}
18+
// CHECK_SUPPORTED-NEXT: clang-offload-packager{{.*}} "-o" "{{.*}}" "--image=file=@{{.*}}"
1419
// CHECK_SUPPORTED: clang-linker-wrapper{{.*}} "-sycl-thin-lto"

clang/tools/clang-offload-packager/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ set(LLVM_LINK_COMPONENTS
22
${LLVM_TARGETS_TO_BUILD}
33
BinaryFormat
44
Object
5-
Support)
5+
Support
6+
TargetParser)
67

78
add_clang_tool(clang-offload-packager
89
ClangOffloadPackager.cpp

clang/tools/clang-offload-packager/ClangOffloadPackager.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/Support/Signals.h"
2727
#include "llvm/Support/StringSaver.h"
2828
#include "llvm/Support/WithColor.h"
29+
#include "llvm/TargetParser/Host.h"
2930

3031
using namespace llvm;
3132
using namespace llvm::object;
@@ -63,13 +64,35 @@ static void PrintVersion(raw_ostream &OS) {
6364
OS << clang::getClangToolFullVersion("clang-offload-packager") << '\n';
6465
}
6566

67+
// For any response file arguments (those starting with '@'), expand them into
68+
// the contents of the response file, deliminated by commas.
69+
static StringRef expandResponseFileImageArguments(StringRef Arg,
70+
StringSaver &Saver) {
71+
std::string FileStr = Arg.str();
72+
SmallVector<const char *, 0> ExpandedFiles{FileStr.c_str()};
73+
cl::ExpandResponseFiles(Saver,
74+
Triple(sys::getProcessTriple()).isOSWindows()
75+
? cl::TokenizeWindowsCommandLine
76+
: cl::TokenizeGNUCommandLine,
77+
ExpandedFiles);
78+
std::string NewValue;
79+
for (size_t FileIdx = 0; FileIdx < ExpandedFiles.size(); FileIdx++) {
80+
NewValue += ExpandedFiles[FileIdx];
81+
if (FileIdx != ExpandedFiles.size() - 1)
82+
NewValue += ',';
83+
}
84+
return Saver.save(NewValue);
85+
}
86+
6687
// Get a map containing all the arguments for the image. Repeated arguments will
6788
// be placed in a comma separated list.
6889
static DenseMap<StringRef, StringRef> getImageArguments(StringRef Image,
6990
StringSaver &Saver) {
7091
DenseMap<StringRef, StringRef> Args;
7192
for (StringRef Arg : llvm::split(Image, ",")) {
7293
auto [Key, Value] = Arg.split("=");
94+
if (Key == "file" && Value[0] == '@')
95+
Value = expandResponseFileImageArguments(Value, Saver);
7396
if (Args.count(Key))
7497
Args[Key] = Saver.save(Args[Key] + "," + Value);
7598
else

0 commit comments

Comments
 (0)