Skip to content

[Driver][SYCL][FPGA] Improve FPGA AOT when using Triple #3330

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 5 commits into from
Mar 14, 2021
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
78 changes: 41 additions & 37 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2793,10 +2793,8 @@ bool Driver::checkForOffloadStaticLib(Compilation &C,
if (isStaticArchiveFile(OLArg) && hasOffloadSections(C, OLArg, Args)) {
// FPGA binaries with AOCX or AOCR sections are not considered fat
// static archives.
if (Args.hasArg(options::OPT_fintelfpga))
return !(hasFPGABinary(C, OLArg.str(), types::TY_FPGA_AOCR) ||
hasFPGABinary(C, OLArg.str(), types::TY_FPGA_AOCX));
return true;
return !(hasFPGABinary(C, OLArg.str(), types::TY_FPGA_AOCR) ||
hasFPGABinary(C, OLArg.str(), types::TY_FPGA_AOCX));
}
return false;
}
Expand Down Expand Up @@ -3814,11 +3812,12 @@ class OffloadingActionBuilder final {
ActionList FullSYCLLinkBinaryList;
bool SYCLDeviceLibLinked = false;
FullSYCLLinkBinaryList.push_back(DeviceLinkAction);
// If used without -fintelfpga, -fsycl-link is used to wrap device
// objects for future host link. Device libraries should be linked
// by default to resolve any undefined reference.
if (!Args.hasArg(options::OPT_fintelfpga)) {
const auto *TC = ToolChains.front();
// If used without the FPGA target, -fsycl-link is used to wrap
// device objects for future host link. Device libraries should
// be linked by default to resolve any undefined reference.
const auto *TC = ToolChains.front();
if (TC->getTriple().getSubArch() !=
llvm::Triple::SPIRSubArch_fpga) {
SYCLDeviceLibLinked =
addSYCLDeviceLibs(TC, FullSYCLLinkBinaryList, true,
C.getDefaultToolChain()
Expand Down Expand Up @@ -3921,8 +3920,9 @@ class OffloadingActionBuilder final {
return ABRT_Inactive;
// For SYCL device libraries, don't need to add them to
// FPGAObjectInputs as there is no FPGA dep files inside.

if (Args.hasArg(options::OPT_fintelfpga) &&
const auto *TC = ToolChains.front();
if (TC->getTriple().getSubArch() ==
llvm::Triple::SPIRSubArch_fpga &&
!IsSYCLDeviceLibObj(FileName, C.getDefaultToolChain()
.getTriple()
.isWindowsMSVCEnvironment()))
Expand Down Expand Up @@ -4269,7 +4269,7 @@ class OffloadingActionBuilder final {
BEInputs.push_back(UnbundleAction);
};
// Send any known objects/archives through the unbundler to grab the
// dependency file associated.
// dependency file associated. This is only done for -fintelfpga.
for (Action *A : FPGAObjectInputs)
unbundleAdd(A, types::TY_FPGA_Dependencies);
for (Action *A : FPGAArchiveInputs)
Expand Down Expand Up @@ -4397,11 +4397,6 @@ class OffloadingActionBuilder final {
// -fsycl-device-code-split=per_source
DeviceCodeSplit = DeviceCodeSplitArg &&
DeviceCodeSplitArg->getValue() != StringRef("off");
// Device only compilation for -fsycl-link (no FPGA) and
// -fsycl-link-targets
CompileDeviceOnly =
(SYCLLinkTargets ||
(WrapDeviceOnlyBinary && !Args.hasArg(options::OPT_fintelfpga)));
// Gather information about the SYCL Ahead of Time targets. The targets
// are determined on the SubArch values passed along in the triple.
Arg *SYCLTargets =
Expand Down Expand Up @@ -4456,14 +4451,19 @@ class OffloadingActionBuilder final {
SYCLfpgaTriple = true;
}

// Device only compilation for -fsycl-link (no FPGA) and
// -fsycl-link-targets
CompileDeviceOnly =
(SYCLLinkTargets || (WrapDeviceOnlyBinary && !SYCLfpgaTriple));

// Set the FPGA output type based on command line (-fsycl-link).
if (auto * A = C.getInputArgs().getLastArg(options::OPT_fsycl_link_EQ))
FPGAOutType = (A->getValue() == StringRef("early"))
? types::TY_FPGA_AOCR : types::TY_FPGA_AOCX;

// Populate FPGA static archives that could contain dep files to be
// incorporated into the aoc compilation
if (SYCLfpgaTriple) {
if (SYCLfpgaTriple && Args.hasArg(options::OPT_fintelfpga)) {
SmallVector<const char *, 16> LinkArgs(getLinkerArgs(C, Args));
for (StringRef LA : LinkArgs) {
if (isStaticArchiveFile(LA) && hasOffloadSections(C, LA, Args)) {
Expand Down Expand Up @@ -4622,6 +4622,7 @@ class OffloadingActionBuilder final {
// is a bundle or not and if the input is not a bundle it assumes it is a
// host file. Therefore it is safe to create an unbundling action even if
// the input is not a bundle.
bool HasFPGATarget = false;
if (CanUseBundler && isa<InputAction>(HostAction) &&
InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
!InputArg->getOption().hasFlag(options::LinkerInput) &&
Expand All @@ -4631,9 +4632,12 @@ class OffloadingActionBuilder final {
ActionList HostActionList;
Action *A(HostAction);
// Only check for FPGA device information when using fpga SubArch.
if (Args.hasArg(options::OPT_fintelfpga) &&
!(HostAction->getType() == types::TY_Object &&
isObjectFile(InputName))) {
auto SYCLTCRange = C.getOffloadToolChains<Action::OFK_SYCL>();
for (auto TI = SYCLTCRange.first, TE = SYCLTCRange.second; TI != TE; ++TI)
HasFPGATarget |= TI->second->getTriple().getSubArch() ==
llvm::Triple::SPIRSubArch_fpga;
if (HasFPGATarget && !(HostAction->getType() == types::TY_Object &&
isObjectFile(InputName))) {
// Type FPGA aoco is a special case for -foffload-static-lib.
if (HostAction->getType() == types::TY_FPGA_AOCO) {
if (!hasFPGABinary(C, InputName, types::TY_FPGA_AOCO))
Expand Down Expand Up @@ -4678,10 +4682,9 @@ class OffloadingActionBuilder final {
// For unbundling of an FPGA AOCX binary, we want to link with the original
// FPGA device archive.
if ((OffloadKind == Action::OFK_None && CanUseBundler) ||
(Args.hasArg(options::OPT_fintelfpga) &&
((Args.hasArg(options::OPT_fsycl_link_EQ) &&
HostAction->getType() == types::TY_Object) ||
HostAction->getType() == types::TY_FPGA_AOCX)))
(HasFPGATarget && ((Args.hasArg(options::OPT_fsycl_link_EQ) &&
HostAction->getType() == types::TY_Object) ||
HostAction->getType() == types::TY_FPGA_AOCX)))
if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
HostAction = UA->getInputs().back();

Expand Down Expand Up @@ -5124,13 +5127,13 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// 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))
if (hasOffloadSections(C, LA, Args)) {
unbundleStaticLib(types::TY_Archive, LA);
// 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.
if (Args.hasArg(options::OPT_fintelfpga))
// 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.
unbundleStaticLib(types::TY_FPGA_AOCO, LA);
}
}

// For an FPGA archive, we add the unbundling step above to take care of
Expand Down Expand Up @@ -6089,16 +6092,17 @@ InputInfo Driver::BuildJobsForActionNoCache(
// unbundling action does not change the type of the output which can
// cause a overwrite.
InputInfo CurI;
bool IsFPGAObjLink = (JA->getType() == types::TY_Object &&
C.getInputArgs().hasArg(options::OPT_fintelfpga) &&
C.getInputArgs().hasArg(options::OPT_fsycl_link_EQ));
bool IsFPGAObjLink =
(JA->getType() == types::TY_Object &&
EffectiveTriple.getSubArch() == llvm::Triple::SPIRSubArch_fpga &&
C.getInputArgs().hasArg(options::OPT_fsycl_link_EQ));
if (C.getDriver().getOffloadStaticLibSeen() &&
JA->getType() == types::TY_Archive) {
// Host part of the unbundled static archive is not used.
if (UI.DependentOffloadKind == Action::OFK_Host)
continue;
// Host part of the unbundled object when -fintelfpga -fsycl-link is
// enabled is not used
// Host part of the unbundled object is not used when using the
// FPGA target and -fsycl-link is enabled.
if (UI.DependentOffloadKind == Action::OFK_Host && IsFPGAObjLink)
continue;
std::string TmpFileName = C.getDriver().GetTemporaryPath(
Expand Down Expand Up @@ -6140,8 +6144,8 @@ InputInfo Driver::BuildJobsForActionNoCache(
C.addTempFile(C.getArgs().MakeArgString(TmpFileName));
CurI = InputInfo(TI, TmpFile, TmpFile);
} else {
// Host part of the unbundled object is not used when -fintelfpga
// -fsycl-link is enabled
// Host part of the unbundled object is not used when -fsycl-link is
// enabled with FPGA target
if (UI.DependentOffloadKind == Action::OFK_Host && IsFPGAObjLink)
continue;
std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix(
Expand Down
19 changes: 10 additions & 9 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs) const {
const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
const bool IsIntelFPGA = Args.hasArg(options::OPT_fintelfpga);

CheckPreprocessingOptions(D, Args);

Expand Down Expand Up @@ -1143,16 +1144,14 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
C.addFailureResultFile(DepFile, &JA);
// Populate the named dependency file to be used in the bundle
// or passed to the offline compilation.
if (Args.hasArg(options::OPT_fintelfpga) &&
JA.isDeviceOffloading(Action::OFK_SYCL))
if (IsIntelFPGA && JA.isDeviceOffloading(Action::OFK_SYCL))
C.getDriver().addFPGATempDepFile(
DepFile, Clang::getBaseInputName(Args, Inputs[0]));
} else if (Output.getType() == types::TY_Dependencies) {
DepFile = Output.getFilename();
} else if (!ArgMD) {
DepFile = "-";
} else if (Args.hasArg(options::OPT_fintelfpga) &&
JA.isDeviceOffloading(Action::OFK_SYCL)) {
} else if (IsIntelFPGA && JA.isDeviceOffloading(Action::OFK_SYCL)) {
createFPGATempDepFile(DepFile);
} else {
DepFile = getDependencyFileName(Args, Inputs);
Expand Down Expand Up @@ -1208,8 +1207,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-module-file-deps");
}

if (!ArgM && Args.hasArg(options::OPT_fintelfpga) &&
JA.isDeviceOffloading(Action::OFK_SYCL)) {
if (!ArgM && IsIntelFPGA && JA.isDeviceOffloading(Action::OFK_SYCL)) {
// No dep generation option was provided, add all of the needed options
// to ensure a successful dep generation.
const char *DepFile;
Expand Down Expand Up @@ -7668,9 +7666,12 @@ void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA,
Triples += CurDep->getOffloadingArch();
}
}
bool IsFPGADepBundle = (TCArgs.hasArg(options::OPT_fintelfpga) &&
Output.getType() == types::TY_Object);
// For -fintelfpga, when bundling objects we also want to bundle up the
// If we see we are bundling for FPGA using -fintelfpga, add the
// dependency bundle
bool IsFPGADepBundle = TCArgs.hasArg(options::OPT_fintelfpga) &&
Output.getType() == types::TY_Object;

// For spir64_fpga target, when bundling objects we also want to bundle up the
// named dependency file.
// TODO - We are currently using the target triple inputs to slot a location
// of the dependency information into the bundle. It would be good to
Expand Down
6 changes: 6 additions & 0 deletions clang/test/Driver/sycl-intelfpga-static-lib-win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@
// RUN: | FileCheck -check-prefix=CHECK_UNBUNDLE %s
// CHECK_UNBUNDLE: clang-offload-bundler" "-type=aoo" "-targets=sycl-fpga_dep" "-inputs={{.*}}" "-outputs=[[DEPFILES:.+\.txt]]" "-unbundle"
// CHECK_UNBUNDLE: aoc{{.*}} "-dep-files=@[[DEPFILES]]"

/// Check for no unbundle and use of deps in static lib when using triple
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %t.lib -### 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK_NO_UNBUNDLE %s
// CHECK_NO_UNBUNDLE-NOT: clang-offload-bundler" "-type=aoo" "-targets=sycl-fpga_dep"
// CHECK_NO_UNBUNDLE-NOT: aoc{{.*}} "-dep-files={{.*}}"
6 changes: 6 additions & 0 deletions clang/test/Driver/sycl-intelfpga-static-lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,9 @@
// RUN: | FileCheck -check-prefix=CHECK_UNBUNDLE %s
// CHECK_UNBUNDLE: clang-offload-bundler" "-type=aoo" "-targets=sycl-fpga_dep" "-inputs={{.*}}" "-outputs=[[DEPFILES:.+\.txt]]" "-unbundle"
// CHECK_UNBUNDLE: aoc{{.*}} "-dep-files=@[[DEPFILES]]"

/// Check for no unbundle and use of deps in static lib when using triple
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %t.a -### 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK_NO_UNBUNDLE %s
// CHECK_NO_UNBUNDLE-NOT: clang-offload-bundler" "-type=aoo" "-targets=sycl-fpga_dep"
// CHECK_NO_UNBUNDLE-NOT: aoc{{.*}} "-dep-files={{.*}}"
1 change: 1 addition & 0 deletions clang/test/Driver/sycl-offload-intelfpga.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

/// Check SYCL headers path
// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %s 2>&1 \
// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-HEADERS-INTELFPGA %s
// CHK-HEADERS-INTELFPGA: clang{{.*}} "-internal-isystem" "{{.*}}bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl"

Expand Down
2 changes: 2 additions & 0 deletions clang/test/Driver/sycl-offload-with-split.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@
// RUN: %clang -### -fsycl -fno-sycl-device-code-split-esimd %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-SPLIT
// RUN: %clang_cl -### -fsycl -fno-sycl-device-code-split-esimd %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-SPLIT
// RUN: %clang -### -fsycl -fintelfpga %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-SPLIT
// RUN: %clang -### -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-SPLIT
// RUN: %clang_cl -### -fsycl -fintelfpga %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-SPLIT
// CHK-ESIMD-SPLIT: sycl-post-link{{.*}} "-split-esimd"
// CHK-NO-ESIMD-SPLIT-NOT: sycl-post-link{{.*}} "-split-esimd"
Expand All @@ -325,6 +326,7 @@
// RUN: %clang -### -fsycl -fno-sycl-device-code-lower-esimd %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-LOWER
// RUN: %clang_cl -### -fsycl -fno-sycl-device-code-lower-esimd %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-LOWER
// RUN: %clang -### -fsycl -fintelfpga %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-LOWER
// RUN: %clang -### -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-LOWER
// RUN: %clang_cl -### -fsycl -fintelfpga %s 2>&1 | FileCheck %s -check-prefixes=CHK-NO-ESIMD-LOWER
// CHK-ESIMD-LOWER: sycl-post-link{{.*}} "-lower-esimd"
// CHK-NO-ESIMD-LOWER-NOT: sycl-post-link{{.*}} "-lower-esimd"