44
44
#include " mlir/IR/Matchers.h"
45
45
#include " mlir/Pass/Pass.h"
46
46
#include " mlir/Pass/PassManager.h"
47
+ #include " mlir/Target/LLVMIR/Import.h"
47
48
#include " mlir/Target/LLVMIR/ModuleTranslation.h"
48
49
#include " llvm/ADT/ArrayRef.h"
49
50
#include " llvm/ADT/TypeSwitch.h"
@@ -67,8 +68,41 @@ static constexpr unsigned defaultAlign = 8;
67
68
static constexpr unsigned kAttrPointer = CFI_attribute_pointer;
68
69
static constexpr unsigned kAttrAllocatable = CFI_attribute_allocatable;
69
70
70
- static inline mlir::Type getLlvmPtrType (mlir::MLIRContext *context) {
71
- return mlir::LLVM::LLVMPointerType::get (context);
71
+ static inline unsigned getAllocaAddressSpace (mlir::ModuleOp module) {
72
+ if (mlir::Attribute addrSpace =
73
+ mlir::DataLayout (module).getAllocaMemorySpace ())
74
+ return addrSpace.cast <mlir::IntegerAttr>().getUInt ();
75
+
76
+ return 0u ;
77
+ }
78
+
79
+ static inline unsigned getProgramAddressSpace (mlir::ModuleOp module) {
80
+ if (mlir::Attribute addrSpace =
81
+ mlir::DataLayout (module).getProgramMemorySpace ())
82
+ return addrSpace.cast <mlir::IntegerAttr>().getUInt ();
83
+
84
+ return 0u ;
85
+ }
86
+
87
+ static inline unsigned
88
+ getAllocaAddressSpace (mlir::ConversionPatternRewriter &rewriter) {
89
+ mlir::Operation *parentOp = rewriter.getInsertionBlock ()->getParentOp ();
90
+ return parentOp ? ::getAllocaAddressSpace (
91
+ parentOp->getParentOfType <mlir::ModuleOp>())
92
+ : 0u ;
93
+ }
94
+
95
+ static inline unsigned
96
+ getProgramAddressSpace (mlir::ConversionPatternRewriter &rewriter) {
97
+ mlir::Operation *parentOp = rewriter.getInsertionBlock ()->getParentOp ();
98
+ return parentOp ? ::getProgramAddressSpace (
99
+ parentOp->getParentOfType <mlir::ModuleOp>())
100
+ : 0u ;
101
+ }
102
+
103
+ static inline mlir::Type getLlvmPtrType (mlir::MLIRContext *context,
104
+ unsigned addressSpace = 0 ) {
105
+ return mlir::LLVM::LLVMPointerType::get (context, addressSpace);
72
106
}
73
107
74
108
static inline mlir::Type getI8Type (mlir::MLIRContext *context) {
@@ -369,7 +403,7 @@ class FIROpConversion : public mlir::ConvertOpToLLVMPattern<FromOp> {
369
403
}
370
404
371
405
// Generate an alloca of size 1 for an object of type \p llvmObjectTy.
372
- mlir::LLVM::AllocaOp
406
+ mlir::Value
373
407
genAllocaWithType (mlir::Location loc, mlir::Type llvmObjectTy,
374
408
unsigned alignment,
375
409
mlir::ConversionPatternRewriter &rewriter) const {
@@ -378,9 +412,23 @@ class FIROpConversion : public mlir::ConvertOpToLLVMPattern<FromOp> {
378
412
mlir::Block *insertBlock = getBlockForAllocaInsert (parentOp);
379
413
rewriter.setInsertionPointToStart (insertBlock);
380
414
auto size = genI32Constant (loc, rewriter, 1 );
381
- mlir::Type llvmPtrTy = ::getLlvmPtrType (llvmObjectTy.getContext ());
382
- auto al = rewriter.create <mlir::LLVM::AllocaOp>(
383
- loc, llvmPtrTy, llvmObjectTy, size, alignment);
415
+ unsigned allocaAs = getAllocaAddressSpace (rewriter);
416
+ unsigned programAs = getProgramAddressSpace (rewriter);
417
+
418
+ mlir::Value al = rewriter.create <mlir::LLVM::AllocaOp>(
419
+ loc, ::getLlvmPtrType (llvmObjectTy.getContext (), allocaAs),
420
+ llvmObjectTy, size, alignment);
421
+
422
+ // if our allocation address space, is not the same as the program address
423
+ // space, then we must emit a cast to the program address space before use.
424
+ // An example case would be on AMDGPU, where the allocation address space is
425
+ // the numeric value 5 (private), and the program address space is 0
426
+ // (generic).
427
+ if (allocaAs != programAs) {
428
+ al = rewriter.create <mlir::LLVM::AddrSpaceCastOp>(
429
+ loc, ::getLlvmPtrType (llvmObjectTy.getContext (), programAs), al);
430
+ }
431
+
384
432
rewriter.restoreInsertionPoint (thisPt);
385
433
return al;
386
434
}
@@ -532,20 +580,34 @@ struct AllocaOpConversion : public FIROpConversion<fir::AllocaOp> {
532
580
size = rewriter.create <mlir::LLVM::MulOp>(
533
581
loc, ity, size, integerCast (loc, rewriter, ity, operands[i]));
534
582
}
535
- mlir::Type llvmPtrTy = ::getLlvmPtrType (alloc.getContext ());
583
+
584
+ unsigned allocaAs = getAllocaAddressSpace (rewriter);
585
+ unsigned programAs = getProgramAddressSpace (rewriter);
586
+
536
587
// NOTE: we used to pass alloc->getAttrs() in the builder for non opaque
537
588
// pointers! Only propagate pinned and bindc_name to help debugging, but
538
589
// this should have no functional purpose (and passing the operand segment
539
590
// attribute like before is certainly bad).
540
591
auto llvmAlloc = rewriter.create <mlir::LLVM::AllocaOp>(
541
- loc, llvmPtrTy, llvmObjectType, size);
592
+ loc, ::getLlvmPtrType (alloc.getContext (), allocaAs), llvmObjectType,
593
+ size);
542
594
if (alloc.getPinned ())
543
595
llvmAlloc->setDiscardableAttr (alloc.getPinnedAttrName (),
544
596
alloc.getPinnedAttr ());
545
597
if (alloc.getBindcName ())
546
598
llvmAlloc->setDiscardableAttr (alloc.getBindcNameAttrName (),
547
599
alloc.getBindcNameAttr ());
548
- rewriter.replaceOp (alloc, llvmAlloc);
600
+ if (allocaAs == programAs) {
601
+ rewriter.replaceOp (alloc, llvmAlloc);
602
+ } else {
603
+ // if our allocation address space, is not the same as the program address
604
+ // space, then we must emit a cast to the program address space before
605
+ // use. An example case would be on AMDGPU, where the allocation address
606
+ // space is the numeric value 5 (private), and the program address space
607
+ // is 0 (generic).
608
+ rewriter.replaceOpWithNewOp <mlir::LLVM::AddrSpaceCastOp>(
609
+ alloc, ::getLlvmPtrType (alloc.getContext (), programAs), llvmAlloc);
610
+ }
549
611
return mlir::success ();
550
612
}
551
613
};
@@ -3114,7 +3176,7 @@ struct LoadOpConversion : public FIROpConversion<fir::LoadOp> {
3114
3176
auto storeOp =
3115
3177
rewriter.create <mlir::LLVM::StoreOp>(loc, boxValue, newBoxStorage);
3116
3178
attachTBAATag (storeOp, boxTy, boxTy, nullptr );
3117
- rewriter.replaceOp (load, newBoxStorage. getResult () );
3179
+ rewriter.replaceOp (load, newBoxStorage);
3118
3180
} else {
3119
3181
auto loadOp = rewriter.create <mlir::LLVM::LoadOp>(
3120
3182
load.getLoc (), llvmLoadTy, adaptor.getOperands (), load->getAttrs ());
@@ -3808,6 +3870,17 @@ class FIRToLLVMLowering
3808
3870
if (!forcedTargetTriple.empty ())
3809
3871
fir::setTargetTriple (mod, forcedTargetTriple);
3810
3872
3873
+ if (!forcedDataLayout.empty ()) {
3874
+ llvm::DataLayout dl (forcedDataLayout);
3875
+ mlir::MLIRContext *context = mod.getContext ();
3876
+ mod->setAttr (
3877
+ mlir::LLVM::LLVMDialect::getDataLayoutAttrName (),
3878
+ mlir::StringAttr::get (context, dl.getStringRepresentation ()));
3879
+ mlir::DataLayoutSpecInterface dlSpec =
3880
+ mlir::translateDataLayout (dl, context);
3881
+ mod->setAttr (mlir::DLTIDialect::kDataLayoutAttrName , dlSpec);
3882
+ }
3883
+
3811
3884
// Run dynamic pass pipeline for converting Math dialect
3812
3885
// operations into other dialects (llvm, func, etc.).
3813
3886
// Some conversions of Math operations cannot be done
0 commit comments