@@ -1377,6 +1377,22 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
1377
1377
// Populate the tool chains for the offloading devices, if any.
1378
1378
CreateOffloadingDeviceToolChains (*C, Inputs);
1379
1379
1380
+ // Determine FPGA emulation status.
1381
+ if (C->hasOffloadToolChain <Action::OFK_SYCL>()) {
1382
+ auto SYCLTCRange = C->getOffloadToolChains <Action::OFK_SYCL>();
1383
+ ArgStringList TargetArgs;
1384
+ const ToolChain *TC = SYCLTCRange.first ->second ;
1385
+ const toolchains::SYCLToolChain *SYCLTC =
1386
+ static_cast <const toolchains::SYCLToolChain *>(TC);
1387
+ SYCLTC->TranslateBackendTargetArgs (*TranslatedArgs, TargetArgs);
1388
+ for (StringRef ArgString : TargetArgs) {
1389
+ if (ArgString.equals (" -hardware" ) || ArgString.equals (" -simulation" )) {
1390
+ setFPGAEmulationMode (false );
1391
+ break ;
1392
+ }
1393
+ }
1394
+ }
1395
+
1380
1396
// Construct the list of abstract actions to perform for this compilation. On
1381
1397
// MachO targets this uses the driver-driver and universal actions.
1382
1398
if (TC.getTriple ().isOSBinFormatMachO ())
@@ -4210,11 +4226,13 @@ class OffloadingActionBuilder final {
4210
4226
Action *FPGAAOTAction;
4211
4227
constexpr char COL_CODE[] = " Code" ;
4212
4228
constexpr char COL_ZERO[] = " 0" ;
4213
- if (Input->getType () == types::TY_FPGA_AOCR)
4229
+ if (Input->getType () == types::TY_FPGA_AOCR ||
4230
+ Input->getType () == types::TY_FPGA_AOCR_EMU)
4214
4231
// Generate AOCX/AOCR
4215
4232
FPGAAOTAction =
4216
4233
C.MakeAction <BackendCompileJobAction>(Input, FPGAOutType);
4217
- else if (Input->getType () == types::TY_FPGA_AOCX)
4234
+ else if (Input->getType () == types::TY_FPGA_AOCX ||
4235
+ Input->getType () == types::TY_FPGA_AOCX_EMU)
4218
4236
FPGAAOTAction = Input;
4219
4237
else
4220
4238
llvm_unreachable (" Unexpected FPGA input type." );
@@ -4563,9 +4581,15 @@ class OffloadingActionBuilder final {
4563
4581
(SYCLLinkTargets || (WrapDeviceOnlyBinary && !SYCLfpgaTriple));
4564
4582
4565
4583
// Set the FPGA output type based on command line (-fsycl-link).
4566
- if (auto * A = C.getInputArgs ().getLastArg (options::OPT_fsycl_link_EQ))
4584
+ if (auto *A = C.getInputArgs ().getLastArg (options::OPT_fsycl_link_EQ)) {
4567
4585
FPGAOutType = (A->getValue () == StringRef (" early" ))
4568
- ? types::TY_FPGA_AOCR : types::TY_FPGA_AOCX;
4586
+ ? types::TY_FPGA_AOCR
4587
+ : types::TY_FPGA_AOCX;
4588
+ if (C.getDriver ().isFPGAEmulationMode ())
4589
+ FPGAOutType = (A->getValue () == StringRef (" early" ))
4590
+ ? types::TY_FPGA_AOCR_EMU
4591
+ : types::TY_FPGA_AOCX_EMU;
4592
+ }
4569
4593
4570
4594
// Populate FPGA static archives that could contain dep files to be
4571
4595
// incorporated into the aoc compilation
@@ -4709,6 +4733,46 @@ class OffloadingActionBuilder final {
4709
4733
return C.MakeAction <OffloadAction>(HDep, DDeps);
4710
4734
}
4711
4735
4736
+ // Update Input action to reflect FPGA device archive specifics based
4737
+ // on archive contents.
4738
+ bool updateInputForFPGA (Action *&A, const Arg *InputArg,
4739
+ DerivedArgList &Args) {
4740
+ std::string InputName = InputArg->getAsString (Args);
4741
+ const Driver &D = C.getDriver ();
4742
+ bool IsFPGAEmulation = D.isFPGAEmulationMode ();
4743
+ // Only check for FPGA device information when using fpga SubArch.
4744
+ if (A->getType () == types::TY_Object && isObjectFile (InputName))
4745
+ return true ;
4746
+
4747
+ auto ArchiveTypeMismatch = [&D, &InputName](bool EmitDiag) {
4748
+ if (EmitDiag)
4749
+ D.Diag (clang::diag::warn_drv_mismatch_fpga_archive) << InputName;
4750
+ };
4751
+ // Type FPGA aoco is a special case for static archives
4752
+ if (A->getType () == types::TY_FPGA_AOCO) {
4753
+ if (!hasFPGABinary (C, InputName, types::TY_FPGA_AOCO))
4754
+ return false ;
4755
+ A = C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCO);
4756
+ return true ;
4757
+ }
4758
+
4759
+ SmallVector<std::pair<types::ID, bool >, 4 > FPGAAOCTypes = {
4760
+ {types::TY_FPGA_AOCX, false },
4761
+ {types::TY_FPGA_AOCR, false },
4762
+ {types::TY_FPGA_AOCX_EMU, true },
4763
+ {types::TY_FPGA_AOCR_EMU, true }};
4764
+ for (const auto &ArchiveType : FPGAAOCTypes) {
4765
+ bool BinaryFound = hasFPGABinary (C, InputName, ArchiveType.first );
4766
+ if (BinaryFound && ArchiveType.second == IsFPGAEmulation) {
4767
+ // Binary matches check and emulation type, we keep this one.
4768
+ A = C.MakeAction <InputAction>(*InputArg, ArchiveType.first );
4769
+ return true ;
4770
+ }
4771
+ ArchiveTypeMismatch (BinaryFound && ArchiveType.second != IsFPGAEmulation);
4772
+ }
4773
+ return true ;
4774
+ }
4775
+
4712
4776
// / Generate an action that adds a host dependence to a device action. The
4713
4777
// / results will be kept in this action builder. Return true if an error was
4714
4778
// / found.
@@ -4719,7 +4783,8 @@ class OffloadingActionBuilder final {
4719
4783
return true ;
4720
4784
4721
4785
// An FPGA AOCX input does not have a host dependence to the unbundler
4722
- if (HostAction->getType () == types::TY_FPGA_AOCX)
4786
+ if (HostAction->getType () == types::TY_FPGA_AOCX ||
4787
+ HostAction->getType () == types::TY_FPGA_AOCX_EMU)
4723
4788
return false ;
4724
4789
4725
4790
// If we are supporting bundling/unbundling and the current action is an
@@ -4734,7 +4799,6 @@ class OffloadingActionBuilder final {
4734
4799
!InputArg->getOption ().hasFlag (options::LinkerInput) &&
4735
4800
(!types::isSrcFile (HostAction->getType ()) ||
4736
4801
HostAction->getType () == types::TY_PP_HIP)) {
4737
- std::string InputName = InputArg->getAsString (Args);
4738
4802
ActionList HostActionList;
4739
4803
Action *A (HostAction);
4740
4804
// Only check for FPGA device information when using fpga SubArch.
@@ -4743,22 +4807,13 @@ class OffloadingActionBuilder final {
4743
4807
HasFPGATarget |= TI->second ->getTriple ().getSubArch () ==
4744
4808
llvm::Triple::SPIRSubArch_fpga;
4745
4809
bool isArchive = !(HostAction->getType () == types::TY_Object &&
4746
- isObjectFile (InputName ));
4810
+ isObjectFile (InputArg-> getAsString (Args) ));
4747
4811
if (!HasFPGATarget && isArchive &&
4748
4812
HostAction->getType () == types::TY_FPGA_AOCO)
4749
4813
// Archive with Non-FPGA target with AOCO type should not be unbundled.
4750
4814
return false ;
4751
- if (HasFPGATarget && isArchive) {
4752
- // Type FPGA aoco is a special case for -foffload-static-lib.
4753
- if (HostAction->getType () == types::TY_FPGA_AOCO) {
4754
- if (!hasFPGABinary (C, InputName, types::TY_FPGA_AOCO))
4755
- return false ;
4756
- A = C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCO);
4757
- } else if (hasFPGABinary (C, InputName, types::TY_FPGA_AOCX))
4758
- A = C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCX);
4759
- else if (hasFPGABinary (C, InputName, types::TY_FPGA_AOCR))
4760
- A = C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCR);
4761
- }
4815
+ if (HasFPGATarget && !updateInputForFPGA (A, InputArg, Args))
4816
+ return false ;
4762
4817
auto UnbundlingHostAction = C.MakeAction <OffloadUnbundlingJobAction>(A);
4763
4818
UnbundlingHostAction->registerDependentActionInfo (
4764
4819
C.getSingleOffloadToolChain <Action::OFK_Host>(),
@@ -4795,7 +4850,8 @@ class OffloadingActionBuilder final {
4795
4850
if ((OffloadKind == Action::OFK_None && CanUseBundler) ||
4796
4851
(HasFPGATarget && ((Args.hasArg (options::OPT_fsycl_link_EQ) &&
4797
4852
HostAction->getType () == types::TY_Object) ||
4798
- HostAction->getType () == types::TY_FPGA_AOCX)))
4853
+ HostAction->getType () == types::TY_FPGA_AOCX ||
4854
+ HostAction->getType () == types::TY_FPGA_AOCX_EMU)))
4799
4855
if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4800
4856
HostAction = UA->getInputs ().back ();
4801
4857
@@ -5245,8 +5301,13 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
5245
5301
continue ;
5246
5302
// FPGA AOCX/AOCR files are archives, but we do not want to unbundle them
5247
5303
// here as they have already been unbundled and processed for linking.
5304
+ // TODO: The multiple binary checks for FPGA types getting a little out
5305
+ // of hand. Improve this by doing a single scan of the args and holding
5306
+ // that in a data structure for reference.
5248
5307
if (hasFPGABinary (C, LA.str (), types::TY_FPGA_AOCX) ||
5249
- hasFPGABinary (C, LA.str (), types::TY_FPGA_AOCR))
5308
+ hasFPGABinary (C, LA.str (), types::TY_FPGA_AOCR) ||
5309
+ hasFPGABinary (C, LA.str (), types::TY_FPGA_AOCX_EMU) ||
5310
+ hasFPGABinary (C, LA.str (), types::TY_FPGA_AOCR_EMU))
5250
5311
continue ;
5251
5312
// For offload-static-libs we add an unbundling action for each static
5252
5313
// archive which produces list files with extracted objects. Device lists
@@ -5279,7 +5340,9 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
5279
5340
};
5280
5341
if (auto *IA = dyn_cast<InputAction>(LI)) {
5281
5342
if (IA->getType () == types::TY_FPGA_AOCR ||
5282
- IA->getType () == types::TY_FPGA_AOCX) {
5343
+ IA->getType () == types::TY_FPGA_AOCX ||
5344
+ IA->getType () == types::TY_FPGA_AOCR_EMU ||
5345
+ IA->getType () == types::TY_FPGA_AOCX_EMU) {
5283
5346
// Add to unbundler.
5284
5347
UnbundlerInput = LI;
5285
5348
} else {
@@ -6249,7 +6312,8 @@ InputInfo Driver::BuildJobsForActionNoCache(
6249
6312
TI = types::TY_TempAOCOfilelist;
6250
6313
Ext = " txt" ;
6251
6314
}
6252
- if (JA->getType () == types::TY_FPGA_AOCR)
6315
+ if (JA->getType () == types::TY_FPGA_AOCR ||
6316
+ JA->getType () == types::TY_FPGA_AOCR_EMU)
6253
6317
// AOCR files are always unbundled into a list file.
6254
6318
TI = types::TY_Tempfilelist;
6255
6319
} else if (EffectiveTriple.getSubArch () !=
0 commit comments