Skip to content

[Driver][SYCL] Do device section checking only when offloading is enabled #5384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 26, 2022
Merged
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
102 changes: 55 additions & 47 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5539,6 +5539,59 @@ class OffloadingActionBuilder final {
/*BoundArch*/ nullptr, ActiveOffloadKinds);
return C.MakeAction<OffloadAction>(HDep, DDeps);
}

void unbundleStaticArchives(Compilation &C, DerivedArgList &Args,
DeviceActionBuilder::PhasesTy &PL) {
if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false))
return;

// Go through all of the args, and create a Linker specific argument list.
// When dealing with fat static archives each archive is individually
// unbundled.
SmallVector<const char *, 16> LinkArgs(getLinkerArgs(C, Args));
const llvm::opt::OptTable &Opts = C.getDriver().getOpts();
auto unbundleStaticLib = [&](types::ID T, const StringRef &A) {
Arg *InputArg = MakeInputArg(Args, Opts, Args.MakeArgString(A));
Action *Current = C.MakeAction<InputAction>(*InputArg, T);
addHostDependenceToDeviceActions(Current, InputArg, Args);
addDeviceDependencesToHostAction(Current, InputArg, phases::Link,
PL.back(), PL);
};
for (StringRef LA : LinkArgs) {
// At this point, we will process the archives for FPGA AOCO and
// individual archive unbundling for Windows.
if (!isStaticArchiveFile(LA))
continue;
// FPGA AOCX/AOCR files are archives, but we do not want to unbundle them
// here as they have already been unbundled and processed for linking.
// TODO: The multiple binary checks for FPGA types getting a little out
// of hand. Improve this by doing a single scan of the args and holding
// that in a data structure for reference.
if (hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCX) ||
hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCR) ||
hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCR_EMU))
continue;
// For offload-static-libs we add an unbundling action for each static
// archive which produces list files with extracted objects. Device lists
// are then added to the appropriate device link actions and host list is
// ignored since we are adding offload-static-libs as normal libraries to
// the host link command.
if (hasOffloadSections(C, LA, Args)) {
// Pass along the static libraries to check if we need to add them for
// unbundling for FPGA AOT static lib usage. Uses FPGA aoco type to
// differentiate if aoco unbundling is needed. Unbundling of aoco is
// not needed for emulation, as these are treated as regular archives.
if (!C.getDriver().isFPGAEmulationMode())
unbundleStaticLib(types::TY_FPGA_AOCO, LA);
// Do not unbundle any AOCO archive as a regular archive when we are
// in FPGA Hardware/Simulation mode.
if (!C.getDriver().isFPGAEmulationMode() &&
hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCO))
continue;
unbundleStaticLib(types::TY_Archive, LA);
}
}
}
};
} // anonymous namespace.

Expand Down Expand Up @@ -5880,52 +5933,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
if (!LinkerInputs.empty() && C.getDriver().getOffloadStaticLibSeen())
OffloadBuilder.addDeviceLinkDependenciesFromHost(LinkerInputs);

// Go through all of the args, and create a Linker specific argument list.
// When dealing with fat static archives each archive is individually
// unbundled.
SmallVector<const char *, 16> LinkArgs(getLinkerArgs(C, Args));
const llvm::opt::OptTable &Opts = getOpts();
auto unbundleStaticLib = [&](types::ID T, const StringRef &A) {
Arg *InputArg = MakeInputArg(Args, Opts, Args.MakeArgString(A));
Action *Current = C.MakeAction<InputAction>(*InputArg, T);
OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg, Args);
OffloadBuilder.addDeviceDependencesToHostAction(
Current, InputArg, phases::Link, PL.back(), PL);
};
for (StringRef LA : LinkArgs) {
// At this point, we will process the archives for FPGA AOCO and individual
// archive unbundling for Windows.
if (!isStaticArchiveFile(LA))
continue;
// FPGA AOCX/AOCR files are archives, but we do not want to unbundle them
// here as they have already been unbundled and processed for linking.
// TODO: The multiple binary checks for FPGA types getting a little out
// of hand. Improve this by doing a single scan of the args and holding
// that in a data structure for reference.
if (hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCX) ||
hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCR) ||
hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCR_EMU))
continue;
// For offload-static-libs we add an unbundling action for each static
// archive which produces list files with extracted objects. Device lists
// are then added to the appropriate device link actions and host list is
// ignored since we are adding offload-static-libs as normal libraries to
// the host link command.
if (hasOffloadSections(C, LA, Args)) {
// Pass along the static libraries to check if we need to add them for
// unbundling for FPGA AOT static lib usage. Uses FPGA aoco type to
// differentiate if aoco unbundling is needed. Unbundling of aoco is not
// needed for emulation, as these are treated as regular archives.
if (!C.getDriver().isFPGAEmulationMode())
unbundleStaticLib(types::TY_FPGA_AOCO, LA);
// Do not unbundle any AOCO archive as a regular archive when we are
// in FPGA Hardware/Simulation mode.
if (!C.getDriver().isFPGAEmulationMode() &&
hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCO))
continue;
unbundleStaticLib(types::TY_Archive, LA);
}
}
OffloadBuilder.unbundleStaticArchives(C, Args, PL);

// For an FPGA archive, we add the unbundling step above to take care of
// the device side, but also unbundle here to extract the host side
Expand Down Expand Up @@ -5961,7 +5969,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
if (UnbundlerInput && !PL.empty()) {
if (auto *IA = dyn_cast<InputAction>(UnbundlerInput)) {
std::string FileName = IA->getInputArg().getAsString(Args);
Arg *InputArg = MakeInputArg(Args, Opts, FileName);
Arg *InputArg = MakeInputArg(Args, getOpts(), FileName);
OffloadBuilder.addHostDependenceToDeviceActions(UnbundlerInput,
InputArg, Args);
OffloadBuilder.addDeviceDependencesToHostAction(
Expand Down
14 changes: 14 additions & 0 deletions clang/test/Driver/sycl-offload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,17 @@
// RUN: %clangxx -### -Wl,-rpath,%S -fsycl -fintelfpga %t_empty.o %s 2>&1 \
// RUN: | FileCheck -check-prefix NO_DIR_CHECK %s
// NO_DIR_CHECK-NOT: clang-offload-bundler: error: '{{.*}}': Is a directory

// Device section checking only occur when offloading is enabled
// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl %S/Inputs/SYCL/liblin64.a %s 2>&1 \
// RUN: | FileCheck -check-prefix CHECK_SECTION %s
// RUN: %clangxx -### -target x86_64-unknown-linux-gnu %S/Inputs/SYCL/liblin64.a %s 2>&1 \
// RUN: | FileCheck -check-prefix NO_CHECK_SECTION %s
// CHECK_SECTION: clang-offload-bundler{{.*}} "-type=ao" "-targets=host-x86_64-unknown-linux-gnu"{{.*}} "-check-section"
// CHECK_SECTION: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocr-intel-unknown"{{.*}} "-check-section"
// CHECK_SECTION: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown"{{.*}} "-check-section"
// CHECK_SECTION: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocr_emu-intel-unknown"{{.*}} "-check-section"
// NO_CHECK_SECTION-NOT: clang-offload-bundler{{.*}} "-type=ao" "-targets=host-x86_64-unknown-linux-gnu"{{.*}} "-check-section"
// NO_CHECK_SECTION-NOT: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocr-intel-unknown"{{.*}} "-check-section"
// NO_CHECK_SECTION-NOT: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown"{{.*}} "-check-section"
// NO_CHECK_SECTION-NOT: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocr_emu-intel-unknown"{{.*}} "-check-section"