@@ -121,23 +121,51 @@ static void writeToFile(std::string Filename, std::string Content) {
121121 OS.close ();
122122}
123123
124- // Output parameter ResKernelModuleMap is a map containing groups of kernels
125- // with same values of the sycl-module-id attribute.
126- // The function fills ResKernelModuleMap using input module M.
124+ // Describes scope covered by each entry in the module-kernel map populated by
125+ // the collectKernelModuleMap function.
126+ enum KernelMapEntryScope {
127+ Scope_PerKernel, // one entry per kernel
128+ Scope_PerModule, // one entry per module
129+ Scope_Global // single entry in the map for all kernels
130+ };
131+
132+ // This function decides how kernels of the input module M will be distributed
133+ // ("split") into multiple modules based on the command options and IR
134+ // attributes. The decision is recorded in the output map parameter
135+ // ResKernelModuleMap which maps some key to a group of kernels. Each such group
136+ // along with IR it depends on (globals, functions from its call graph,...) will
137+ // constitute a separate module.
127138static void collectKernelModuleMap (
128139 Module &M, std::map<StringRef, std::vector<Function *>> &ResKernelModuleMap,
129- bool OneKernelPerModule) {
130-
131- constexpr char ATTR_SYCL_MODULE_ID[] = " sycl-module-id" ;
140+ KernelMapEntryScope EntryScope) {
132141
133142 for (auto &F : M.functions ()) {
134143 if (F.getCallingConv () == CallingConv::SPIR_KERNEL) {
135- if (OneKernelPerModule) {
144+ switch (EntryScope) {
145+ case Scope_PerKernel:
136146 ResKernelModuleMap[F.getName ()].push_back (&F);
137- } else if (F.hasFnAttribute (ATTR_SYCL_MODULE_ID)) {
147+ break ;
148+ case Scope_PerModule: {
149+ constexpr char ATTR_SYCL_MODULE_ID[] = " sycl-module-id" ;
150+
151+ // TODO It may make sense to group all kernels w/o the attribute into
152+ // a separate module rather than issuing an error. Should probably be
153+ // controlled by an option.
154+ if (!F.hasFnAttribute (ATTR_SYCL_MODULE_ID))
155+ error (" no '" + Twine (ATTR_SYCL_MODULE_ID) +
156+ " ' attribute in kernel '" + F.getName () +
157+ " ', per-module split not possible" );
138158 Attribute Id = F.getFnAttribute (ATTR_SYCL_MODULE_ID);
139159 StringRef Val = Id.getValueAsString ();
140160 ResKernelModuleMap[Val].push_back (&F);
161+ break ;
162+ }
163+ case Scope_Global:
164+ // the map key is not significant here
165+ ResKernelModuleMap[" <GLOBAL>" ].push_back (&F);
166+ break ;
167+ default :
168+ llvm_unreachable (" unknown scope" );
141169 }
142170 }
143171 }
@@ -375,8 +403,12 @@ int main(int argc, char **argv) {
375403
376404 std::map<StringRef, std::vector<Function *>> GlobalsSet;
377405
378- if (DoSplit || DoSymGen)
379- collectKernelModuleMap (*MPtr, GlobalsSet, SplitMode == SPLIT_PER_KERNEL);
406+ if (DoSplit || DoSymGen) {
407+ KernelMapEntryScope Scope = Scope_Global;
408+ if (DoSplit)
409+ Scope = SplitMode == SPLIT_PER_KERNEL ? Scope_PerKernel : Scope_PerModule;
410+ collectKernelModuleMap (*MPtr, GlobalsSet, Scope);
411+ }
380412
381413 std::vector<std::unique_ptr<Module>> ResultModules;
382414 std::vector<SpecIDMapTy> ResultSpecIDMaps;
0 commit comments