@@ -2461,17 +2461,18 @@ class OffloadingActionBuilder final {
2461
2461
return ABRT_Inactive;
2462
2462
2463
2463
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
+ }
2475
2476
2476
2477
for (auto Arch : GpuArchList) {
2477
2478
CudaDeviceActions.push_back (UA);
@@ -2893,17 +2894,18 @@ class OffloadingActionBuilder final {
2893
2894
// If this is an unbundling action use it as is for each OpenMP toolchain.
2894
2895
if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
2895
2896
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
+ }
2907
2909
for (unsigned I = 0 ; I < ToolChains.size (); ++I) {
2908
2910
OpenMPDeviceActions.push_back (UA);
2909
2911
UA->registerDependentActionInfo (
@@ -3102,21 +3104,22 @@ class OffloadingActionBuilder final {
3102
3104
// If this is an unbundling action use it as is for each SYCL toolchain.
3103
3105
if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3104
3106
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 (
3113
3115
llvm::sys::path::extension (FileName).drop_front ()) !=
3114
3116
types::TY_Object))
3115
- return ABRT_Inactive;
3117
+ return ABRT_Inactive;
3118
+ }
3116
3119
for (unsigned I = 0 ; I < ToolChains.size (); ++I) {
3117
3120
SYCLDeviceActions.push_back (UA);
3118
3121
UA->registerDependentActionInfo (
3119
- ToolChains[I], /* BoundArch=*/ StringRef (), Action::OFK_SYCL);
3122
+ ToolChains[I], /* BoundArch=*/ StringRef (), Action::OFK_SYCL);
3120
3123
}
3121
3124
return ABRT_Success;
3122
3125
}
@@ -3373,7 +3376,8 @@ class OffloadingActionBuilder final {
3373
3376
// / results will be kept in this action builder. Return true if an error was
3374
3377
// / found.
3375
3378
bool addHostDependenceToDeviceActions (Action *&HostAction,
3376
- const Arg *InputArg) {
3379
+ const Arg *InputArg,
3380
+ DerivedArgList &Args) {
3377
3381
if (!IsValid)
3378
3382
return true ;
3379
3383
@@ -3386,12 +3390,27 @@ class OffloadingActionBuilder final {
3386
3390
if (CanUseBundler && isa<InputAction>(HostAction) &&
3387
3391
InputArg->getOption ().getKind () == llvm::opt::Option::InputClass &&
3388
3392
!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
+ }
3395
3414
}
3396
3415
3397
3416
assert (HostAction && " Invalid host action!" );
@@ -3423,6 +3442,43 @@ class OffloadingActionBuilder final {
3423
3442
return false ;
3424
3443
}
3425
3444
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
+
3426
3482
// / Add the offloading top level actions that are specific for unique
3427
3483
// / linking situations where objects are used at only the device link
3428
3484
// / with no intermedate steps.
@@ -3674,7 +3730,8 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
3674
3730
3675
3731
// Use the current host action in any of the offloading actions, if
3676
3732
// required.
3677
- if (OffloadBuilder.addHostDependenceToDeviceActions (Current, InputArg))
3733
+ if (OffloadBuilder.addHostDependenceToDeviceActions (Current, InputArg,
3734
+ Args))
3678
3735
break ;
3679
3736
3680
3737
for (SmallVectorImpl<phases::ID>::iterator i = PL.begin (), e = PL.end ();
@@ -3688,6 +3745,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
3688
3745
// Add any offload action the host action depends on.
3689
3746
Current = OffloadBuilder.addDeviceDependencesToHostAction (
3690
3747
Current, InputArg, Phase, FinalPhase, PL);
3748
+
3691
3749
if (!Current)
3692
3750
break ;
3693
3751
@@ -3726,7 +3784,8 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
3726
3784
3727
3785
// Use the current host action in any of the offloading actions, if
3728
3786
// required.
3729
- if (OffloadBuilder.addHostDependenceToDeviceActions (Current, InputArg))
3787
+ if (OffloadBuilder.addHostDependenceToDeviceActions (Current, InputArg,
3788
+ Args))
3730
3789
break ;
3731
3790
3732
3791
if (Current->getType () == types::TY_Nothing)
@@ -3743,6 +3802,43 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
3743
3802
3744
3803
OffloadBuilder.appendTopLevelLinkAction (Actions);
3745
3804
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
+
3746
3842
// Add a link action if necessary.
3747
3843
if (!LinkerInputs.empty ()) {
3748
3844
Action *LA = C.MakeAction <LinkJobAction>(LinkerInputs, types::TY_Image);
@@ -4495,18 +4591,30 @@ InputInfo Driver::BuildJobsForActionNoCache(
4495
4591
// offloading prefix, we also do that for the host file because the
4496
4592
// unbundling action does not change the type of the output which can
4497
4593
// 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 (
4499
4606
UI.DependentOffloadKind ,
4500
4607
UI.DependentToolChain ->getTriple ().normalize (),
4501
4608
/* CreatePrefixForHost=*/ true );
4502
- auto CurI = InputInfo (
4609
+ CurI = InputInfo (
4503
4610
UA,
4504
4611
GetNamedOutputPath (C, *UA, BaseInput, UI.DependentBoundArch ,
4505
4612
/* AtTopLevel=*/ false ,
4506
4613
MultipleArchs ||
4507
4614
UI.DependentOffloadKind == Action::OFK_HIP,
4508
4615
OffloadingPrefix),
4509
4616
BaseInput);
4617
+ }
4510
4618
// Save the unbundling result.
4511
4619
UnbundlingResults.push_back (CurI);
4512
4620
0 commit comments