23
23
#include " flang/Optimizer/Support/InternalNames.h"
24
24
#include " flang/Optimizer/Support/TypeCode.h"
25
25
#include " flang/Optimizer/Support/Utils.h"
26
+ #include " flang/Runtime/CUDA/descriptor.h"
26
27
#include " flang/Runtime/allocator-registry-consts.h"
27
28
#include " flang/Runtime/descriptor-consts.h"
28
29
#include " flang/Semantics/runtime-type-info.h"
@@ -2970,6 +2971,93 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
2970
2971
}
2971
2972
};
2972
2973
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
+
2973
3061
// / `fir.load` --> `llvm.load`
2974
3062
struct LoadOpConversion : public fir ::FIROpConversion<fir::LoadOp> {
2975
3063
using FIROpConversion::FIROpConversion;
@@ -2986,9 +3074,23 @@ struct LoadOpConversion : public fir::FIROpConversion<fir::LoadOp> {
2986
3074
// loading a fir.ref<fir.box> is implemented as taking a snapshot of the
2987
3075
// descriptor value into a new descriptor temp.
2988
3076
auto inputBoxStorage = adaptor.getOperands ()[0 ];
3077
+ mlir::Value newBoxStorage;
2989
3078
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);
2992
3094
2993
3095
TypePair boxTypePair{boxTy, llvmLoadTy};
2994
3096
mlir::Value boxSize =
0 commit comments