@@ -421,6 +421,42 @@ void SPIRVRegularizeLLVMBase::cleanupConversionToNonStdIntegers(Module *M) {
421421 }
422422}
423423
424+ void SPIRVRegularizeLLVMBase::replacePrivateConstGlobalsWithAllocas (Module *M) {
425+ SmallVector<GlobalVariable *> GlobalsToRemove;
426+ for (auto &GV : M->globals ()) {
427+
428+ if (!GV.isConstant () || !GV.hasInternalLinkage () ||
429+ !(GV.getAddressSpace () == SPIRAS_Private) || !GV.hasInitializer () ||
430+ GV.getName ().starts_with (" llvm.compiler.used" ) ||
431+ GV.getName ().starts_with (" llvm.used" ))
432+ continue ;
433+
434+ SmallVector<User *> Users (GV.users ());
435+ // TODO: Handle other llvm::User types, for example, constant expressions.
436+ if (llvm::any_of (Users, [](User *U) { return !isa<Instruction>(U); }))
437+ continue ;
438+
439+ DenseMap<Function *, AllocaInst *> LocalCopies;
440+ for (User *U : Users) {
441+ Instruction *Inst = cast<Instruction>(U);
442+ Function *F = Inst->getFunction ();
443+ AllocaInst *&AI = LocalCopies[F];
444+ if (!AI) {
445+ IRBuilder<> Builder (&*F->getEntryBlock ().getFirstInsertionPt ());
446+ AI = Builder.CreateAlloca (GV.getValueType (), nullptr , GV.getName ());
447+ if (GV.getAlign ())
448+ AI->setAlignment (GV.getAlign ().value ());
449+ Builder.CreateStore (GV.getInitializer (), AI);
450+ }
451+ Inst->replaceUsesOfWith (&GV, AI);
452+ }
453+ GlobalsToRemove.push_back (&GV);
454+ }
455+
456+ for (GlobalVariable *GV : GlobalsToRemove)
457+ GV->eraseFromParent ();
458+ }
459+
424460bool SPIRVRegularizeLLVMBase::runRegularizeLLVM (Module &Module) {
425461 M = &Module;
426462 Ctx = &M->getContext ();
@@ -582,6 +618,7 @@ bool SPIRVRegularizeLLVMBase::regularize() {
582618 addKernelEntryPoint (M);
583619 expandSYCLTypeUsing (M);
584620 cleanupConversionToNonStdIntegers (M);
621+ replacePrivateConstGlobalsWithAllocas (M);
585622
586623 // Kernels called by other kernels
587624 std::vector<Function *> CalledKernels;
0 commit comments