@@ -3131,9 +3131,6 @@ class OffloadingActionBuilder final {
3131
3131
// / The linker inputs obtained for each toolchain.
3132
3132
SmallVector<ActionList, 8 > DeviceLinkerInputs;
3133
3133
3134
- // / Host object list
3135
- ActionList HostObjectList;
3136
-
3137
3134
// / The compiler inputs obtained for each toolchain
3138
3135
Action * DeviceCompilerInput = nullptr ;
3139
3136
@@ -3146,7 +3143,7 @@ class OffloadingActionBuilder final {
3146
3143
unsigned FPGArCount = 0 ;
3147
3144
3148
3145
// / Type of output file for FPGA device compilation.
3149
- types::ID FPGAOutType = types::TY_Image ;
3146
+ types::ID FPGAOutType = types::TY_FPGA_AOCX ;
3150
3147
3151
3148
public:
3152
3149
SYCLActionBuilder (Compilation &C, DerivedArgList &Args,
@@ -3191,51 +3188,15 @@ class OffloadingActionBuilder final {
3191
3188
// for each device and link them together to a single binary that will
3192
3189
// be used in a split compilation step.
3193
3190
if (CompileDeviceOnly && !SYCLDeviceActions.empty ()) {
3194
- bool SYCLAOTCompile = false ;
3195
- unsigned I = 0 ;
3196
- for (auto SDA : SYCLDeviceActions) {
3191
+ for (auto SDA : SYCLDeviceActions)
3197
3192
SYCLLinkBinaryList.push_back (SDA);
3198
- auto TT = SYCLTripleList[I];
3199
- if (TT.getSubArch () == llvm::Triple::SPIRSubArch_fpga ||
3200
- TT.getSubArch () == llvm::Triple::SPIRSubArch_gen)
3201
- SYCLAOTCompile = true ;
3202
- I++;
3203
- }
3204
- if (WrapDeviceOnlyBinary && !SYCLAOTCompile) {
3193
+ if (WrapDeviceOnlyBinary) {
3205
3194
auto *DeviceLinkAction =
3206
3195
C.MakeAction <LinkJobAction>(SYCLLinkBinaryList, types::TY_Image);
3207
3196
// Wrap the binary when -fsycl-link is given
3208
3197
SYCLLinkBinary =
3209
3198
C.MakeAction <OffloadWrappingJobAction>(DeviceLinkAction,
3210
3199
types::TY_Object);
3211
- } else if (SYCLAOTCompile) {
3212
- // All inputs have corresponding dependency files when built with
3213
- // -fintelfpga. Gather those here.
3214
- auto *LinkAction = C.MakeAction <LinkJobAction>(SYCLLinkBinaryList,
3215
- types::TY_SPIRV);
3216
- // Do the additional Ahead of Time compilation when the specific
3217
- // triple calls for it (provided a valid subarch).
3218
- auto *DeviceBECompileAction =
3219
- C.MakeAction <BackendCompileJobAction>(LinkAction, FPGAOutType);
3220
-
3221
- // When performing -fsycl-link with FPGA, we will take the
3222
- // generated device binary and bundle that with all of the host
3223
- // objects (partially linked together).
3224
- if (!HostObjectList.empty ()) {
3225
- // Bundling job only takes a single host and target object, so
3226
- // perform the partial link and send that into the bundler
3227
- auto *PartialLinkAction =
3228
- C.MakeAction <LinkJobAction>(HostObjectList,
3229
- types::TY_Object);
3230
- // Add the host action to the list in order to create the
3231
- // bundling action.
3232
- ActionList OffloadAL;
3233
- OffloadAL.push_back (DeviceBECompileAction);
3234
- OffloadAL.push_back (PartialLinkAction);
3235
-
3236
- SYCLLinkBinary =
3237
- C.MakeAction <OffloadBundlingJobAction>(OffloadAL);
3238
- }
3239
3200
} else
3240
3201
SYCLLinkBinary = C.MakeAction <LinkJobAction>(SYCLLinkBinaryList,
3241
3202
types::TY_Image);
@@ -3303,11 +3264,6 @@ class OffloadingActionBuilder final {
3303
3264
if (IA->getType () == types::TY_Object ||
3304
3265
IA->getType () == types::TY_FPGA_AOCX ||
3305
3266
IA->getType () == types::TY_FPGA_AOCR) {
3306
- OffloadingActionBuilder OffloadBuilder (C, Args, Inputs);
3307
- if (Args.hasArg (options::OPT_fsycl_link_EQ)) {
3308
- HostObjectList.push_back (
3309
- C.MakeAction <InputAction>(IA->getInputArg (), types::TY_Object));
3310
- }
3311
3267
// Keep track of the number of FPGA devices encountered
3312
3268
// Only one of these is allowed at a single time.
3313
3269
if (IA->getType () == types::TY_FPGA_AOCX)
@@ -3379,20 +3335,23 @@ class OffloadingActionBuilder final {
3379
3335
// Perform a check for device kernels. This is done for FPGA when an
3380
3336
// aocx or aocr based file is found.
3381
3337
if (FPGAxCount || FPGArCount) {
3338
+ ActionList DeviceObjects;
3382
3339
for (const auto &I : LI) {
3383
3340
if (I->getType () == types::TY_Object) {
3384
- auto *DeviceCheckAction =
3385
- C.MakeAction <SPIRCheckJobAction>(I, types::TY_Image);
3386
- DA.add (*DeviceCheckAction, **TC, /* BoundArch=*/ nullptr ,
3387
- Action::OFK_SYCL);
3341
+ // FIXME - Checker does not work well inline with the tool
3342
+ // chain, but it needs to be here for real time checking
3343
+ // auto *DeviceCheckAction =
3344
+ // C.MakeAction<SPIRCheckJobAction>(I, types::TY_Object);
3345
+ // DeviceObjects.push_back(DeviceCheckAction);
3346
+ DeviceObjects.push_back (I);
3388
3347
} else {
3389
3348
// Do not perform a device link and only pass the aocr
3390
3349
// file to the offline compilation before wrapping. Just
3391
3350
// wrap an aocx file.
3392
3351
Action * DeviceWrappingAction;
3393
3352
if (I->getType () == types::TY_FPGA_AOCR) {
3394
3353
auto *DeviceBECompileAction =
3395
- C.MakeAction <BackendCompileJobAction>(I, types::TY_Image );
3354
+ C.MakeAction <BackendCompileJobAction>(I, FPGAOutType );
3396
3355
DeviceWrappingAction =
3397
3356
C.MakeAction <OffloadWrappingJobAction>(
3398
3357
DeviceBECompileAction, types::TY_Object);
@@ -3403,6 +3362,17 @@ class OffloadingActionBuilder final {
3403
3362
Action::OFK_SYCL);
3404
3363
}
3405
3364
}
3365
+ if (!DeviceObjects.empty ()) {
3366
+ // link and wrap the device binary, but do not perform the
3367
+ // backend compile.
3368
+ auto *DeviceLinkAction =
3369
+ C.MakeAction <LinkJobAction>(DeviceObjects, types::TY_SPIRV);
3370
+ auto *DeviceWrappingAction =
3371
+ C.MakeAction <OffloadWrappingJobAction>(DeviceLinkAction,
3372
+ types::TY_Object);
3373
+ DA.add (*DeviceWrappingAction, **TC, /* BoundArch=*/ nullptr ,
3374
+ Action::OFK_SYCL);
3375
+ }
3406
3376
continue ;
3407
3377
}
3408
3378
auto *DeviceLinkAction =
@@ -3417,7 +3387,7 @@ class OffloadingActionBuilder final {
3417
3387
if (SYCLAOTCompile) {
3418
3388
types::ID OutType = types::TY_Image;
3419
3389
if (TT.getSubArch () == llvm::Triple::SPIRSubArch_fpga)
3420
- OutType = types::TY_FPGA_AOCX ;
3390
+ OutType = FPGAOutType ;
3421
3391
// Do the additional Ahead of Time compilation when the specific
3422
3392
// triple calls for it (provided a valid subarch).
3423
3393
auto *DeviceBECompileAction =
@@ -3474,10 +3444,10 @@ class OffloadingActionBuilder final {
3474
3444
Arg *SYCLLinkTargets = Args.getLastArg (
3475
3445
options::OPT_fsycl_link_targets_EQ);
3476
3446
WrapDeviceOnlyBinary = Args.hasArg (options::OPT_fsycl_link_EQ);
3477
- CompileDeviceOnly = (SYCLLinkTargets &&
3478
- SYCLLinkTargets-> getOption (). matches (
3479
- options::OPT_fsycl_link_targets_EQ)) ||
3480
- WrapDeviceOnlyBinary ;
3447
+ // Device only compilation for -fsycl-link (no FPGA) and
3448
+ // -fsycl-link-targets
3449
+ CompileDeviceOnly = (SYCLLinkTargets || (WrapDeviceOnlyBinary &&
3450
+ !Args. hasArg (options::OPT_fintelfpga))) ;
3481
3451
Arg *SYCLAddTargets = Args.getLastArg (
3482
3452
options::OPT_fsycl_add_targets_EQ);
3483
3453
if (SYCLAddTargets) {
@@ -3687,12 +3657,13 @@ class OffloadingActionBuilder final {
3687
3657
3688
3658
// Checking uses -check-section option with the input file, no output
3689
3659
// file and the target triple being looked for.
3690
- const char *Targets = C.getArgs ().MakeArgString (Twine (" -targets=fpga -" ) +
3660
+ const char *Targets = C.getArgs ().MakeArgString (Twine (" -targets=sycl -" ) +
3691
3661
TT.str ());
3692
3662
const char *Inputs = C.getArgs ().MakeArgString (Twine (" -inputs=" ) +
3693
3663
Object);
3694
- // Always use -type=o for aocx/aocr bundle checking.
3695
- const char *Type = C.getArgs ().MakeArgString (" -type=o" );
3664
+ // Always use -type=ao for aocx/aocr bundle checking. The 'bundles' are
3665
+ // actually archives.
3666
+ const char *Type = C.getArgs ().MakeArgString (" -type=ao" );
3696
3667
std::vector<StringRef> BundlerArgs = { " clang-offload-bundler" ,
3697
3668
Type,
3698
3669
Targets,
@@ -3715,8 +3686,6 @@ class OffloadingActionBuilder final {
3715
3686
else
3716
3687
llvm::errs () << A << " " ;
3717
3688
llvm::errs () << ' \n ' ;
3718
- if (OutputOnly)
3719
- return false ;
3720
3689
}
3721
3690
if (BundlerBinary.getError ())
3722
3691
return false ;
@@ -3764,19 +3733,22 @@ class OffloadingActionBuilder final {
3764
3733
types::TY_Object &&
3765
3734
Args.hasArg (options::OPT_foffload_static_lib_EQ))) {
3766
3735
ActionList HostActionList;
3736
+ Action * A (HostAction);
3767
3737
// Only check for FPGA device information when using fpga SubArch.
3768
3738
if (Args.hasArg (options::OPT_fintelfpga) &&
3769
- HasFPGADeviceBinary (C, InputArg->getAsString (Args), true )) {
3770
- Action * FPGAAction =
3771
- C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCX);
3772
- HostActionList.push_back (FPGAAction);
3773
- } else if (Args.hasArg (options::OPT_fintelfpga) &&
3774
- HasFPGADeviceBinary (C, InputArg->getAsString (Args))) {
3775
- Action * FPGAAction =
3776
- C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCR);
3777
- HostActionList.push_back (FPGAAction);
3778
- } else
3779
- HostActionList.push_back (HostAction);
3739
+ HostAction->getType () != types::TY_FPGA_AOCR &&
3740
+ HostAction->getType () != types::TY_FPGA_AOCX &&
3741
+ !(HostAction->getType () == types::TY_Object &&
3742
+ llvm::sys::path::has_extension (InputName) &&
3743
+ types::lookupTypeForExtension (
3744
+ llvm::sys::path::extension (InputName).drop_front ()) ==
3745
+ types::TY_Object)) {
3746
+ if (HasFPGADeviceBinary (C, InputArg->getAsString (Args), true ))
3747
+ A = C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCX);
3748
+ else if (HasFPGADeviceBinary (C, InputArg->getAsString (Args)))
3749
+ A = C.MakeAction <InputAction>(*InputArg, types::TY_FPGA_AOCR);
3750
+ }
3751
+ HostActionList.push_back (A);
3780
3752
if (!HostActionList.empty ()) {
3781
3753
auto UnbundlingHostAction =
3782
3754
C.MakeAction <OffloadUnbundlingJobAction>(HostActionList);
@@ -4230,10 +4202,35 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
4230
4202
Current, InputArg, phases::Link, FinalPhase, PL);
4231
4203
}
4232
4204
}
4205
+ // For an FPGA archive, we add the unbundling step above to take care of
4206
+ // the device side, but also unbundle here to extract the host side
4207
+ for (const auto &LI : LinkerInputs) {
4208
+ Action *UnbundlerInput = nullptr ;
4209
+ if (auto *IA = dyn_cast<InputAction>(LI)) {
4210
+ if (IA->getType () == types::TY_FPGA_AOCR ||
4211
+ IA->getType () == types::TY_FPGA_AOCX) {
4212
+ // Add to unbundler.
4213
+ UnbundlerInput = LI;
4214
+ }
4215
+ }
4216
+ if (UnbundlerInput) {
4217
+ if (auto *IA = dyn_cast<InputAction>(UnbundlerInput)) {
4218
+ std::string FileName = IA->getInputArg ().getAsString (Args);
4219
+ Arg *InputArg = MakeInputArg (Args, *Opts, FileName);
4220
+ OffloadBuilder.addHostDependenceToDeviceActions (UnbundlerInput,
4221
+ InputArg, Args);
4222
+ OffloadBuilder.addDeviceDependencesToHostAction (UnbundlerInput,
4223
+ InputArg, phases::Link, FinalPhase, PL);
4224
+ }
4225
+ }
4226
+ }
4233
4227
4234
4228
// Add a link action if necessary.
4235
4229
if (!LinkerInputs.empty ()) {
4236
- Action *LA = C.MakeAction <LinkJobAction>(LinkerInputs, types::TY_Image);
4230
+ types::ID LinkType (types::TY_Image);
4231
+ if (Args.hasArg (options::OPT_fsycl_link_EQ))
4232
+ LinkType = types::TY_Archive;
4233
+ Action *LA = C.MakeAction <LinkJobAction>(LinkerInputs, LinkType);
4237
4234
LA = OffloadBuilder.processHostLinkAction (LA);
4238
4235
Actions.push_back (LA);
4239
4236
}
@@ -5011,17 +5008,33 @@ InputInfo Driver::BuildJobsForActionNoCache(
5011
5008
C.addTempFile (C.getArgs ().MakeArgString (TmpFileName),
5012
5009
types::TY_Tempfilelist);
5013
5010
CurI = InputInfo (types::TY_Tempfilelist, TmpFile, TmpFile);
5014
- } else if (UI.DependentOffloadKind == Action::OFK_Host &&
5015
- EffectiveTriple.getSubArch () == llvm::Triple::SPIRSubArch_fpga &&
5016
- (JA->getType () == types::TY_FPGA_AOCX ||
5017
- JA->getType () == types::TY_FPGA_AOCR)) {
5018
- // Output file from unbundle is FPGA device. Name the file accordingly.
5011
+ } else if (JA->getType () == types::TY_FPGA_AOCX ||
5012
+ JA->getType () == types::TY_FPGA_AOCR) {
5013
+ std::string Ext (types::getTypeTempSuffix (JA->getType ()));
5014
+ types::ID TI = types::TY_Object;
5015
+ if (EffectiveTriple.getSubArch () == llvm::Triple::SPIRSubArch_fpga) {
5016
+ // Output file from unbundle is FPGA device. Name the file
5017
+ // accordingly.
5018
+ if (UI.DependentOffloadKind == Action::OFK_Host) {
5019
+ // Do not add the current info for Host with FPGA device. The host
5020
+ // side isn't used
5021
+ continue ;
5022
+ }
5023
+ } else if (EffectiveTriple.getSubArch () !=
5024
+ llvm::Triple::SPIRSubArch_fpga) {
5025
+ if (UI.DependentOffloadKind == Action::OFK_SYCL) {
5026
+ // Do not add the current info for device with FPGA device. The
5027
+ // device side isn't used
5028
+ continue ;
5029
+ }
5030
+ TI = types::TY_Tempfilelist;
5031
+ Ext = " txt" ;
5032
+ }
5019
5033
std::string TmpFileName =
5020
- C.getDriver ().GetTemporaryPath (llvm::sys::path::stem (BaseInput),
5021
- " o" );
5034
+ C.getDriver ().GetTemporaryPath (llvm::sys::path::stem (BaseInput), Ext);
5022
5035
const char *TmpFile =
5023
5036
C.addTempFile (C.getArgs ().MakeArgString (TmpFileName));
5024
- CurI = InputInfo (types::TY_Object , TmpFile, TmpFile);
5037
+ CurI = InputInfo (TI , TmpFile, TmpFile);
5025
5038
} else {
5026
5039
std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix (
5027
5040
UI.DependentOffloadKind ,
0 commit comments