@@ -306,7 +306,8 @@ std::string saveModuleIR(Module &M, int I, StringRef Suff) {
306306
307307std::string saveModuleProperties (module_split::ModuleDesc &MD,
308308 const GlobalBinImageProps &GlobProps, int I,
309- StringRef Suff, StringRef Target = " " ) {
309+ StringRef Suff, StringRef Target = " " ,
310+ bool IsDummy = false ) {
310311 auto PropSet =
311312 computeModuleProperties (MD.getModule (), MD.entries (), GlobProps);
312313
@@ -318,6 +319,10 @@ std::string saveModuleProperties(module_split::ModuleDesc &MD,
318319 NewSuff += Target;
319320 }
320321
322+ if (IsDummy) {
323+ PropSet.add (PropSetRegTy::SYCL_VIRTUAL_FUNCTIONS, " dummy" , 1 );
324+ }
325+
321326 std::error_code EC;
322327 std::string SCFile = makeResultFileName (" .prop" , I, NewSuff);
323328 raw_fd_ostream SCOut (SCFile, EC);
@@ -416,7 +421,8 @@ void addTableRow(util::SimpleTable &Table,
416421// IR component saving is skipped, and this file name is recorded as such in
417422// the result.
418423void saveModule (std::vector<std::unique_ptr<util::SimpleTable>> &OutTables,
419- module_split::ModuleDesc &MD, int I, StringRef IRFilename) {
424+ module_split::ModuleDesc &MD, int I, StringRef IRFilename,
425+ bool IsDummy = false ) {
420426 IrPropSymFilenameTriple BaseTriple;
421427 StringRef Suffix = getModuleSuffix (MD);
422428 MD.saveSplitInformationAsMetadata ();
@@ -440,8 +446,8 @@ void saveModule(std::vector<std::unique_ptr<util::SimpleTable>> &OutTables,
440446 GlobalBinImageProps Props = {EmitKernelParamInfo, EmitProgramMetadata,
441447 EmitExportedSymbols, EmitImportedSymbols,
442448 DeviceGlobals};
443- CopyTriple.Prop =
444- saveModuleProperties (MD, Props, I, Suffix, OutputFile.Target );
449+ CopyTriple.Prop = saveModuleProperties (MD, Props, I, Suffix,
450+ OutputFile.Target , IsDummy );
445451 }
446452 addTableRow (*Table, CopyTriple);
447453 }
@@ -741,6 +747,36 @@ bool isTargetCompatibleWithModule(const std::string &Target,
741747 return true ;
742748}
743749
750+ std::optional<module_split::ModuleDesc>
751+ makeDummy (module_split::ModuleDesc &MD) {
752+ bool hasVirtualFunctions = false ;
753+ bool hasOptionalKernelFeatures = false ;
754+ for (Function &F : MD.getModule ().functions ()) {
755+ if (F.hasFnAttribute (" indirectly-callable" ))
756+ hasVirtualFunctions = true ;
757+ if (F.getMetadata (" sycl_used_aspects" ))
758+ hasOptionalKernelFeatures = true ;
759+ if (hasVirtualFunctions && hasOptionalKernelFeatures)
760+ break ;
761+ }
762+ if (!hasVirtualFunctions || !hasOptionalKernelFeatures)
763+ return {};
764+
765+ auto MDCopy = MD.clone ();
766+
767+ for (Function &F : MDCopy.getModule ().functions ()) {
768+ if (!F.hasFnAttribute (" indirectly-callable" ))
769+ continue ;
770+
771+ F.erase (F.begin (), F.end ());
772+ BasicBlock *newBB = BasicBlock::Create (F.getContext (), " entry" , &F);
773+ IRBuilder<> builder (newBB);
774+ builder.CreateRetVoid ();
775+ }
776+
777+ return MDCopy;
778+ }
779+
744780std::vector<std::unique_ptr<util::SimpleTable>>
745781processInputModule (std::unique_ptr<Module> M) {
746782 // Construct the resulting table which will accumulate all the outputs.
@@ -893,6 +929,16 @@ processInputModule(std::unique_ptr<Module> M) {
893929
894930 ++ID;
895931 }
932+
933+ bool dummyEmitted = false ;
934+ for (module_split::ModuleDesc &IrMD : MMs) {
935+ if (auto Dummy = makeDummy (IrMD)) {
936+ saveModule (Tables, *Dummy, ID, OutIRFileName, /* IsDummy*/ true );
937+ dummyEmitted = true ;
938+ }
939+ }
940+ if (dummyEmitted)
941+ ++ID;
896942 }
897943 return Tables;
898944}
0 commit comments