Skip to content

[Driver][SYCL] Improve dependency file behaviors for -fintelfpga #1186

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 13 commits into from
Mar 5, 2020
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
1 change: 1 addition & 0 deletions clang/include/clang/Driver/Types.def
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,5 @@ TYPE("wholearchive", WholeArchive, INVALID, "a", phases
TYPE("fpga_aocx", FPGA_AOCX, INVALID, "aocx", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("fpga_aocr", FPGA_AOCR, INVALID, "aocr", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("fpga_aoco", FPGA_AOCO, INVALID, "aoco", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("fpga_dependencies", FPGA_Dependencies, INVALID, "d", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("none", Nothing, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
47 changes: 37 additions & 10 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3253,6 +3253,9 @@ class OffloadingActionBuilder final {
/// Type of output file for FPGA device compilation.
types::ID FPGAOutType = types::TY_FPGA_AOCX;

/// List of objects to extract FPGA dependency info from
ActionList FPGAObjectInputs;

/// List of CUDA architectures to use in this compilation with NVPTX targets.
SmallVector<CudaArch, 8> GpuArchList;

Expand Down Expand Up @@ -3417,8 +3420,12 @@ class OffloadingActionBuilder final {
// Check if the type of the file is the same as the action. Do not
// unbundle it if it is not. Do not unbundle .so files, for example,
// which are not object files.
if (IA->getType() == types::TY_Object && !isObjectFile(FileName))
return ABRT_Inactive;
if (IA->getType() == types::TY_Object) {
if (!isObjectFile(FileName))
return ABRT_Inactive;
if (Args.hasArg(options::OPT_fintelfpga))
FPGAObjectInputs.push_back(IA);
}
// When creating FPGA device fat objects, all host objects are
// partially linked. Gather that list here.
if (IA->getType() == types::TY_Object ||
Expand Down Expand Up @@ -3598,6 +3605,15 @@ class OffloadingActionBuilder final {
Action *DeviceBECompileAction;
ActionList BEActionList;
BEActionList.push_back(DeviceLinkAction);
for (Action *A : FPGAObjectInputs) {
// Send any known objects through the unbundler to grab the
// dependency file associated.
ActionList AL;
AL.push_back(A);
Action *UnbundleAction = C.MakeAction<OffloadUnbundlingJobAction>(
AL, types::TY_FPGA_Dependencies);
BEActionList.push_back(UnbundleAction);
}
for (const auto &A : DeviceLibObjects)
BEActionList.push_back(A);
DeviceBECompileAction =
Expand Down Expand Up @@ -5484,14 +5500,25 @@ InputInfo Driver::BuildJobsForActionNoCache(
DependentOffloadKind)}] =
CurI;
}

// Now that we have all the results generated, select the one that should be
// returned for the current depending action.
std::pair<const Action *, std::string> ActionTC = {
A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};
assert(CachedResults.find(ActionTC) != CachedResults.end() &&
"Result does not exist??");
Result = CachedResults[ActionTC];
// Do a check for a dependency file unbundle for FPGA. This is out of line
// from a regular unbundle, so just create and return the name of the
// unbundled file.
if (JA->getType() == types::TY_FPGA_Dependencies) {
std::string TmpFileName =
C.getDriver().GetTemporaryPath(llvm::sys::path::stem(BaseInput), "d");
const char *TmpFile =
C.addTempFile(C.getArgs().MakeArgString(TmpFileName));
Result = InputInfo(types::TY_FPGA_Dependencies, TmpFile, TmpFile);
UnbundlingResults.push_back(Result);
} else {
// Now that we have all the results generated, select the one that should
// be returned for the current depending action.
std::pair<const Action *, std::string> ActionTC = {
A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};
assert(CachedResults.find(ActionTC) != CachedResults.end() &&
"Result does not exist??");
Result = CachedResults[ActionTC];
}
} else if (JA->getType() == types::TY_Nothing)
Result = InputInfo(A, BaseInput);
else {
Expand Down
56 changes: 49 additions & 7 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,8 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
} else if (!ArgMD) {
DepFile = "-";
} else if (ArgMD->getOption().matches(options::OPT_MMD) &&
Args.hasArg(options::OPT_fintelfpga)) {
Args.hasArg(options::OPT_fintelfpga) &&
!Args.hasArg(options::OPT_c)) {
// When generating dependency files for FPGA AOT, the output files will
// always be named after the source file.
DepFile = Args.MakeArgString(Twine(getBaseInputStem(Args, Inputs)) + ".d");
Expand Down Expand Up @@ -6758,7 +6759,8 @@ const char *Clang::getDependencyFileName(const ArgList &Args,
const InputInfoList &Inputs) {
// FIXME: Think about this more.

if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
if (Arg *OutputOpt =
Args.getLastArg(options::OPT_o, options::OPT__SLASH_Fo)) {
SmallString<128> OutputFilename(OutputOpt->getValue());
llvm::sys::path::replace_extension(OutputFilename, llvm::Twine('d'));
return Args.MakeArgString(OutputFilename);
Expand Down Expand Up @@ -7070,6 +7072,20 @@ 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
// 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
// separate this out to an explicit option in the bundler for the dependency
// file as it does not match the type being bundled.
if (IsFPGADepBundle) {
Triples += ',';
Triples += Action::GetOffloadKindName(Action::OFK_SYCL);
Triples += '-';
Triples += llvm::Triple::getArchTypeName(llvm::Triple::fpga_dep);
}
CmdArgs.push_back(TCArgs.MakeArgString(Triples));

// Get bundled file command.
Expand All @@ -7094,6 +7110,14 @@ void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA,
}
UB += CurTC->getInputFilename(Inputs[I]);
}
// For -fintelfpga, when bundling objects we also want to bundle up the
// named dependency file.
if (IsFPGADepBundle) {
SmallString<128> CurOutput(Output.getFilename());
llvm::sys::path::replace_extension(CurOutput, "d");
UB += ',';
UB += CurOutput;
}
CmdArgs.push_back(TCArgs.MakeArgString(UB));

// All the inputs are encoded as commands.
Expand Down Expand Up @@ -7124,6 +7148,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
bool IsMSVCEnv =
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
types::ID InputType(Input.getType());
bool IsFPGADepUnbundle = (JA.getType() == types::TY_FPGA_Dependencies);

// For Linux, we have initial support for fat archives (archives which
// contain bundled objects). We will perform partial linking against the
Expand Down Expand Up @@ -7183,6 +7208,8 @@ void OffloadBundler::ConstructJobMultipleOutputs(
if (InputType == types::TY_FPGA_AOCO ||
(IsMSVCEnv && types::isArchive(InputType)))
TypeArg = "aoo";
if (IsFPGADepUnbundle)
TypeArg = "o";

// Get the type.
CmdArgs.push_back(TCArgs.MakeArgString(Twine("-type=") + TypeArg));
Expand Down Expand Up @@ -7238,7 +7265,15 @@ void OffloadBundler::ConstructJobMultipleOutputs(
Triples += Dep.DependentBoundArch;
}
}

if (IsFPGADepUnbundle) {
// 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
// separate this out to an explicit option in the bundler for the dependency
// file as it does not match the type being bundled.
Triples += Action::GetOffloadKindName(Action::OFK_SYCL);
Triples += '-';
Triples += llvm::Triple::getArchTypeName(llvm::Triple::fpga_dep);
}
CmdArgs.push_back(TCArgs.MakeArgString(Triples));

// Get bundled file command.
Expand All @@ -7248,10 +7283,17 @@ void OffloadBundler::ConstructJobMultipleOutputs(
// Get unbundled files command.
SmallString<128> UB;
UB += "-outputs=";
for (unsigned I = 0; I < Outputs.size(); ++I) {
if (I)
UB += ',';
UB += DepInfo[I].DependentToolChain->getInputFilename(Outputs[I]);
// When dealing with -fintelfpga, there is an additional unbundle step
// that occurs for the dependency file. In that case, do not use the
// dependent information, but just the output file.
if (IsFPGADepUnbundle)
UB += Outputs[0].getFilename();
else {
for (unsigned I = 0; I < Outputs.size(); ++I) {
if (I)
UB += ',';
UB += DepInfo[I].DependentToolChain->getInputFilename(Outputs[I]);
}
}
CmdArgs.push_back(TCArgs.MakeArgString(UB));
CmdArgs.push_back("-unbundle");
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/Driver/ToolChains/SYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C,
"Unsupported target");

InputInfoList ForeachInputs;
InputInfoList FPGADepFiles;
ArgStringList CmdArgs{"-o", Output.getFilename()};
for (const auto &II : Inputs) {
std::string Filename(II.getFilename());
Expand All @@ -217,6 +218,8 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C,
// Add any FPGA library lists. These come in as special tempfile lists.
CmdArgs.push_back(Args.MakeArgString(Twine("-library-list=") +
Filename));
else if (II.getType() == types::TY_FPGA_Dependencies)
FPGADepFiles.push_back(II);
else
CmdArgs.push_back(C.getArgs().MakeArgString(Filename));
}
Expand All @@ -229,8 +232,6 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C,
ForeachExt = "aocr";
}


InputInfoList FPGADepFiles;
for (auto *A : Args) {
// Any input file is assumed to have a dependency file associated
if (A->getOption().getKind() == Option::InputClass) {
Expand All @@ -240,7 +241,7 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C,
types::ID Ty = getToolChain().LookupTypeForExtension(Ext.drop_front());
if (Ty == types::TY_INVALID)
continue;
if (types::isSrcFile(Ty) || Ty == types::TY_Object) {
if (types::isSrcFile(Ty)) {
llvm::sys::path::replace_extension(FN, "d");
FPGADepFiles.push_back(InputInfo(types::TY_Dependencies,
Args.MakeArgString(FN), Args.MakeArgString(FN)));
Expand Down
53 changes: 53 additions & 0 deletions clang/test/Driver/sycl-offload-intelfpga.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,65 @@
// RUN: touch %t-2.cpp
// RUN: %clangxx -### -fsycl -fintelfpga %t-1.cpp %t-2.cpp -o %t.out 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES %s
// RUN: %clang_cl -### -fsycl -fintelfpga %t-1.cpp %t-2.cpp -o %t.out 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES %s
// RUN: %clangxx -### -fsycl -fintelfpga %t-1.cpp %t-2.cpp 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES %s
// RUN: %clang_cl -### -fsycl -fintelfpga %t-1.cpp %t-2.cpp 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES %s
// CHK-FPGA-DEP-FILES: clang{{.*}} "-dependency-file" "[[INPUT1:.+\.d]]"
// CHK-FPGA-DEP-FILES: clang{{.*}} "-dependency-file" "[[INPUT2:.+\.d]]"
// CHK-FPGA-DEP-FILES: aoc{{.*}} "-dep-files={{.*}}[[INPUT1]],{{.*}}[[INPUT2]]"

/// -fintelfpga dependency file generation test to object
// RUN: %clangxx -### -fsycl -fintelfpga %t-1.cpp %t-2.cpp -c 2>&1 \
// RUN: | FileCheck -check-prefixes=CHK-FPGA-DEP-FILES2,CHK-FPGA-DEP-FILES2-LIN %s
// RUN: %clang_cl -### -fsycl -fintelfpga %t-1.cpp %t-2.cpp -c 2>&1 \
// RUN: | FileCheck -check-prefixes=CHK-FPGA-DEP-FILES2,CHK-FPGA-DEP-FILES2-WIN %s
// CHK-FPGA-DEP-FILES2: clang{{.*}} "-dependency-file" "[[INPUT1:.+\.d]]"
// CHK-FPGA-DEP-FILES2-LIN: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64_fpga-unknown-unknown-sycldevice,host-x86_64-unknown-linux-gnu,sycl-fpga_dep" {{.*}} "-inputs={{.*}}.bc,{{.*}}.o,[[INPUT1]]"
// CHK-FPGA-DEP-FILES2-WIN: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64_fpga-unknown-unknown-sycldevice-coff,host-x86_64-pc-windows-msvc,sycl-fpga_dep" {{.*}} "-inputs={{.*}}.bc,{{.*}}.obj,[[INPUT1]]"
// CHK-FPGA-DEP-FILES2: clang{{.*}} "-dependency-file" "[[INPUT2:.+\.d]]"
// CHK-FPGA-DEP-FILES2-LIN: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64_fpga-unknown-unknown-sycldevice,host-x86_64-unknown-linux-gnu,sycl-fpga_dep" {{.*}} "-inputs={{.*}}.bc,{{.*}}.o,[[INPUT2]]"
// CHK-FPGA-DEP-FILES2-WIN: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64_fpga-unknown-unknown-sycldevice-coff,host-x86_64-pc-windows-msvc,sycl-fpga_dep" {{.*}} "-inputs={{.*}}.bc,{{.*}}.obj,[[INPUT2]]"

/// -fintelfpga dependency file test to object with output designator
// RUN: touch %t-1.cpp
// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %t-1.cpp -c -o dummy.o 2>&1 \
// RUN: | FileCheck -check-prefixes=CHK-FPGA-DEP-FILES3,CHK-FPGA-DEP-FILES3-LIN %s
// RUN: %clang_cl -### -fsycl -fintelfpga %t-1.cpp -c -Fodummy.obj 2>&1 \
// RUN: | FileCheck -check-prefixes=CHK-FPGA-DEP-FILES3,CHK-FPGA-DEP-FILES3-WIN %s
// CHK-FPGA-DEP-FILES3: clang{{.*}} "-dependency-file" "[[OUTPUT:.+\.d]]"
// CHK-FPGA-DEP-FILES3-LIN: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64_fpga-unknown-unknown-sycldevice,host-x86_64-unknown-linux-gnu,sycl-fpga_dep" {{.*}} "-inputs={{.*}}.bc,{{.*}}.o,[[OUTPUT]]"
// CHK-FPGA-DEP-FILES3-WIN: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64_fpga-unknown-unknown-sycldevice-coff,host-x86_64-pc-windows-msvc,sycl-fpga_dep" {{.*}} "-inputs={{.*}}.bc,{{.*}}.obj,[[OUTPUT]]"

/// -fintelfpga dependency obj use test
// RUN: touch %t-1.o
// RUN: touch %t-2.o
// RUN: %clangxx -### -fsycl -fintelfpga %t-1.o %t-2.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES-OBJ -DINPUT1=%t-1.o -DINPUT2=%t-2.o %s
// RUN: %clang_cl -### -fsycl -fintelfpga %t-1.o %t-2.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES-OBJ -DINPUT1=%t-1.o -DINPUT2=%t-2.o %s
// CHK-FPGA-DEP-FILES-OBJ: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-fpga_dep" "-inputs=[[INPUT1]]" "-outputs=[[DEPFILE1:.+\.d]]" "-unbundle"
// CHK-FPGA-DEP-FILES-OBJ: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-fpga_dep" "-inputs=[[INPUT2]]" "-outputs=[[DEPFILE2:.+\.d]]" "-unbundle"
// CHK-FPGA-DEP-FILES-OBJ: aoc{{.*}} "-dep-files=[[DEPFILE1]],[[DEPFILE2]]

/// -fintelfpga dependency file use from object phases test
// RUN: touch %t-1.o
// RUN: %clangxx -fsycl -fintelfpga -ccc-print-phases -### %t-1.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES-OBJ-PHASES -DINPUT=%t-1.o %s
// RUN: %clang_cl -fsycl -fintelfpga -ccc-print-phases -### %t-1.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FPGA-DEP-FILES-OBJ-PHASES -DINPUT=%t-1.o %s
// CHK-FPGA-DEP-FILES-OBJ-PHASES: 0: input, "[[INPUT]]", object, (host-sycl)
// CHK-FPGA-DEP-FILES-OBJ-PHASES: 1: clang-offload-unbundler, {0}, object, (host-sycl)
// CHK-FPGA-DEP-FILES-OBJ-PHASES: 2: linker, {1}, image, (host-sycl)
// CHK-FPGA-DEP-FILES-OBJ-PHASES: 3: linker, {1}, ir, (device-sycl)
// CHK-FPGA-DEP-FILES-OBJ-PHASES: 4: llvm-spirv, {3}, spirv, (device-sycl)
// CHK-FPGA-DEP-FILES-OBJ-PHASES: 5: clang-offload-unbundler, {0}, fpga_dependencies
// CHK-FPGA-DEP-FILES-OBJ-PHASES: 6: backend-compiler, {4, 5}, fpga_aocx, (device-sycl)
// CHK-FPGA-DEP-FILES-OBJ-PHASES: 7: clang-offload-wrapper, {6}, object, (device-sycl)
// CHK-FPGA-DEP-FILES-OBJ-PHASES: 8: offload, "host-sycl (x86_64-{{unknown-linux-gnu|pc-windows-msvc}})" {2}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice{{(-coff)?}})" {7}, image

/// -fintelfpga output report file test
// RUN: mkdir -p %t_dir
// RUN: %clangxx -### -fsycl -fintelfpga %s -o %t_dir/file.out 2>&1 \
Expand Down
Loading