2323#include " flang/Optimizer/Support/InternalNames.h"
2424#include " flang/Optimizer/Support/TypeCode.h"
2525#include " flang/Optimizer/Support/Utils.h"
26+ #include " flang/Runtime/CUDA/descriptor.h"
2627#include " flang/Runtime/allocator-registry-consts.h"
2728#include " flang/Runtime/descriptor-consts.h"
2829#include " flang/Semantics/runtime-type-info.h"
@@ -2970,6 +2971,93 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
29702971 }
29712972};
29722973
2974+ static mlir::Value genSourceFile (mlir::Location loc, mlir::ModuleOp mod,
2975+ mlir::ConversionPatternRewriter &rewriter) {
2976+ auto ptrTy = mlir::LLVM::LLVMPointerType::get (rewriter.getContext ());
2977+ if (auto flc = mlir::dyn_cast<mlir::FileLineColLoc>(loc)) {
2978+ auto fn = flc.getFilename ().str () + ' \0 ' ;
2979+ std::string globalName = fir::factory::uniqueCGIdent (" cl" , fn);
2980+
2981+ if (auto g = mod.lookupSymbol <fir::GlobalOp>(globalName)) {
2982+ return rewriter.create <mlir::LLVM::AddressOfOp>(loc, ptrTy, g.getName ());
2983+ } else if (auto g = mod.lookupSymbol <mlir::LLVM::GlobalOp>(globalName)) {
2984+ return rewriter.create <mlir::LLVM::AddressOfOp>(loc, ptrTy, g.getName ());
2985+ }
2986+
2987+ auto crtInsPt = rewriter.saveInsertionPoint ();
2988+ rewriter.setInsertionPoint (mod.getBody (), mod.getBody ()->end ());
2989+ auto arrayTy = mlir::LLVM::LLVMArrayType::get (
2990+ mlir::IntegerType::get (rewriter.getContext (), 8 ), fn.size ());
2991+ mlir::LLVM::GlobalOp globalOp = rewriter.create <mlir::LLVM::GlobalOp>(
2992+ loc, arrayTy, /* constant=*/ true , mlir::LLVM::Linkage::Linkonce,
2993+ globalName, mlir::Attribute ());
2994+
2995+ mlir::Region ®ion = globalOp.getInitializerRegion ();
2996+ mlir::Block *block = rewriter.createBlock (®ion);
2997+ rewriter.setInsertionPoint (block, block->begin ());
2998+ mlir::Value constValue = rewriter.create <mlir::LLVM::ConstantOp>(
2999+ loc, arrayTy, rewriter.getStringAttr (fn));
3000+ rewriter.create <mlir::LLVM::ReturnOp>(loc, constValue);
3001+ rewriter.restoreInsertionPoint (crtInsPt);
3002+ return rewriter.create <mlir::LLVM::AddressOfOp>(loc, ptrTy,
3003+ globalOp.getName ());
3004+ }
3005+ return rewriter.create <mlir::LLVM::ZeroOp>(loc, ptrTy);
3006+ }
3007+
3008+ static mlir::Value genSourceLine (mlir::Location loc,
3009+ mlir::ConversionPatternRewriter &rewriter) {
3010+ if (auto flc = mlir::dyn_cast<mlir::FileLineColLoc>(loc))
3011+ return rewriter.create <mlir::LLVM::ConstantOp>(loc, rewriter.getI32Type (),
3012+ flc.getLine ());
3013+ return rewriter.create <mlir::LLVM::ConstantOp>(loc, rewriter.getI32Type (), 0 );
3014+ }
3015+
3016+ static mlir::Value
3017+ genCUFAllocDescriptor (mlir::Location loc,
3018+ mlir::ConversionPatternRewriter &rewriter,
3019+ mlir::ModuleOp mod, fir::BaseBoxType boxTy,
3020+ const fir::LLVMTypeConverter &typeConverter) {
3021+ std::optional<mlir::DataLayout> dl =
3022+ fir::support::getOrSetDataLayout (mod, /* allowDefaultLayout=*/ true );
3023+ if (!dl)
3024+ mlir::emitError (mod.getLoc (),
3025+ " module operation must carry a data layout attribute "
3026+ " to generate llvm IR from FIR" );
3027+
3028+ mlir::Value sourceFile = genSourceFile (loc, mod, rewriter);
3029+ mlir::Value sourceLine = genSourceLine (loc, rewriter);
3030+
3031+ mlir::MLIRContext *ctx = mod.getContext ();
3032+
3033+ mlir::LLVM::LLVMPointerType llvmPointerType =
3034+ mlir::LLVM::LLVMPointerType::get (ctx);
3035+ mlir::Type llvmInt32Type = mlir::IntegerType::get (ctx, 32 );
3036+ mlir::Type llvmIntPtrType =
3037+ mlir::IntegerType::get (ctx, typeConverter.getPointerBitwidth (0 ));
3038+ auto fctTy = mlir::LLVM::LLVMFunctionType::get (
3039+ llvmPointerType, {llvmIntPtrType, llvmPointerType, llvmInt32Type});
3040+
3041+ auto llvmFunc = mod.lookupSymbol <mlir::LLVM::LLVMFuncOp>(
3042+ RTNAME_STRING (CUFAllocDesciptor));
3043+ auto funcFunc =
3044+ mod.lookupSymbol <mlir::func::FuncOp>(RTNAME_STRING (CUFAllocDesciptor));
3045+ if (!llvmFunc && !funcFunc)
3046+ mlir::OpBuilder::atBlockEnd (mod.getBody ())
3047+ .create <mlir::LLVM::LLVMFuncOp>(loc, RTNAME_STRING (CUFAllocDesciptor),
3048+ fctTy);
3049+
3050+ mlir::Type structTy = typeConverter.convertBoxTypeAsStruct (boxTy);
3051+ std::size_t boxSize = dl->getTypeSizeInBits (structTy) / 8 ;
3052+ mlir::Value sizeInBytes =
3053+ genConstantIndex (loc, llvmIntPtrType, rewriter, boxSize);
3054+ llvm::SmallVector args = {sizeInBytes, sourceFile, sourceLine};
3055+ return rewriter
3056+ .create <mlir::LLVM::CallOp>(loc, fctTy, RTNAME_STRING (CUFAllocDesciptor),
3057+ args)
3058+ .getResult ();
3059+ }
3060+
29733061// / `fir.load` --> `llvm.load`
29743062struct LoadOpConversion : public fir ::FIROpConversion<fir::LoadOp> {
29753063 using FIROpConversion::FIROpConversion;
@@ -2986,9 +3074,23 @@ struct LoadOpConversion : public fir::FIROpConversion<fir::LoadOp> {
29863074 // loading a fir.ref<fir.box> is implemented as taking a snapshot of the
29873075 // descriptor value into a new descriptor temp.
29883076 auto inputBoxStorage = adaptor.getOperands ()[0 ];
3077+ mlir::Value newBoxStorage;
29893078 mlir::Location loc = load.getLoc ();
2990- auto newBoxStorage =
2991- genAllocaAndAddrCastWithType (loc, llvmLoadTy, defaultAlign, rewriter);
3079+ if (auto callOp = mlir::dyn_cast_or_null<mlir::LLVM::CallOp>(
3080+ inputBoxStorage.getDefiningOp ())) {
3081+ if (callOp.getCallee () &&
3082+ (*callOp.getCallee ())
3083+ .starts_with (RTNAME_STRING (CUFAllocDesciptor))) {
3084+ // CUDA Fortran local descriptor are allocated in managed memory. So
3085+ // new storage must be allocated the same way.
3086+ auto mod = load->getParentOfType <mlir::ModuleOp>();
3087+ newBoxStorage =
3088+ genCUFAllocDescriptor (loc, rewriter, mod, boxTy, lowerTy ());
3089+ }
3090+ }
3091+ if (!newBoxStorage)
3092+ newBoxStorage = genAllocaAndAddrCastWithType (loc, llvmLoadTy,
3093+ defaultAlign, rewriter);
29923094
29933095 TypePair boxTypePair{boxTy, llvmLoadTy};
29943096 mlir::Value boxSize =
0 commit comments