@@ -3486,8 +3486,17 @@ class OffloadingActionBuilder final {
3486
3486
}
3487
3487
continue ;
3488
3488
}
3489
+ ActionList DeviceLibObjects;
3490
+ ActionList LinkObjects;
3491
+ for (const auto &Input : LI) {
3492
+ // FPGA aoco does not go through the link, everything else does.
3493
+ if (Input->getType () == types::TY_FPGA_AOCO)
3494
+ DeviceLibObjects.push_back (Input);
3495
+ else
3496
+ LinkObjects.push_back (Input);
3497
+ }
3489
3498
auto *DeviceLinkAction =
3490
- C.MakeAction <LinkJobAction>(LI , types::TY_LLVM_BC);
3499
+ C.MakeAction <LinkJobAction>(LinkObjects , types::TY_LLVM_BC);
3491
3500
ActionList WrapperInputs;
3492
3501
Action *SPIRVInput = DeviceLinkAction;
3493
3502
types::ID OutType = types::TY_SPIRV;
@@ -3520,9 +3529,13 @@ class OffloadingActionBuilder final {
3520
3529
}
3521
3530
// Do the additional Ahead of Time compilation when the specific
3522
3531
// triple calls for it (provided a valid subarch).
3523
- auto *DeviceBECompileAction = C.MakeAction <BackendCompileJobAction>(
3524
- SPIRVTranslateAction, OutType);
3525
-
3532
+ Action *DeviceBECompileAction;
3533
+ ActionList BEActionList;
3534
+ BEActionList.push_back (SPIRVTranslateAction);
3535
+ for (const auto &A : DeviceLibObjects)
3536
+ BEActionList.push_back (A);
3537
+ DeviceBECompileAction =
3538
+ C.MakeAction <BackendCompileJobAction>(BEActionList, OutType);
3526
3539
WrapperInputs.push_back (DeviceBECompileAction);
3527
3540
auto *DeviceWrappingAction = C.MakeAction <OffloadWrapperJobAction>(
3528
3541
WrapperInputs, types::TY_Object);
@@ -3765,12 +3778,12 @@ class OffloadingActionBuilder final {
3765
3778
return C.MakeAction <OffloadAction>(HDep, DDeps);
3766
3779
}
3767
3780
3768
- bool HasFPGADeviceBinary (Compilation &C, std::string Object,
3769
- bool CheckAOCX = false ) {
3781
+ bool hasFPGABinary (Compilation &C, std::string Object, types::ID Type) {
3782
+ assert ( types::isFPGA (Type) && " unexpected Type for FPGA binary check " );
3770
3783
// Temporary names for the output.
3771
3784
const ToolChain *OTC = C.getSingleOffloadToolChain <Action::OFK_SYCL>();
3772
3785
llvm::Triple TT;
3773
- TT.setArchName (CheckAOCX ? " fpga_aocx " : " fpga_aocr " );
3786
+ TT.setArchName (types::getTypeName (Type) );
3774
3787
TT.setVendorName (" intel" );
3775
3788
TT.setOS (llvm::Triple (OTC->getTriple ()).getOS ());
3776
3789
TT.setEnvironment (llvm::Triple::SYCLDevice);
@@ -3783,9 +3796,8 @@ class OffloadingActionBuilder final {
3783
3796
Object);
3784
3797
// Always use -type=ao for aocx/aocr bundle checking. The 'bundles' are
3785
3798
// actually archives.
3786
- const char *Type = C.getArgs ().MakeArgString (" -type=ao" );
3787
3799
std::vector<StringRef> BundlerArgs = { " clang-offload-bundler" ,
3788
- Type ,
3800
+ " -type=ao " ,
3789
3801
Targets,
3790
3802
Inputs,
3791
3803
" -check-section" };
@@ -3858,13 +3870,16 @@ class OffloadingActionBuilder final {
3858
3870
Action *A (HostAction);
3859
3871
// Only check for FPGA device information when using fpga SubArch.
3860
3872
if (Args.hasArg (options::OPT_fintelfpga) &&
3861
- HostAction->getType () != types::TY_FPGA_AOCR &&
3862
- HostAction->getType () != types::TY_FPGA_AOCX &&
3863
3873
!(HostAction->getType () == types::TY_Object &&
3864
3874
isObjectFile (InputName))) {
3865
- if (HasFPGADeviceBinary (C, InputArg->getAsString (Args), true ))
3875
+ // Type FPGA aoco is a special case for -foffload-static-lib.
3876
+ if (HostAction->getType () == types::TY_FPGA_AOCO) {
3877
+ if (!hasFPGABinary (C, InputName, types::TY_FPGA_AOCO))
3878
+ return false ;
3879
+ A = C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCO);
3880
+ } else if (hasFPGABinary (C, InputName, types::TY_FPGA_AOCX))
3866
3881
A = C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCX);
3867
- else if (HasFPGADeviceBinary (C, InputArg-> getAsString (Args) ))
3882
+ else if (hasFPGABinary (C, InputName, types::TY_FPGA_AOCR ))
3868
3883
A = C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCR);
3869
3884
}
3870
3885
HostActionList.push_back (A);
@@ -4369,22 +4384,29 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
4369
4384
LinkerInputs.push_back (TLI);
4370
4385
}
4371
4386
const llvm::opt::OptTable &Opts = getOpts ();
4372
- if (C.getDefaultToolChain ().getTriple ().isWindowsMSVCEnvironment () &&
4373
- Args.hasArg (options::OPT_foffload_static_lib_EQ)) {
4387
+ for (const auto *A : Args.filtered (options::OPT_foffload_static_lib_EQ)) {
4388
+ auto unbundleStaticLib = [&](types::ID T) {
4389
+ Arg *InputArg = MakeInputArg (Args, Opts, A->getValue ());
4390
+ Action *Current = C.MakeAction <InputAction>(*InputArg, T);
4391
+ OffloadBuilder.addHostDependenceToDeviceActions (Current, InputArg, Args);
4392
+ OffloadBuilder.addDeviceDependencesToHostAction (
4393
+ Current, InputArg, phases::Link, PL.back (), PL);
4394
+ };
4374
4395
// In MSVC environment offload-static-libs are handled slightly different
4375
4396
// because of missing support for partial linking in the linker. We add an
4376
4397
// unbundling action for each static archive which produces list files with
4377
4398
// extracted objects. Device lists are then added to the appropriate device
4378
4399
// link actions and host list is ignored since we are adding
4379
4400
// offload-static-libs as normal libraries to the host link command.
4380
- for ( const auto *A : Args. filtered (options::OPT_foffload_static_lib_EQ)) {
4381
- Arg *InputArg = MakeInputArg (Args, Opts, A-> getValue () );
4382
- Action *Current = C. MakeAction <InputAction>(*InputArg, types::TY_Archive);
4383
- OffloadBuilder. addHostDependenceToDeviceActions (Current, InputArg, Args);
4384
- OffloadBuilder. addDeviceDependencesToHostAction (
4385
- Current, InputArg, phases::Link, PL. back (), PL);
4386
- }
4401
+ if (C. getDefaultToolChain (). getTriple (). isWindowsMSVCEnvironment ())
4402
+ unbundleStaticLib (types::TY_Archive );
4403
+ // Pass along the -foffload-static-lib values to check if we need to
4404
+ // add them for unbundling for FPGA AOT static lib usage. Uses FPGA
4405
+ // aoco type to differentiate if aoco unbundling is needed.
4406
+ if (Args. hasArg (options::OPT_fintelfpga))
4407
+ unbundleStaticLib (types::TY_FPGA_AOCO);
4387
4408
}
4409
+
4388
4410
// For an FPGA archive, we add the unbundling step above to take care of
4389
4411
// the device side, but also unbundle here to extract the host side
4390
4412
for (const auto &LI : LinkerInputs) {
@@ -5263,8 +5285,7 @@ InputInfo Driver::BuildJobsForActionNoCache(
5263
5285
C.addTempFile (C.getArgs ().MakeArgString (TmpFileName),
5264
5286
types::TY_Tempfilelist);
5265
5287
CurI = InputInfo (types::TY_Tempfilelist, TmpFile, TmpFile);
5266
- } else if (JA->getType () == types::TY_FPGA_AOCX ||
5267
- JA->getType () == types::TY_FPGA_AOCR) {
5288
+ } else if (types::isFPGA (JA->getType ())) {
5268
5289
std::string Ext (types::getTypeTempSuffix (JA->getType ()));
5269
5290
types::ID TI = types::TY_Object;
5270
5291
if (EffectiveTriple.getSubArch () == llvm::Triple::SPIRSubArch_fpga) {
@@ -5275,6 +5296,10 @@ InputInfo Driver::BuildJobsForActionNoCache(
5275
5296
// side isn't used
5276
5297
continue ;
5277
5298
}
5299
+ if (JA->getType () == types::TY_FPGA_AOCO) {
5300
+ TI = types::TY_TempAOCOfilelist;
5301
+ Ext = " txt" ;
5302
+ }
5278
5303
} else if (EffectiveTriple.getSubArch () !=
5279
5304
llvm::Triple::SPIRSubArch_fpga) {
5280
5305
if (UI.DependentOffloadKind == Action::OFK_SYCL) {
0 commit comments