@@ -2461,17 +2461,18 @@ class OffloadingActionBuilder final {
24612461 return ABRT_Inactive;
24622462
24632463 CudaDeviceActions.clear ();
2464- auto *IA = cast<InputAction>(UA->getInputs ().back ());
2465- std::string FileName = IA->getInputArg ().getAsString (Args);
2466- // Check if the type of the file is the same as the action. Do not
2467- // unbundle it if it is not. Do not unbundle .so files, for example,
2468- // which are not object files.
2469- if (IA->getType () == types::TY_Object &&
2470- (!llvm::sys::path::has_extension (FileName) ||
2471- types::lookupTypeForExtension (
2472- llvm::sys::path::extension (FileName).drop_front ()) !=
2473- types::TY_Object))
2474- return ABRT_Inactive;
2464+ if (auto *IA = dyn_cast<InputAction>(UA->getInputs ().back ())) {
2465+ std::string FileName = IA->getInputArg ().getAsString (Args);
2466+ // Check if the type of the file is the same as the action. Do not
2467+ // unbundle it if it is not. Do not unbundle .so files, for example,
2468+ // which are not object files.
2469+ if (IA->getType () == types::TY_Object &&
2470+ (!llvm::sys::path::has_extension (FileName) ||
2471+ types::lookupTypeForExtension (
2472+ llvm::sys::path::extension (FileName).drop_front ()) !=
2473+ types::TY_Object))
2474+ return ABRT_Inactive;
2475+ }
24752476
24762477 for (auto Arch : GpuArchList) {
24772478 CudaDeviceActions.push_back (UA);
@@ -2893,17 +2894,18 @@ class OffloadingActionBuilder final {
28932894 // If this is an unbundling action use it as is for each OpenMP toolchain.
28942895 if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
28952896 OpenMPDeviceActions.clear ();
2896- auto *IA = cast<InputAction>(UA->getInputs ().back ());
2897- std::string FileName = IA->getInputArg ().getAsString (Args);
2898- // Check if the type of the file is the same as the action. Do not
2899- // unbundle it if it is not. Do not unbundle .so files, for example,
2900- // which are not object files.
2901- if (IA->getType () == types::TY_Object &&
2902- (!llvm::sys::path::has_extension (FileName) ||
2903- types::lookupTypeForExtension (
2904- llvm::sys::path::extension (FileName).drop_front ()) !=
2905- types::TY_Object))
2906- return ABRT_Inactive;
2897+ if (auto *IA = dyn_cast<InputAction>(UA->getInputs ().back ())) {
2898+ std::string FileName = IA->getInputArg ().getAsString (Args);
2899+ // Check if the type of the file is the same as the action. Do not
2900+ // unbundle it if it is not. Do not unbundle .so files, for example,
2901+ // which are not object files.
2902+ if (IA->getType () == types::TY_Object &&
2903+ (!llvm::sys::path::has_extension (FileName) ||
2904+ types::lookupTypeForExtension (
2905+ llvm::sys::path::extension (FileName).drop_front ()) !=
2906+ types::TY_Object))
2907+ return ABRT_Inactive;
2908+ }
29072909 for (unsigned I = 0 ; I < ToolChains.size (); ++I) {
29082910 OpenMPDeviceActions.push_back (UA);
29092911 UA->registerDependentActionInfo (
@@ -3102,21 +3104,22 @@ class OffloadingActionBuilder final {
31023104 // If this is an unbundling action use it as is for each SYCL toolchain.
31033105 if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
31043106 SYCLDeviceActions.clear ();
3105- auto *IA = cast <InputAction>(UA->getInputs ().back ());
3106- std::string FileName = IA->getInputArg ().getAsString (Args);
3107- // Check if the type of the file is the same as the action. Do not
3108- // unbundle it if it is not. Do not unbundle .so files, for example,
3109- // which are not object files.
3110- if (IA->getType () == types::TY_Object &&
3111- (!llvm::sys::path::has_extension (FileName) ||
3112- types::lookupTypeForExtension (
3107+ if ( auto *IA = dyn_cast <InputAction>(UA->getInputs ().back ())) {
3108+ std::string FileName = IA->getInputArg ().getAsString (Args);
3109+ // Check if the type of the file is the same as the action. Do not
3110+ // unbundle it if it is not. Do not unbundle .so files, for example,
3111+ // which are not object files.
3112+ if (IA->getType () == types::TY_Object &&
3113+ (!llvm::sys::path::has_extension (FileName) ||
3114+ types::lookupTypeForExtension (
31133115 llvm::sys::path::extension (FileName).drop_front ()) !=
31143116 types::TY_Object))
3115- return ABRT_Inactive;
3117+ return ABRT_Inactive;
3118+ }
31163119 for (unsigned I = 0 ; I < ToolChains.size (); ++I) {
31173120 SYCLDeviceActions.push_back (UA);
31183121 UA->registerDependentActionInfo (
3119- ToolChains[I], /* BoundArch=*/ StringRef (), Action::OFK_SYCL);
3122+ ToolChains[I], /* BoundArch=*/ StringRef (), Action::OFK_SYCL);
31203123 }
31213124 return ABRT_Success;
31223125 }
@@ -3373,7 +3376,8 @@ class OffloadingActionBuilder final {
33733376 // / results will be kept in this action builder. Return true if an error was
33743377 // / found.
33753378 bool addHostDependenceToDeviceActions (Action *&HostAction,
3376- const Arg *InputArg) {
3379+ const Arg *InputArg,
3380+ DerivedArgList &Args) {
33773381 if (!IsValid)
33783382 return true ;
33793383
@@ -3386,12 +3390,27 @@ class OffloadingActionBuilder final {
33863390 if (CanUseBundler && isa<InputAction>(HostAction) &&
33873391 InputArg->getOption ().getKind () == llvm::opt::Option::InputClass &&
33883392 !types::isSrcFile (HostAction->getType ())) {
3389- auto UnbundlingHostAction =
3390- C.MakeAction <OffloadUnbundlingJobAction>(HostAction);
3391- UnbundlingHostAction->registerDependentActionInfo (
3392- C.getSingleOffloadToolChain <Action::OFK_Host>(),
3393- /* BoundArch=*/ StringRef (), Action::OFK_Host);
3394- HostAction = UnbundlingHostAction;
3393+ const char * InputName = InputArg->getValue ();
3394+ // Do not create an unbundling action for an object when we know a fat
3395+ // static library is being used. A separate unbundling action is created
3396+ // for all objects and the fat static library.
3397+ if (!(HostAction->getType () == types::TY_Object &&
3398+ llvm::sys::path::has_extension (InputName) &&
3399+ types::lookupTypeForExtension (
3400+ llvm::sys::path::extension (InputName).drop_front ()) ==
3401+ types::TY_Object &&
3402+ Args.hasArg (options::OPT_foffload_static_lib_EQ))) {
3403+ ActionList HostActionList;
3404+ HostActionList.push_back (HostAction);
3405+ if (!HostActionList.empty ()) {
3406+ auto UnbundlingHostAction =
3407+ C.MakeAction <OffloadUnbundlingJobAction>(HostActionList);
3408+ UnbundlingHostAction->registerDependentActionInfo (
3409+ C.getSingleOffloadToolChain <Action::OFK_Host>(),
3410+ /* BoundArch=*/ StringRef (), Action::OFK_Host);
3411+ HostAction = UnbundlingHostAction;
3412+ }
3413+ }
33953414 }
33963415
33973416 assert (HostAction && " Invalid host action!" );
@@ -3423,6 +3442,43 @@ class OffloadingActionBuilder final {
34233442 return false ;
34243443 }
34253444
3445+ // / Generate an action that adds a host dependence to an unbundling action.
3446+ // / The results will be kept in this action builder. Return true if an error
3447+ // / was found.
3448+ bool addHostDependenceToUnbundlingAction (Action *&HostAction,
3449+ ActionList &InputActionList,
3450+ const Arg *InputArg) {
3451+ if (!IsValid || InputActionList.empty ())
3452+ return true ;
3453+
3454+ auto *DeviceUnbundlingAction =
3455+ C.MakeAction <OffloadUnbundlingJobAction>(InputActionList);
3456+ DeviceUnbundlingAction->registerDependentActionInfo (
3457+ C.getSingleOffloadToolChain <Action::OFK_Host>(),
3458+ /* BoundArch=*/ StringRef (), Action::OFK_Host);
3459+ HostAction = DeviceUnbundlingAction;
3460+
3461+ // Register the offload kinds that are used.
3462+ auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3463+ for (auto *SB : SpecializedBuilders) {
3464+ if (!SB->isValid ())
3465+ continue ;
3466+
3467+ auto RetCode = SB->addDeviceDepences (HostAction);
3468+
3469+ // Host dependences for device actions are not compatible with that same
3470+ // action being ignored.
3471+ assert (RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3472+ " Host dependence not expected to be ignored.!" );
3473+
3474+ // Unless the builder was inactive for this action, we have to record the
3475+ // offload kind because the host will have to use it.
3476+ if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3477+ OffloadKind |= SB->getAssociatedOffloadKind ();
3478+ }
3479+ return false ;
3480+ }
3481+
34263482 // / Add the offloading top level actions that are specific for unique
34273483 // / linking situations where objects are used at only the device link
34283484 // / with no intermedate steps.
@@ -3674,7 +3730,8 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
36743730
36753731 // Use the current host action in any of the offloading actions, if
36763732 // required.
3677- if (OffloadBuilder.addHostDependenceToDeviceActions (Current, InputArg))
3733+ if (OffloadBuilder.addHostDependenceToDeviceActions (Current, InputArg,
3734+ Args))
36783735 break ;
36793736
36803737 for (SmallVectorImpl<phases::ID>::iterator i = PL.begin (), e = PL.end ();
@@ -3688,6 +3745,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
36883745 // Add any offload action the host action depends on.
36893746 Current = OffloadBuilder.addDeviceDependencesToHostAction (
36903747 Current, InputArg, Phase, FinalPhase, PL);
3748+
36913749 if (!Current)
36923750 break ;
36933751
@@ -3726,7 +3784,8 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
37263784
37273785 // Use the current host action in any of the offloading actions, if
37283786 // required.
3729- if (OffloadBuilder.addHostDependenceToDeviceActions (Current, InputArg))
3787+ if (OffloadBuilder.addHostDependenceToDeviceActions (Current, InputArg,
3788+ Args))
37303789 break ;
37313790
37323791 if (Current->getType () == types::TY_Nothing)
@@ -3743,6 +3802,43 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
37433802
37443803 OffloadBuilder.appendTopLevelLinkAction (Actions);
37453804
3805+ // When a static fat archive is provided, create a new unbundling step
3806+ // for all of the objects.
3807+ if (Args.hasArg (options::OPT_foffload_static_lib_EQ) &&
3808+ !LinkerInputs.empty ()) {
3809+ ActionList UnbundlerInputs;
3810+ ActionList TempLinkerInputs;
3811+ for (const auto &LI : LinkerInputs) {
3812+ // Unbundler only handles objects.
3813+ if (auto *IA = dyn_cast<InputAction>(LI)) {
3814+ std::string FileName = IA->getInputArg ().getAsString (Args);
3815+ if (IA->getType () == types::TY_Object &&
3816+ (!llvm::sys::path::has_extension (FileName) ||
3817+ types::lookupTypeForExtension (
3818+ llvm::sys::path::extension (FileName).drop_front ()) !=
3819+ types::TY_Object))
3820+ // Pass the Input along to linker.
3821+ TempLinkerInputs.push_back (LI);
3822+ else
3823+ // Add to unbundler.
3824+ UnbundlerInputs.push_back (LI);
3825+ } else
3826+ UnbundlerInputs.push_back (LI);
3827+ }
3828+ LinkerInputs.clear ();
3829+ if (!UnbundlerInputs.empty ()) {
3830+ Action *Current;
3831+ const Arg *LastArg = Args.getLastArg (options::OPT_foffload_static_lib_EQ);
3832+ OffloadBuilder.addHostDependenceToUnbundlingAction (Current,
3833+ UnbundlerInputs, LastArg);
3834+ Current = OffloadBuilder.addDeviceDependencesToHostAction (Current,
3835+ LastArg, phases::Link, FinalPhase, PL);
3836+ LinkerInputs.push_back (Current);
3837+ }
3838+ for (const auto &TLI : TempLinkerInputs)
3839+ LinkerInputs.push_back (TLI);
3840+ }
3841+
37463842 // Add a link action if necessary.
37473843 if (!LinkerInputs.empty ()) {
37483844 Action *LA = C.MakeAction <LinkJobAction>(LinkerInputs, types::TY_Image);
@@ -4495,18 +4591,30 @@ InputInfo Driver::BuildJobsForActionNoCache(
44954591 // offloading prefix, we also do that for the host file because the
44964592 // unbundling action does not change the type of the output which can
44974593 // cause a overwrite.
4498- std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix (
4594+ InputInfo CurI;
4595+ if (C.getInputArgs ().hasArg (options::OPT_foffload_static_lib_EQ) &&
4596+ UI.DependentOffloadKind != Action::OFK_Host &&
4597+ JA->getType () == types::TY_Object) {
4598+ std::string TmpFileName =
4599+ C.getDriver ().GetTemporaryPath (llvm::sys::path::stem (BaseInput),
4600+ " txt" );
4601+ const char *TmpFile =
4602+ C.addTempFile (C.getArgs ().MakeArgString (TmpFileName));
4603+ CurI = InputInfo (types::TY_Tempfilelist, TmpFile, TmpFile);
4604+ } else {
4605+ std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix (
44994606 UI.DependentOffloadKind ,
45004607 UI.DependentToolChain ->getTriple ().normalize (),
45014608 /* CreatePrefixForHost=*/ true );
4502- auto CurI = InputInfo (
4609+ CurI = InputInfo (
45034610 UA,
45044611 GetNamedOutputPath (C, *UA, BaseInput, UI.DependentBoundArch ,
45054612 /* AtTopLevel=*/ false ,
45064613 MultipleArchs ||
45074614 UI.DependentOffloadKind == Action::OFK_HIP,
45084615 OffloadingPrefix),
45094616 BaseInput);
4617+ }
45104618 // Save the unbundling result.
45114619 UnbundlingResults.push_back (CurI);
45124620
0 commit comments