Skip to content

Commit a5f2937

Browse files
authored
[sycl-post-link][NFC] Another portion of small refactorings (#4807)
* Removed unused variable and unnecessary members of ImagePropSaveInfo struct * Several logical parts of functions are moved in a separate functions * Several variable definitions moved closer to their use * Aliasing is used to reduce variable names Signed-off-by: Mikhail Lychkov <[email protected]>
1 parent 0cece3a commit a5f2937

File tree

1 file changed

+115
-106
lines changed

1 file changed

+115
-106
lines changed

llvm/tools/sycl-post-link/sycl-post-link.cpp

Lines changed: 115 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
using namespace llvm;
5252

5353
using string_vector = std::vector<std::string>;
54+
using PropSetRegTy = llvm::util::PropertySetRegistry;
5455

5556
namespace {
5657

@@ -183,8 +184,6 @@ cl::opt<bool> EmitOnlyKernelsAsEntryPoints{
183184
cl::cat(PostLinkCat), cl::init(false)};
184185

185186
struct ImagePropSaveInfo {
186-
bool NeedDeviceLibReqMask;
187-
bool DoSpecConst;
188187
bool SetSpecConstAtRT;
189188
bool SpecConstsMet;
190189
bool EmitKernelParamInfo;
@@ -219,20 +218,13 @@ enum KernelMapEntryScope {
219218
Scope_Global // single entry in the map for all kernels
220219
};
221220

222-
KernelMapEntryScope selectDeviceCodeSplitScopeAutomatically(const Module &M) {
223-
if (IROutputOnly) {
224-
// We allow enabling auto split mode even in presence of -ir-output-only
225-
// flag, but in this case we are limited by it so we can't do any split at
226-
// all.
227-
return Scope_Global;
228-
}
229-
221+
bool hasIndirectFunctionCalls(const Module &M) {
230222
for (const auto &F : M.functions()) {
231223
// There are functions marked with [[intel::device_indirectly_callable]]
232224
// attribute, because it instructs us to make this function available to the
233225
// whole program as it was compiled as a single module.
234226
if (F.hasFnAttribute("referenced-indirectly"))
235-
return Scope_Global;
227+
return true;
236228
if (F.isDeclaration())
237229
continue;
238230
// There are indirect calls in the module, which means that we don't know
@@ -241,18 +233,47 @@ KernelMapEntryScope selectDeviceCodeSplitScopeAutomatically(const Module &M) {
241233
for (const auto &I : instructions(F)) {
242234
if (auto *CI = dyn_cast<CallInst>(&I))
243235
if (!CI->getCalledFunction())
244-
return Scope_Global;
236+
return true;
245237
}
246238

247239
// Function pointer is used somewhere. Follow the same rule as above.
248240
for (const auto *U : F.users())
249241
if (!isa<CallInst>(U))
250-
return Scope_Global;
242+
return true;
251243
}
252244

253-
// At the moment, we assume that per-source split is the best way of splitting
254-
// device code and can always be used execpt for cases handled above.
255-
return Scope_PerModule;
245+
return false;
246+
}
247+
248+
KernelMapEntryScope selectDeviceCodeSplitScope(const Module &M) {
249+
bool DoSplit = SplitMode.getNumOccurrences() > 0;
250+
if (DoSplit) {
251+
switch (SplitMode) {
252+
case SPLIT_PER_TU:
253+
return Scope_PerModule;
254+
255+
case SPLIT_PER_KERNEL:
256+
return Scope_PerKernel;
257+
258+
case SPLIT_AUTO: {
259+
if (IROutputOnly) {
260+
// We allow enabling auto split mode even in presence of -ir-output-only
261+
// flag, but in this case we are limited by it so we can't do any split
262+
// at all.
263+
return Scope_Global;
264+
}
265+
266+
if (hasIndirectFunctionCalls(M))
267+
return Scope_Global;
268+
269+
// At the moment, we assume that per-source split is the best way of
270+
// splitting device code and can always be used except for cases handled
271+
// above.
272+
return Scope_PerModule;
273+
}
274+
}
275+
}
276+
return Scope_Global;
256277
}
257278

258279
// Return true if the function is a SPIRV or SYCL builtin, e.g.
@@ -411,6 +432,41 @@ HasAssertStatus hasAssertInFunctionCallGraph(const Function *Func) {
411432
return No_Assert;
412433
}
413434

435+
std::vector<StringRef> getKernelNamesUsingAssert(const Module &M) {
436+
std::vector<StringRef> Result;
437+
438+
bool HasIndirectlyCalledAssert = false;
439+
std::vector<const Function *> Kernels;
440+
for (const auto &F : M.functions()) {
441+
// TODO: handle SYCL_EXTERNAL functions for dynamic linkage.
442+
// TODO: handle function pointers.
443+
if (F.getCallingConv() != CallingConv::SPIR_KERNEL)
444+
continue;
445+
446+
Kernels.push_back(&F);
447+
if (HasIndirectlyCalledAssert)
448+
continue;
449+
450+
HasAssertStatus HasAssert = hasAssertInFunctionCallGraph(&F);
451+
switch (HasAssert) {
452+
case Assert:
453+
Result.push_back(F.getName());
454+
break;
455+
case Assert_Indirect:
456+
HasIndirectlyCalledAssert = true;
457+
break;
458+
case No_Assert:
459+
break;
460+
}
461+
}
462+
463+
if (HasIndirectlyCalledAssert)
464+
for (const auto *F : Kernels)
465+
Result.push_back(F->getName());
466+
467+
return Result;
468+
}
469+
414470
// Gets reqd_work_group_size information for function Func.
415471
std::vector<uint32_t> getKernelReqdWorkGroupSizeMetadata(const Function &Func) {
416472
auto ReqdWorkGroupSizeMD = Func.getMetadata("reqd_work_group_size");
@@ -545,7 +601,6 @@ string_vector saveResultModules(const std::vector<ResultModule> &ResModules,
545601
string_vector Res;
546602

547603
for (size_t I = 0; I < ResModules.size(); ++I) {
548-
std::error_code EC;
549604
StringRef FileExt = (OutputAssembly) ? ".ll" : ".bc";
550605
std::string CurOutFileName = makeResultFileName(FileExt, I, Suffix);
551606
saveModule(*ResModules[I].ModulePtr, CurOutFileName);
@@ -560,40 +615,36 @@ string_vector saveDeviceImageProperty(
560615
const ImagePropSaveInfo &ImgPSInfo) {
561616
string_vector Res;
562617
legacy::PassManager GetSYCLDeviceLibReqMask;
563-
SYCLDeviceLibReqMaskPass *SDLReqMaskLegacyPass =
564-
new SYCLDeviceLibReqMaskPass();
618+
auto *SDLReqMaskLegacyPass = new SYCLDeviceLibReqMaskPass();
565619
GetSYCLDeviceLibReqMask.add(SDLReqMaskLegacyPass);
566620
for (size_t I = 0; I < ResultModules.size(); ++I) {
567-
llvm::util::PropertySetRegistry PropSet;
568-
if (ImgPSInfo.NeedDeviceLibReqMask) {
569-
GetSYCLDeviceLibReqMask.run(*ResultModules[I].ModulePtr);
621+
Module &M = *ResultModules[I].ModulePtr;
622+
PropSetRegTy PropSet;
623+
624+
{
625+
GetSYCLDeviceLibReqMask.run(M);
570626
uint32_t MRMask = SDLReqMaskLegacyPass->getSYCLDeviceLibReqMask();
571627
std::map<StringRef, uint32_t> RMEntry = {{"DeviceLibReqMask", MRMask}};
572-
PropSet.add(llvm::util::PropertySetRegistry::SYCL_DEVICELIB_REQ_MASK,
573-
RMEntry);
628+
PropSet.add(PropSetRegTy::SYCL_DEVICELIB_REQ_MASK, RMEntry);
574629
}
575-
if (ImgPSInfo.DoSpecConst) {
576-
if (ImgPSInfo.SpecConstsMet) {
577-
// extract spec constant maps per each module
578-
SpecIDMapTy TmpSpecIDMap;
579-
SpecConstantsPass::collectSpecConstantMetadata(
580-
*ResultModules[I].ModulePtr, TmpSpecIDMap);
581-
PropSet.add(
582-
llvm::util::PropertySetRegistry::SYCL_SPECIALIZATION_CONSTANTS,
583-
TmpSpecIDMap);
584-
585-
// Add property with the default values of spec constants only in native
586-
// (default) mode.
587-
if (!ImgPSInfo.SetSpecConstAtRT) {
588-
std::vector<char> DefaultValues;
589-
SpecConstantsPass::collectSpecConstantDefaultValuesMetadata(
590-
*ResultModules[I].ModulePtr, DefaultValues);
591-
PropSet.add(llvm::util::PropertySetRegistry::
592-
SYCL_SPEC_CONSTANTS_DEFAULT_VALUES,
593-
"all", DefaultValues);
594-
}
630+
631+
if (ImgPSInfo.SpecConstsMet) {
632+
// extract spec constant maps per each module
633+
SpecIDMapTy TmpSpecIDMap;
634+
SpecConstantsPass::collectSpecConstantMetadata(M, TmpSpecIDMap);
635+
PropSet.add(PropSetRegTy::SYCL_SPECIALIZATION_CONSTANTS, TmpSpecIDMap);
636+
637+
// Add property with the default values of spec constants only in native
638+
// (default) mode.
639+
if (!ImgPSInfo.SetSpecConstAtRT) {
640+
std::vector<char> DefaultValues;
641+
SpecConstantsPass::collectSpecConstantDefaultValuesMetadata(
642+
M, DefaultValues);
643+
PropSet.add(PropSetRegTy::SYCL_SPEC_CONSTANTS_DEFAULT_VALUES, "all",
644+
DefaultValues);
595645
}
596646
}
647+
597648
if (ImgPSInfo.EmitKernelParamInfo) {
598649
// extract kernel parameter optimization info per module
599650
ModuleAnalysisManager MAM;
@@ -603,12 +654,11 @@ string_vector saveDeviceImageProperty(
603654

604655
MAM.registerPass([&] { return SYCLKernelParamOptInfoAnalysis(); });
605656
SYCLKernelParamOptInfo PInfo =
606-
MAM.getResult<SYCLKernelParamOptInfoAnalysis>(
607-
*ResultModules[I].ModulePtr);
657+
MAM.getResult<SYCLKernelParamOptInfoAnalysis>(M);
608658

609659
// convert analysis results into properties and record them
610660
llvm::util::PropertySet &Props =
611-
PropSet[llvm::util::PropertySetRegistry::SYCL_KERNEL_PARAM_OPT_INFO];
661+
PropSet[PropSetRegTy::SYCL_KERNEL_PARAM_OPT_INFO];
612662

613663
for (const auto &NameInfoPair : PInfo) {
614664
const llvm::BitVector &Bits = NameInfoPair.second;
@@ -623,15 +673,16 @@ string_vector saveDeviceImageProperty(
623673
NameInfoPair.first, llvm::util::PropertyValue(Data, DataBitSize)));
624674
}
625675
}
676+
626677
if (ImgPSInfo.EmitExportedSymbols) {
627678
// For each result module, extract the exported functions
628679
auto ModuleFunctionsIt =
629680
KernelModuleMap.find(ResultModules[I].KernelModuleName);
630681
if (ModuleFunctionsIt != KernelModuleMap.end()) {
631682
for (const auto &F : ModuleFunctionsIt->second) {
632683
if (F->getCallingConv() == CallingConv::SPIR_FUNC) {
633-
PropSet[llvm::util::PropertySetRegistry::SYCL_EXPORTED_SYMBOLS]
634-
.insert({F->getName(), true});
684+
PropSet[PropSetRegTy::SYCL_EXPORTED_SYMBOLS].insert(
685+
{F->getName(), true});
635686
}
636687
}
637688
}
@@ -641,11 +692,10 @@ string_vector saveDeviceImageProperty(
641692
// properties have been written.
642693
SmallVector<std::string, 4> MetadataNames;
643694
if (ImgPSInfo.EmitProgramMetadata) {
644-
auto &ProgramMetadata =
645-
PropSet[llvm::util::PropertySetRegistry::SYCL_PROGRAM_METADATA];
695+
auto &ProgramMetadata = PropSet[PropSetRegTy::SYCL_PROGRAM_METADATA];
646696

647697
// Add reqd_work_group_size information to program metadata
648-
for (const Function &Func : ResultModules[I].ModulePtr->functions()) {
698+
for (const Function &Func : M.functions()) {
649699
std::vector<uint32_t> KernelReqdWorkGroupSize =
650700
getKernelReqdWorkGroupSizeMetadata(Func);
651701
if (KernelReqdWorkGroupSize.empty())
@@ -655,44 +705,13 @@ string_vector saveDeviceImageProperty(
655705
}
656706
}
657707

658-
if (ImgPSInfo.IsEsimdKernel) {
659-
PropSet[llvm::util::PropertySetRegistry::SYCL_MISC_PROP].insert(
660-
{"isEsimdImage", true});
661-
}
708+
if (ImgPSInfo.IsEsimdKernel)
709+
PropSet[PropSetRegTy::SYCL_MISC_PROP].insert({"isEsimdImage", true});
662710

663711
{
664-
Module *M = ResultModules[I].ModulePtr.get();
665-
bool HasIndirectlyCalledAssert = false;
666-
std::vector<const Function *> Kernels;
667-
for (const auto &F : M->functions()) {
668-
// TODO: handle SYCL_EXTERNAL functions for dynamic linkage.
669-
// TODO: handle function pointers.
670-
if (F.getCallingConv() != CallingConv::SPIR_KERNEL)
671-
continue;
672-
673-
Kernels.push_back(&F);
674-
if (HasIndirectlyCalledAssert)
675-
continue;
676-
677-
HasAssertStatus HasAssert = hasAssertInFunctionCallGraph(&F);
678-
switch (HasAssert) {
679-
case Assert:
680-
PropSet[llvm::util::PropertySetRegistry::SYCL_ASSERT_USED].insert(
681-
{F.getName(), true});
682-
break;
683-
case Assert_Indirect:
684-
HasIndirectlyCalledAssert = true;
685-
break;
686-
case No_Assert:
687-
break;
688-
}
689-
}
690-
691-
if (HasIndirectlyCalledAssert) {
692-
for (const auto *F : Kernels)
693-
PropSet[llvm::util::PropertySetRegistry::SYCL_ASSERT_USED].insert(
694-
{F->getName(), true});
695-
}
712+
std::vector<StringRef> FuncNames = getKernelNamesUsingAssert(M);
713+
for (const StringRef &FName : FuncNames)
714+
PropSet[PropSetRegTy::SYCL_ASSERT_USED].insert({FName, true});
696715
}
697716

698717
std::error_code EC;
@@ -786,23 +805,15 @@ TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
786805
std::map<StringRef, std::vector<const Function *>> GlobalsSet;
787806

788807
bool DoSplit = SplitMode.getNumOccurrences() > 0;
789-
bool DoSpecConst = SpecConstLower.getNumOccurrences() > 0;
790808

791809
if (DoSplit || DoSymGen) {
792-
KernelMapEntryScope Scope = Scope_Global;
793-
if (DoSplit) {
794-
if (SplitMode == SPLIT_AUTO)
795-
Scope = selectDeviceCodeSplitScopeAutomatically(*M);
796-
else
797-
Scope =
798-
SplitMode == SPLIT_PER_KERNEL ? Scope_PerKernel : Scope_PerModule;
799-
}
810+
KernelMapEntryScope Scope = selectDeviceCodeSplitScope(*M);
800811
collectEntryPointToModuleMap(*M, GlobalsSet, Scope);
801812
}
802813

803814
std::vector<ResultModule> ResultModules;
804-
string_vector ResultSymbolsLists;
805815

816+
bool DoSpecConst = SpecConstLower.getNumOccurrences() > 0;
806817
bool SpecConstsMet = false;
807818
bool SetSpecConstAtRT = DoSpecConst && (SpecConstLower == SC_USE_RT_VAL);
808819

@@ -852,21 +863,18 @@ TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
852863
}
853864

854865
{
855-
ImagePropSaveInfo ImgPSInfo = {true,
856-
DoSpecConst,
857-
SetSpecConstAtRT,
858-
SpecConstsMet,
859-
EmitKernelParamInfo,
860-
EmitProgramMetadata,
861-
EmitExportedSymbols,
862-
IsEsimd};
866+
ImagePropSaveInfo ImgPSInfo = {SetSpecConstAtRT, SpecConstsMet,
867+
EmitKernelParamInfo, EmitProgramMetadata,
868+
EmitExportedSymbols, IsEsimd};
863869
string_vector Files =
864870
saveDeviceImageProperty(ResultModules, GlobalsSet, ImgPSInfo);
865871
std::copy(Files.begin(), Files.end(),
866872
std::back_inserter(TblFiles[COL_PROPS]));
867873
}
874+
868875
if (DoSymGen) {
869876
// extract symbols per each module
877+
string_vector ResultSymbolsLists;
870878
collectSymbolsLists(GlobalsSet, ResultSymbolsLists);
871879
if (ResultSymbolsLists.empty()) {
872880
// push empty symbols list for consistency
@@ -878,6 +886,7 @@ TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
878886
std::copy(Files.begin(), Files.end(),
879887
std::back_inserter(TblFiles[COL_SYM]));
880888
}
889+
881890
return TblFiles;
882891
}
883892

0 commit comments

Comments
 (0)