@@ -659,79 +659,82 @@ jit_compiler::performPostLink(std::unique_ptr<llvm::Module> Module,
659659 // TODO: Call `verifyNoCrossModuleDeviceGlobalUsage` if device globals shall
660660 // be processed.
661661
662- // TODO: This allocation assumes that there are no further splits required,
663- // i.e. there are no mixed SYCL/ESIMD modules.
664- RTCBundleInfo BundleInfo;
665- BundleInfo.DevImgInfos = DynArray<RTCDevImgInfo>{Splitter->remainingSplits ()};
662+ SmallVector<RTCDevImgInfo> DevImgInfoVec;
666663 SmallVector<std::unique_ptr<llvm::Module>> Modules;
667664
668- auto *DevImgInfoIt = BundleInfo.DevImgInfos .begin ();
669- while (Splitter->hasMoreSplits ()) {
670- assert (DevImgInfoIt != BundleInfo.DevImgInfos .end ());
665+ // TODO: The following logic is missing the ability to link ESIMD and SYCL
666+ // modules back together, which would be requested via
667+ // `-fno-sycl-device-code-split-esimd` as a prerequisite for compiling
668+ // `invoke_simd` code.
671669
670+ while (Splitter->hasMoreSplits ()) {
672671 ModuleDesc MDesc = Splitter->nextSplit ();
673- RTCDevImgInfo &DevImgInfo = *DevImgInfoIt++;
674672
675673 // TODO: Call `MDesc.fixupLinkageOfDirectInvokeSimdTargets()` when
676674 // `invoke_simd` is supported.
677675
678676 SmallVector<ModuleDesc, 2 > ESIMDSplits =
679677 splitByESIMD (std::move (MDesc), EmitOnlyKernelsAsEntryPoints);
680- assert (!ESIMDSplits.empty ());
681- if (ESIMDSplits.size () > 1 ) {
682- return createStringError (" Mixing SYCL and ESIMD code is unsupported" );
683- }
684- MDesc = std::move (ESIMDSplits.front ());
685-
686- if (MDesc.isESIMD ()) {
687- // `sycl-post-link` has a `-lower-esimd` option, but there's no clang
688- // driver option to influence it. Rather, the driver sets it
689- // unconditionally in the multi-file output mode, which we are mimicking
690- // here.
691- lowerEsimdConstructs (MDesc, PerformOpts);
692- }
693-
694- MDesc.saveSplitInformationAsMetadata ();
695-
696- DevImgInfo.SymbolTable = FrozenSymbolTable{MDesc.entries ().size ()};
697- transform (MDesc.entries (), DevImgInfo.SymbolTable .begin (),
698- [](Function *F) { return F->getName (); });
699-
700- // TODO: Determine what is requested.
701- GlobalBinImageProps PropReq{
702- /* EmitKernelParamInfo=*/ true , /* EmitProgramMetadata=*/ true ,
703- /* EmitExportedSymbols=*/ true , /* EmitImportedSymbols=*/ true ,
704- /* DeviceGlobals=*/ false };
705- PropertySetRegistry Properties =
706- computeModuleProperties (MDesc.getModule (), MDesc.entries (), PropReq);
707- // TODO: Manually add `compile_target` property as in
708- // `saveModuleProperties`?
709- const auto &PropertySets = Properties.getPropSets ();
710-
711- DevImgInfo.Properties = FrozenPropertyRegistry{PropertySets.size ()};
712- for (auto [KV, FrozenPropSet] :
713- zip_equal (PropertySets, DevImgInfo.Properties )) {
714- const auto &PropertySetName = KV.first ;
715- const auto &PropertySet = KV.second ;
716- FrozenPropSet =
717- FrozenPropertySet{PropertySetName.str (), PropertySet.size ()};
718- for (auto [KV2, FrozenProp] :
719- zip_equal (PropertySet, FrozenPropSet.Values )) {
720- const auto &PropertyName = KV2.first ;
721- const auto &PropertyValue = KV2.second ;
722- FrozenProp =
723- PropertyValue.getType () == PropertyValue::Type::UINT32
724- ? FrozenPropertyValue{PropertyName.str (),
725- PropertyValue.asUint32 ()}
726- : FrozenPropertyValue{PropertyName.str (),
727- PropertyValue.asRawByteArray (),
728- PropertyValue.getRawByteArraySize ()};
678+ for (auto &ES : ESIMDSplits) {
679+ MDesc = std::move (ES);
680+
681+ if (MDesc.isESIMD ()) {
682+ // `sycl-post-link` has a `-lower-esimd` option, but there's no clang
683+ // driver option to influence it. Rather, the driver sets it
684+ // unconditionally in the multi-file output mode, which we are mimicking
685+ // here.
686+ lowerEsimdConstructs (MDesc, PerformOpts);
729687 }
730- };
731688
732- Modules.push_back (MDesc.releaseModulePtr ());
689+ MDesc.saveSplitInformationAsMetadata ();
690+
691+ RTCDevImgInfo &DevImgInfo = DevImgInfoVec.emplace_back ();
692+ DevImgInfo.SymbolTable = FrozenSymbolTable{MDesc.entries ().size ()};
693+ transform (MDesc.entries (), DevImgInfo.SymbolTable .begin (),
694+ [](Function *F) { return F->getName (); });
695+
696+ // TODO: Determine what is requested.
697+ GlobalBinImageProps PropReq{
698+ /* EmitKernelParamInfo=*/ true , /* EmitProgramMetadata=*/ true ,
699+ /* EmitExportedSymbols=*/ true , /* EmitImportedSymbols=*/ true ,
700+ /* DeviceGlobals=*/ false };
701+ PropertySetRegistry Properties =
702+ computeModuleProperties (MDesc.getModule (), MDesc.entries (), PropReq);
703+ // TODO: Manually add `compile_target` property as in
704+ // `saveModuleProperties`?
705+ const auto &PropertySets = Properties.getPropSets ();
706+
707+ DevImgInfo.Properties = FrozenPropertyRegistry{PropertySets.size ()};
708+ for (auto [KV, FrozenPropSet] :
709+ zip_equal (PropertySets, DevImgInfo.Properties )) {
710+ const auto &PropertySetName = KV.first ;
711+ const auto &PropertySet = KV.second ;
712+ FrozenPropSet =
713+ FrozenPropertySet{PropertySetName.str (), PropertySet.size ()};
714+ for (auto [KV2, FrozenProp] :
715+ zip_equal (PropertySet, FrozenPropSet.Values )) {
716+ const auto &PropertyName = KV2.first ;
717+ const auto &PropertyValue = KV2.second ;
718+ FrozenProp =
719+ PropertyValue.getType () == PropertyValue::Type::UINT32
720+ ? FrozenPropertyValue{PropertyName.str (),
721+ PropertyValue.asUint32 ()}
722+ : FrozenPropertyValue{PropertyName.str (),
723+ PropertyValue.asRawByteArray (),
724+ PropertyValue.getRawByteArraySize ()};
725+ }
726+ };
727+
728+ Modules.push_back (MDesc.releaseModulePtr ());
729+ }
733730 }
734731
732+ assert (DevImgInfoVec.size () == Modules.size ());
733+ RTCBundleInfo BundleInfo;
734+ BundleInfo.DevImgInfos = DynArray<RTCDevImgInfo>{DevImgInfoVec.size ()};
735+ std::move (DevImgInfoVec.begin (), DevImgInfoVec.end (),
736+ BundleInfo.DevImgInfos .begin ());
737+
735738 return PostLinkResult{std::move (BundleInfo), std::move (Modules)};
736739}
737740
0 commit comments