Repository: llvm/llvm-project
File: mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp (C++)

Code before:
        createDeviceFunctionCall(rewriter, func, resTy, {}, {}, {},
                                 noUnwindWillReturnAttrs, op.getOperation());
    constexpr auto noModRef = LLVM::ModRefInfo::NoModRef;
    auto memAttr = rewriter.getAttr<LLVM::MemoryEffectsAttr>(
        /*other=*/noModRef,
        /*argMem=*/noModRef, /*inaccessibleMem=*/noModRef,
        /*errnoMem=*/noModRef,
        /*targetMem0=*/noModRef,
        /*targetMem1=*/noModRef);
    call.setMemoryEffectsAttr(memAttr);
    rewriter.replaceOp(op, call);
    return success();
  }
};

static unsigned getNextGlobalIdx() {
  static unsigned globalIdx = 0;
  return globalIdx++;
}

class AllocaToGlobalPattern : public OpConversionPattern<LLVM::AllocaOp> {
  using OpConversionPattern::OpConversionPattern;
  LogicalResult
  matchAndRewrite(LLVM::AllocaOp op, LLVM::AllocaOp::Adaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto moduleOp = op->getParentOfType<ModuleOp>();
    if (!moduleOp)
      return failure();
    auto ptrType = cast<LLVM::LLVMPointerType>(op.getType());
    auto addrSpace = ptrType.getAddressSpace();
    if (addrSpace != 3)
      return failure();
    auto val = op.getArraySize();
    APInt cst;
    if (!matchPattern(val, m_ConstantInt(&cst)))
      return failure();
    auto loc = op.getLoc();
    auto globalType = LLVM::LLVMArrayType::get(
        rewriter.getContext(), op.getElemType(), cst.getZExtValue());
    auto saveIP = rewriter.saveInsertionPoint();
    rewriter.setInsertionPointToStart(moduleOp.getBody());
    auto alignment = op.getAlignment();
    auto globalVar = LLVM::GlobalOp::create(
        rewriter, loc, globalType, /*isConstant=*/false,
        /*linkage=*/LLVM::Linkage::Internal,
        /*name=*/std::string("__global_alloca_") +
            std::to_string(getNextGlobalIdx()),
        /*value=*/Attribute(),
        /*alignment=*/alignment ? *alignment : 0, /*addrSpace=*/addrSpace);
    rewriter.restoreInsertionPoint(saveIP);
    rewriter.replaceOpWithNewOp<LLVM::AddressOfOp>(op, globalVar);

Review comment (suggestion):
```suggestion
    auto moduleOp = op->getParentWithTrait<OpTrait::SymbolTable>();
```
It could also be a GPUModule, let's make it "the nearest" module.

Code after:
    auto call =
        createDeviceFunctionCall(rewriter, func, resTy, {}, {}, {},
                                 noUnwindWillReturnAttrs, op.getOperation());
    constexpr auto noModRef = LLVM::ModRefInfo::NoModRef;
    auto memAttr = rewriter.getAttr<LLVM::MemoryEffectsAttr>(
        /*other=*/noModRef,
        /*argMem=*/noModRef, /*inaccessibleMem=*/noModRef,
        /*errnoMem=*/noModRef,
        /*targetMem0=*/noModRef,
        /*targetMem1=*/noModRef);
    call.setMemoryEffectsAttr(memAttr);
    rewriter.replaceOp(op, call);
    return success();
  }
};

class AllocaToGlobalPattern : public OpConversionPattern<LLVM::AllocaOp> {
  using OpConversionPattern::OpConversionPattern;
  LogicalResult
  matchAndRewrite(LLVM::AllocaOp op, LLVM::AllocaOp::Adaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto ptrType = cast<LLVM::LLVMPointerType>(op.getType());
    auto addrSpace = ptrType.getAddressSpace();
    if (addrSpace != 3)
      return failure();
    auto symTable = op->getParentWithTrait<OpTrait::SymbolTable>();
    if (!symTable)
      return failure();
    Block *moduleBody;
    if (ModuleOp mod = dyn_cast<ModuleOp>(*symTable)) {
      moduleBody = mod.getBody();
    } else if (gpu::GPUModuleOp gpuMod =
                   dyn_cast<gpu::GPUModuleOp>(*symTable)) {
      moduleBody = gpuMod.getBody();
    } else {
      return failure();
    }
    auto val = op.getArraySize();
    APInt cst;
    if (!matchPattern(val, m_ConstantInt(&cst)))
      return failure();
    auto loc = op.getLoc();
    auto globalType = LLVM::LLVMArrayType::get(
        rewriter.getContext(), op.getElemType(), cst.getZExtValue());
    LLVM::GlobalOp globalVar;
    {
      OpBuilder::InsertionGuard guard(rewriter);
      rewriter.setInsertionPointToStart(moduleBody);
      auto alignment = op.getAlignment();
      globalVar = LLVM::GlobalOp::create(
          rewriter, loc, globalType, /*isConstant=*/false,