@@ -3451,24 +3451,8 @@ static bool hasSYCLDefaultSection(Compilation &C, const StringRef &File) {
3451
3451
3452
3452
static bool hasOffloadSections (Compilation &C, const StringRef &File,
3453
3453
DerivedArgList &Args) {
3454
- // Do not do the check if the file doesn't exist
3455
- if (!llvm::sys::fs::exists (File))
3456
- return false ;
3457
-
3458
- bool IsArchive = isStaticArchiveFile (File);
3459
- if (!(IsArchive || isObjectFile (File.str ())))
3460
- return false ;
3461
-
3462
- llvm::Triple TT (C.getDefaultToolChain ().getTriple ());
3463
- // Checking uses -check-section option with the input file, no output
3464
- // file and the target triple being looked for.
3465
- // TODO - Improve checking to check for explicit offload target instead
3466
- // of the generic host availability.
3467
- const char *Targets = Args.MakeArgString (Twine (" -targets=host-" ) + TT.str ());
3468
- const char *Inputs = Args.MakeArgString (Twine (" -input=" ) + File.str ());
3469
- SmallVector<StringRef, 6 > BundlerArgs = {IsArchive ? " -type=ao" : " -type=o" ,
3470
- Targets, Inputs, " -check-section" };
3471
- return runBundler (BundlerArgs, C);
3454
+ SmallVector<std::string, 4 > Sections (getOffloadSections (C, File));
3455
+ return !Sections.empty ();
3472
3456
}
3473
3457
3474
3458
// Simple helper function for Linker options, where the option is valid if
@@ -4836,6 +4820,10 @@ class OffloadingActionBuilder final {
4836
4820
// / List of static archives to extract FPGA dependency info from
4837
4821
ActionList FPGAArchiveInputs;
4838
4822
4823
+ // / List of AOCR based archives that contain BC members to use for
4824
+ // / providing symbols and properties.
4825
+ ActionList FPGAAOCArchives;
4826
+
4839
4827
// SYCLInstallation is needed in order to link SYCLDeviceLibs
4840
4828
SYCLInstallationDetector SYCLInstallation;
4841
4829
@@ -5281,6 +5269,9 @@ class OffloadingActionBuilder final {
5281
5269
5282
5270
// List of device objects that go through the device link step.
5283
5271
ActionList LinkObjects;
5272
+
5273
+ // List of FPGA AOC specific device objects/archives.
5274
+ ActionList FPGAAOCDevices;
5284
5275
auto TargetTriple = TC->getTriple ();
5285
5276
auto IsNVPTX = TargetTriple.isNVPTX ();
5286
5277
auto IsAMDGCN = TargetTriple.isAMDGCN ();
@@ -5301,27 +5292,16 @@ class OffloadingActionBuilder final {
5301
5292
}
5302
5293
// FPGA aocr/aocx does not go through the link and is passed
5303
5294
// directly to the backend compilation step (aocr) or wrapper (aocx)
5304
- Action *FPGAAOTAction;
5305
- if (Input->getType () == types::TY_FPGA_AOCR ||
5306
- Input->getType () == types::TY_FPGA_AOCR_EMU)
5307
- // Generate AOCX/AOCR
5308
- FPGAAOTAction =
5309
- C.MakeAction <BackendCompileJobAction>(Input, FPGAOutType);
5310
- else if (Input->getType () == types::TY_FPGA_AOCX)
5311
- FPGAAOTAction = Input;
5312
- else
5313
- llvm_unreachable (" Unexpected FPGA input type." );
5314
- // Rename the column within the table. The list of files that is
5315
- // produced from the AOT offline complation step is just a list of
5316
- // files. Rename with the [Code] designator to be processed by
5317
- // the offload-wrapper in -batch mode.
5318
- auto *RenameAction = C.MakeAction <FileTableTformJobAction>(
5319
- FPGAAOTAction, types::TY_Tempfilelist, types::TY_Tempfilelist);
5320
- RenameAction->addRenameColumnTform (FileTableTformJobAction::COL_ZERO,
5321
- FileTableTformJobAction::COL_CODE);
5322
- auto *DeviceWrappingAction = C.MakeAction <OffloadWrapperJobAction>(
5323
- RenameAction, types::TY_Object);
5324
- addDeps (DeviceWrappingAction, TC, BoundArch);
5295
+ if (Args.hasArg (options::OPT_fintelfpga)) {
5296
+ if (Input->getType () == types::TY_FPGA_AOCR ||
5297
+ Input->getType () == types::TY_FPGA_AOCR_EMU ||
5298
+ Input->getType () == types::TY_FPGA_AOCX)
5299
+ // Save the AOCR device items. These will be processed along
5300
+ // with the FPGAAOCArchives.
5301
+ FPGAAOCDevices.push_back (Input);
5302
+ else
5303
+ llvm_unreachable (" Unexpected FPGA input type." );
5304
+ }
5325
5305
continue ;
5326
5306
} else if (!types::isFPGA (Input->getType ())) {
5327
5307
// No need for any conversion if we are coming in from the
@@ -5342,6 +5322,73 @@ class OffloadingActionBuilder final {
5342
5322
LinkObjects.push_back (ConvertSPIRVAction);
5343
5323
}
5344
5324
}
5325
+ // Process AOCR/AOCR_EMU
5326
+ if (FPGAAOCDevices.size ()) {
5327
+ assert (FPGAAOCDevices.size () == FPGAAOCArchives.size () &&
5328
+ " Unexpected number of AOC binaries" );
5329
+ // Generate AOCX/AOCR
5330
+ // Input is the unbundled device binary. Perform an additional
5331
+ // unbundle against the input file associated to grab the wrapped
5332
+ // device binary.
5333
+ for (auto AOCRItem : llvm::zip (FPGAAOCArchives, FPGAAOCDevices)) {
5334
+ Action *Archive = std::get<0 >(AOCRItem);
5335
+ Action *Device = std::get<1 >(AOCRItem);
5336
+
5337
+ auto *UnbundleAction = C.MakeAction <OffloadUnbundlingJobAction>(
5338
+ Archive, types::TY_Tempfilelist);
5339
+ UnbundleAction->registerDependentActionInfo (TC, /* BoundArch=*/ " " ,
5340
+ Action::OFK_SYCL);
5341
+ auto *RenameUnbundle = C.MakeAction <FileTableTformJobAction>(
5342
+ UnbundleAction, types::TY_Tempfilelist, types::TY_Tempfilelist);
5343
+ RenameUnbundle->addRenameColumnTform (
5344
+ FileTableTformJobAction::COL_ZERO,
5345
+ FileTableTformJobAction::COL_SYM_AND_PROPS);
5346
+
5347
+ // Wrap the unbundled device binary along with the additional
5348
+ // .bc file that contains the Symbols and Properties
5349
+ if (Device->getType () == types::TY_FPGA_AOCX) {
5350
+ auto *RenameAction = C.MakeAction <FileTableTformJobAction>(
5351
+ Device, types::TY_Tempfilelist, types::TY_Tempfilelist);
5352
+ RenameAction->addRenameColumnTform (
5353
+ FileTableTformJobAction::COL_ZERO,
5354
+ FileTableTformJobAction::COL_CODE);
5355
+ ActionList WrapperItems ({RenameAction, RenameUnbundle});
5356
+ auto *DeviceWrappingAction = C.MakeAction <OffloadWrapperJobAction>(
5357
+ WrapperItems, types::TY_Object);
5358
+ addDeps (DeviceWrappingAction, TC, BoundArch);
5359
+ } else {
5360
+ auto *FPGAAOTAction =
5361
+ C.MakeAction <BackendCompileJobAction>(Device, FPGAOutType);
5362
+ auto *RenameAction = C.MakeAction <FileTableTformJobAction>(
5363
+ FPGAAOTAction, types::TY_Tempfilelist, types::TY_Tempfilelist);
5364
+ RenameAction->addRenameColumnTform (
5365
+ FileTableTformJobAction::COL_ZERO,
5366
+ FileTableTformJobAction::COL_CODE);
5367
+ ActionList WrapperItems ({RenameAction, RenameUnbundle});
5368
+ auto *DeviceWrappingAction = C.MakeAction <OffloadWrapperJobAction>(
5369
+ WrapperItems, types::TY_Object);
5370
+
5371
+ Action *DeviceAction = DeviceWrappingAction;
5372
+ if (Args.hasArg (options::OPT_fsycl_link_EQ)) {
5373
+ if (auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5374
+ OWA->setCompileStep (false );
5375
+ ActionList BundlingActions;
5376
+ BundlingActions.push_back (DeviceWrappingAction);
5377
+ DeviceAction =
5378
+ C.MakeAction <OffloadBundlingJobAction>(BundlingActions);
5379
+ // We created a bundled section for the wrapped images that
5380
+ // are not compiled. Create another image set that are
5381
+ // compiled. This set would be extracted for feeding into
5382
+ // the offline compilation step when consumed.
5383
+ Action *CompiledDeviceAction =
5384
+ C.MakeAction <OffloadWrapperJobAction>(WrapperItems,
5385
+ types::TY_Object);
5386
+ addDeps (CompiledDeviceAction, TC, nullptr );
5387
+ }
5388
+ addDeps (DeviceAction, TC, nullptr );
5389
+ }
5390
+ }
5391
+ }
5345
5392
for (const auto &A : SYCLFinalDeviceList) {
5346
5393
// Given the list of archives that have final device binaries, take
5347
5394
// those archives and unbundle all of the devices seen. These will
@@ -5689,14 +5736,39 @@ class OffloadingActionBuilder final {
5689
5736
}
5690
5737
5691
5738
// After the Link, wrap the files before the final host link
5739
+ // Add the unbundled wrapped AOC device binary to the wrapper
5740
+ // call.
5692
5741
auto *DeviceWrappingAction = C.MakeAction <OffloadWrapperJobAction>(
5693
5742
WrapperInputs, types::TY_Object);
5694
5743
5695
5744
if (IsSpirvAOT) {
5696
- bool AddBA =
5697
- (TargetTriple.getSubArch () == llvm::Triple::SPIRSubArch_gen &&
5698
- BoundArch != nullptr );
5699
- addDeps (DeviceWrappingAction, TC, AddBA ? BoundArch : nullptr );
5745
+ // For FPGA with -fsycl-link, we need to bundle the output.
5746
+ if (TargetTriple.getSubArch () == llvm::Triple::SPIRSubArch_fpga) {
5747
+ Action *DeviceAction = DeviceWrappingAction;
5748
+ if (Args.hasArg (options::OPT_fsycl_link_EQ)) {
5749
+ // We do not want to compile the wrapped binary before the link.
5750
+ if (auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5751
+ OWA->setCompileStep (false );
5752
+ ActionList BundlingActions;
5753
+ BundlingActions.push_back (DeviceWrappingAction);
5754
+ DeviceAction =
5755
+ C.MakeAction <OffloadBundlingJobAction>(BundlingActions);
5756
+ // We created a bundled section for the wrapped images that
5757
+ // are not compiled. Create another image set that are
5758
+ // compiled. This set would be extracted for feeding into
5759
+ // the offline compilation step when consumed.
5760
+ Action *CompiledDeviceAction =
5761
+ C.MakeAction <OffloadWrapperJobAction>(WrapperInputs,
5762
+ types::TY_Object);
5763
+ addDeps (CompiledDeviceAction, TC, nullptr );
5764
+ }
5765
+ addDeps (DeviceAction, TC, nullptr );
5766
+ } else {
5767
+ bool AddBA =
5768
+ (TargetTriple.getSubArch () == llvm::Triple::SPIRSubArch_gen &&
5769
+ BoundArch != nullptr );
5770
+ addDeps (DeviceWrappingAction, TC, AddBA ? BoundArch : nullptr );
5771
+ }
5700
5772
} else {
5701
5773
withBoundArchForToolChain (TC, [&](const char *BoundArch) {
5702
5774
addDeps (DeviceWrappingAction, TC, BoundArch);
@@ -6346,13 +6418,22 @@ class OffloadingActionBuilder final {
6346
6418
Action *Current = C.MakeAction <InputAction>(*InputArg, Type);
6347
6419
return Current;
6348
6420
};
6349
- // Populate FPGA static archives that could contain dep files to be
6350
- // incorporated into the aoc compilation
6421
+ // Populate FPGA archives that could contain dep files to be
6422
+ // incorporated into the aoc compilation. Consider AOCR type archives
6423
+ // as well for tracking symbols and properties information.
6351
6424
if (SYCLfpgaTriple && Args.hasArg (options::OPT_fintelfpga)) {
6352
6425
SmallVector<const char *, 16 > LinkArgs (getLinkerArgs (C, Args));
6353
6426
for (StringRef LA : LinkArgs) {
6354
- if (isStaticArchiveFile (LA) && hasOffloadSections (C, LA, Args))
6427
+ if (isStaticArchiveFile (LA) && hasOffloadSections (C, LA, Args)) {
6355
6428
FPGAArchiveInputs.push_back (makeInputAction (LA, types::TY_Archive));
6429
+ for (types::ID Type : {types::TY_FPGA_AOCR, types::TY_FPGA_AOCR_EMU,
6430
+ types::TY_FPGA_AOCX}) {
6431
+ if (hasFPGABinary (C, LA.str (), Type)) {
6432
+ FPGAAOCArchives.push_back (makeInputAction (LA, Type));
6433
+ break ;
6434
+ }
6435
+ }
6436
+ }
6356
6437
}
6357
6438
}
6358
6439
// Discover any objects and archives that contain final device binaries.
@@ -6604,7 +6685,6 @@ class OffloadingActionBuilder final {
6604
6685
// An FPGA AOCX input does not have a host dependence to the unbundler
6605
6686
if (HostAction->getType () == types::TY_FPGA_AOCX)
6606
6687
return false ;
6607
-
6608
6688
recordHostAction (HostAction, InputArg);
6609
6689
6610
6690
// If we are supporting bundling/unbundling and the current action is an
@@ -8862,9 +8942,13 @@ InputInfoList Driver::BuildJobsForActionNoCache(
8862
8942
Ext = " txt" ;
8863
8943
}
8864
8944
if (JA->getType () == types::TY_FPGA_AOCR ||
8865
- JA->getType () == types::TY_FPGA_AOCR_EMU)
8945
+ JA->getType () == types::TY_FPGA_AOCX ||
8946
+ JA->getType () == types::TY_FPGA_AOCR_EMU) {
8947
+ if (IsFPGAObjLink)
8948
+ continue ;
8866
8949
// AOCR files are always unbundled into a list file.
8867
8950
TI = types::TY_Tempfilelist;
8951
+ }
8868
8952
} else {
8869
8953
if (UI.DependentOffloadKind == Action::OFK_SYCL)
8870
8954
// Do not add the current info for device with FPGA device. The
0 commit comments