forked from OSchip/llvm-project
[Driver][OpenMP] Update actions builder to create bundling action when necessary.
Summary: In order to save the user from dealing with multiple output files (for host and device) while using separate compilation, a new action `OffloadBundlingAction` is used when the last phase is not linking. This action will then result in a job that uses the proposed bundling tool to create a single preprocessed/IR/ASM/Object file from multiple ones. The job creation for the new action will be proposed in a separate patch. Reviewers: echristo, tra, jlebar, ABataev, hfinkel Subscribers: whchung, mehdi_amini, cfe-commits, Hahnfeld, andreybokhanko, arpith-jacob, carlo.bertolli, caomhin Differential Revision: https://reviews.llvm.org/D21852 llvm-svn: 285323
This commit is contained in:
parent
093abab817
commit
69d6f31f74
|
@ -66,9 +66,10 @@ public:
|
|||
DsymutilJobClass,
|
||||
VerifyDebugInfoJobClass,
|
||||
VerifyPCHJobClass,
|
||||
OffloadBundlingJobClass,
|
||||
|
||||
JobClassFirst = PreprocessJobClass,
|
||||
JobClassLast = VerifyPCHJobClass
|
||||
JobClassLast = OffloadBundlingJobClass
|
||||
};
|
||||
|
||||
// The offloading kind determines if this action is binded to a particular
|
||||
|
@ -481,6 +482,18 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class OffloadBundlingJobAction : public JobAction {
|
||||
void anchor() override;
|
||||
|
||||
public:
|
||||
// Offloading bundling doesn't change the type of output.
|
||||
OffloadBundlingJobAction(ActionList &Inputs);
|
||||
|
||||
static bool classof(const Action *A) {
|
||||
return A->getKind() == OffloadBundlingJobClass;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace driver
|
||||
} // end namespace clang
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ const char *Action::getClassName(ActionClass AC) {
|
|||
case DsymutilJobClass: return "dsymutil";
|
||||
case VerifyDebugInfoJobClass: return "verify-debug-info";
|
||||
case VerifyPCHJobClass: return "verify-pch";
|
||||
case OffloadBundlingJobClass:
|
||||
return "clang-offload-bundler";
|
||||
}
|
||||
|
||||
llvm_unreachable("invalid class");
|
||||
|
@ -346,3 +348,8 @@ void VerifyPCHJobAction::anchor() {}
|
|||
|
||||
VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
|
||||
: VerifyJobAction(VerifyPCHJobClass, Input, Type) {}
|
||||
|
||||
void OffloadBundlingJobAction::anchor() {}
|
||||
|
||||
OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
|
||||
: JobAction(OffloadBundlingJobClass, Inputs, Inputs.front()->getType()) {}
|
||||
|
|
|
@ -1568,6 +1568,9 @@ class OffloadingActionBuilder final {
|
|||
/// found.
|
||||
virtual bool initialize() { return false; }
|
||||
|
||||
/// Return true if the builder can use bundling/unbundling.
|
||||
virtual bool canUseBundlerUnbundler() const { return false; }
|
||||
|
||||
/// Return true if this builder is valid. We have a valid builder if we have
|
||||
/// associated device tool chains.
|
||||
bool isValid() { return !ToolChains.empty(); }
|
||||
|
@ -1911,6 +1914,26 @@ class OffloadingActionBuilder final {
|
|||
return ABRT_Success;
|
||||
}
|
||||
|
||||
void appendTopLevelActions(ActionList &AL) override {
|
||||
if (OpenMPDeviceActions.empty())
|
||||
return;
|
||||
|
||||
// We should always have an action for each input.
|
||||
assert(OpenMPDeviceActions.size() == ToolChains.size() &&
|
||||
"Number of OpenMP actions and toolchains do not match.");
|
||||
|
||||
// Append all device actions followed by the proper offload action.
|
||||
auto TI = ToolChains.begin();
|
||||
for (auto *A : OpenMPDeviceActions) {
|
||||
OffloadAction::DeviceDependences Dep;
|
||||
Dep.add(*A, **TI, /*BoundArch=*/nullptr, Action::OFK_OpenMP);
|
||||
AL.push_back(C.MakeAction<OffloadAction>(Dep, A->getType()));
|
||||
++TI;
|
||||
}
|
||||
// We no longer need the action stored in this builder.
|
||||
OpenMPDeviceActions.clear();
|
||||
}
|
||||
|
||||
void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {
|
||||
assert(ToolChains.size() == DeviceLinkerInputs.size() &&
|
||||
"Toolchains and linker inputs sizes do not match.");
|
||||
|
@ -1937,6 +1960,11 @@ class OffloadingActionBuilder final {
|
|||
DeviceLinkerInputs.resize(ToolChains.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool canUseBundlerUnbundler() const override {
|
||||
// OpenMP should use bundled files whenever possible.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
|
@ -1946,6 +1974,9 @@ class OffloadingActionBuilder final {
|
|||
/// Specialized builders being used by this offloading action builder.
|
||||
SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
|
||||
|
||||
/// Flag set to true if all valid builders allow file bundling/unbundling.
|
||||
bool CanUseBundler;
|
||||
|
||||
public:
|
||||
OffloadingActionBuilder(Compilation &C, DerivedArgList &Args,
|
||||
const Driver::InputList &Inputs)
|
||||
|
@ -1964,9 +1995,22 @@ public:
|
|||
// TODO: Build other specialized builders here.
|
||||
//
|
||||
|
||||
// Initialize all the builders, keeping track of errors.
|
||||
for (auto *SB : SpecializedBuilders)
|
||||
// Initialize all the builders, keeping track of errors. If all valid
|
||||
// builders agree that we can use bundling, set the flag to true.
|
||||
unsigned ValidBuilders = 0u;
|
||||
unsigned ValidBuildersSupportingBundling = 0u;
|
||||
for (auto *SB : SpecializedBuilders) {
|
||||
IsValid = IsValid && !SB->initialize();
|
||||
|
||||
// Update the counters if the builder is valid.
|
||||
if (SB->isValid()) {
|
||||
++ValidBuilders;
|
||||
if (SB->canUseBundlerUnbundler())
|
||||
++ValidBuildersSupportingBundling;
|
||||
}
|
||||
}
|
||||
CanUseBundler =
|
||||
ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
|
||||
}
|
||||
|
||||
~OffloadingActionBuilder() {
|
||||
|
@ -2066,15 +2110,33 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Add the offloading top level actions to the provided action list.
|
||||
/// Add the offloading top level actions to the provided action list. This
|
||||
/// function can replace the host action by a bundling action if the
|
||||
/// programming models allow it.
|
||||
bool appendTopLevelActions(ActionList &AL, Action *HostAction,
|
||||
const Arg *InputArg) {
|
||||
// Get the device actions to be appended.
|
||||
ActionList OffloadAL;
|
||||
for (auto *SB : SpecializedBuilders) {
|
||||
if (!SB->isValid())
|
||||
continue;
|
||||
SB->appendTopLevelActions(AL);
|
||||
SB->appendTopLevelActions(OffloadAL);
|
||||
}
|
||||
|
||||
// If we can use the bundler, replace the host action by the bundling one in
|
||||
// the resulting list. Otherwise, just append the device actions.
|
||||
if (CanUseBundler && !OffloadAL.empty()) {
|
||||
// Add the host action to the list in order to create the bundling action.
|
||||
OffloadAL.push_back(HostAction);
|
||||
|
||||
// We expect that the host action was just appended to the action list
|
||||
// before this method was called.
|
||||
assert(HostAction == AL.back() && "Host action not in the list??");
|
||||
HostAction = C.MakeAction<OffloadBundlingJobAction>(OffloadAL);
|
||||
AL.back() = HostAction;
|
||||
} else
|
||||
AL.append(OffloadAL.begin(), OffloadAL.end());
|
||||
|
||||
// Propagate to the current host action (if any) the offload information
|
||||
// associated with the current input.
|
||||
if (HostAction)
|
||||
|
|
|
@ -263,6 +263,10 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const {
|
|||
case Action::VerifyPCHJobClass:
|
||||
case Action::BackendJobClass:
|
||||
return getClang();
|
||||
|
||||
case Action::OffloadBundlingJobClass:
|
||||
// FIXME: Add a tool for the bundling actions.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
llvm_unreachable("Invalid tool kind.");
|
||||
|
|
|
@ -274,3 +274,31 @@
|
|||
// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTASM:.+\.s]]" "-x" "ir" "[[HOSTBC]]"
|
||||
// CHK-COMMANDS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le--linux" "-filetype" "obj" {{.*}}"-o" [[HOSTOBJ:.+\.o]]" [[HOSTASM:.+\.s]]
|
||||
// CHK-COMMANDS-ST: ld" {{.*}}"-o" "[[HOSTBIN:.+\.out]]" {{.*}}"-lomptarget" {{.*}}"-T" "[[HOSTLK:.+\.lk]]"
|
||||
|
||||
|
||||
/// ###########################################################################
|
||||
|
||||
/// Check separate compilation with offloading - bundling actions
|
||||
// RUN: %clang -### -ccc-print-phases -fopenmp -c -o %t.o -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu %s 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=CHK-BUACTIONS %s
|
||||
|
||||
// CHK-BUACTIONS: 0: input, "[[INPUT:.+\.c]]", c, (host-openmp)
|
||||
// CHK-BUACTIONS: 1: preprocessor, {0}, cpp-output, (host-openmp)
|
||||
// CHK-BUACTIONS: 2: compiler, {1}, ir, (host-openmp)
|
||||
// CHK-BUACTIONS: 3: input, "[[INPUT]]", c, (device-openmp)
|
||||
// CHK-BUACTIONS: 4: preprocessor, {3}, cpp-output, (device-openmp)
|
||||
// CHK-BUACTIONS: 5: compiler, {4}, ir, (device-openmp)
|
||||
// CHK-BUACTIONS: 6: offload, "host-openmp (powerpc64le--linux)" {2}, "device-openmp (powerpc64le-ibm-linux-gnu)" {5}, ir
|
||||
// CHK-BUACTIONS: 7: backend, {6}, assembler, (device-openmp)
|
||||
// CHK-BUACTIONS: 8: assembler, {7}, object, (device-openmp)
|
||||
// CHK-BUACTIONS: 9: offload, "device-openmp (powerpc64le-ibm-linux-gnu)" {8}, object
|
||||
// CHK-BUACTIONS: 10: input, "[[INPUT]]", c, (device-openmp)
|
||||
// CHK-BUACTIONS: 11: preprocessor, {10}, cpp-output, (device-openmp)
|
||||
// CHK-BUACTIONS: 12: compiler, {11}, ir, (device-openmp)
|
||||
// CHK-BUACTIONS: 13: offload, "host-openmp (powerpc64le--linux)" {2}, "device-openmp (x86_64-pc-linux-gnu)" {12}, ir
|
||||
// CHK-BUACTIONS: 14: backend, {13}, assembler, (device-openmp)
|
||||
// CHK-BUACTIONS: 15: assembler, {14}, object, (device-openmp)
|
||||
// CHK-BUACTIONS: 16: offload, "device-openmp (x86_64-pc-linux-gnu)" {15}, object
|
||||
// CHK-BUACTIONS: 17: backend, {2}, assembler, (host-openmp)
|
||||
// CHK-BUACTIONS: 18: assembler, {17}, object, (host-openmp)
|
||||
// CHK-BUACTIONS: 19: clang-offload-bundler, {9, 16, 18}, object, (host-openmp)
|
||||
|
|
Loading…
Reference in New Issue