Skip to content

Commit 50ea17b

Browse files
committed
[mlir][MemRef] Add option to -finalize-memref-to-llvm to emit opaque pointers
This is the first patch in a series of patches part of this RFC: https://discourse.llvm.org/t/rfc-switching-the-llvm-dialect-and-dialect-lowerings-to-opaque-pointers/68179 This patch adds the ability to lower the memref dialect to the LLVM Dialect with the use of opaque pointers instead of typed pointers. The latter are being phased out of LLVM and this patch is part of an effort to phase them out of MLIR as well. To do this, we'll need to support both typed and opaque pointers in lowering passes, to allow downstream projects to change without breakage. The gist of changes required to change a conversion pass are: * Change any `LLVM::LLVMPointerType::get` calls to NOT use an element type if opaque pointers are to be used. * Use the `build` method of `llvm.load` with the explicit result type. Since the pointer does not have an element type anymore it has to be specified explicitly. * Use the `build` method of `llvm.getelementptr` with the explicit `basePtrType`. Ditto to above, we have to now specify what the element type is so that GEP can do its indexing calculations * Use the `build` method of `llvm.alloca` with the explicit `elementType`. Ditto to the above, alloca needs to know how many bytes to allocate through the element type. * Get rid of any `llvm.bitcast`s * Adapt the tests to the above. Note that `llvm.store` changes syntax as well when using opaque pointers I'd like to note that the 3 `build` method changes work for both opaque and typed pointers, so unconditionally using the explicit element type form is always correct. For the testsuite a practical approach suggested by @ftynse was taken: I created a separate test file for testing the typed pointer lowering of Ops. This mostly comes down to checking that bitcasts have been created at the appropiate places, since these are required for typed pointer support. Differential Revision: https://reviews.llvm.org/D143268
1 parent 3ecaf27 commit 50ea17b

20 files changed

+1446
-975
lines changed

mlir/include/mlir/Conversion/LLVMCommon/LoweringOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class LowerToLLVMOptions {
3333
LowerToLLVMOptions(MLIRContext *ctx, const DataLayout &dl);
3434

3535
bool useBarePtrCallConv = false;
36+
bool useOpaquePointers = false;
3637

3738
enum class AllocLowering {
3839
/// Use malloc for for heap allocations.

mlir/include/mlir/Conversion/LLVMCommon/MemRefBuilder.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ class MemRefDescriptor : public StructBuilder {
111111
static unsigned getNumUnpackedValues(MemRefType type);
112112

113113
private:
114+
bool useOpaquePointers();
115+
114116
// Cached index type.
115117
Type indexType;
116118
};
@@ -194,36 +196,39 @@ class UnrankedMemRefDescriptor : public StructBuilder {
194196

195197
/// Builds IR extracting the allocated pointer from the descriptor.
196198
static Value allocatedPtr(OpBuilder &builder, Location loc,
197-
Value memRefDescPtr, Type elemPtrPtrType);
199+
Value memRefDescPtr,
200+
LLVM::LLVMPointerType elemPtrType);
198201
/// Builds IR inserting the allocated pointer into the descriptor.
199202
static void setAllocatedPtr(OpBuilder &builder, Location loc,
200-
Value memRefDescPtr, Type elemPtrPtrType,
203+
Value memRefDescPtr,
204+
LLVM::LLVMPointerType elemPtrType,
201205
Value allocatedPtr);
202206

203207
/// Builds IR extracting the aligned pointer from the descriptor.
204208
static Value alignedPtr(OpBuilder &builder, Location loc,
205209
LLVMTypeConverter &typeConverter, Value memRefDescPtr,
206-
Type elemPtrPtrType);
210+
LLVM::LLVMPointerType elemPtrType);
207211
/// Builds IR inserting the aligned pointer into the descriptor.
208212
static void setAlignedPtr(OpBuilder &builder, Location loc,
209213
LLVMTypeConverter &typeConverter,
210-
Value memRefDescPtr, Type elemPtrPtrType,
214+
Value memRefDescPtr,
215+
LLVM::LLVMPointerType elemPtrType,
211216
Value alignedPtr);
212217

213218
/// Builds IR extracting the offset from the descriptor.
214219
static Value offset(OpBuilder &builder, Location loc,
215220
LLVMTypeConverter &typeConverter, Value memRefDescPtr,
216-
Type elemPtrPtrType);
221+
LLVM::LLVMPointerType elemPtrType);
217222
/// Builds IR inserting the offset into the descriptor.
218223
static void setOffset(OpBuilder &builder, Location loc,
219224
LLVMTypeConverter &typeConverter, Value memRefDescPtr,
220-
Type elemPtrPtrType, Value offset);
225+
LLVM::LLVMPointerType elemPtrType, Value offset);
221226

222227
/// Builds IR extracting the pointer to the first element of the size array.
223228
static Value sizeBasePtr(OpBuilder &builder, Location loc,
224229
LLVMTypeConverter &typeConverter,
225230
Value memRefDescPtr,
226-
LLVM::LLVMPointerType elemPtrPtrType);
231+
LLVM::LLVMPointerType elemPtrType);
227232
/// Builds IR extracting the size[index] from the descriptor.
228233
static Value size(OpBuilder &builder, Location loc,
229234
LLVMTypeConverter &typeConverter, Value sizeBasePtr,

mlir/include/mlir/Conversion/LLVMCommon/TypeConverter.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class LowerToLLVMOptions;
2424

2525
namespace LLVM {
2626
class LLVMDialect;
27+
class LLVMPointerType;
2728
} // namespace LLVM
2829

2930
/// Conversion from types to the LLVM IR dialect.
@@ -119,6 +120,17 @@ class LLVMTypeConverter : public TypeConverter {
119120
/// integer type with the size configured for this type converter.
120121
Type getIndexType();
121122

123+
/// Returns true if using opaque pointers was enabled in the lowering options.
124+
bool useOpaquePointers() const { return getOptions().useOpaquePointers; }
125+
126+
/// Creates an LLVM pointer type with the given element type and address
127+
/// space.
128+
/// This function is meant to be used in code supporting both typed and opaque
129+
/// pointers, as it will create an opaque pointer with the given address space
130+
/// if opaque pointers are enabled in the lowering options.
131+
LLVM::LLVMPointerType getPointerType(Type elementType,
132+
unsigned addressSpace = 0);
133+
122134
/// Gets the bitwidth of the index type when converted to LLVM.
123135
unsigned getIndexTypeBitwidth() { return options.getIndexBitwidth(); }
124136

mlir/include/mlir/Conversion/Passes.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,10 @@ def FinalizeMemRefToLLVMConversionPass :
582582
"bool",
583583
/*default=*/"false",
584584
"Use generic allocation and deallocation functions instead of the "
585-
"classic 'malloc', 'aligned_alloc' and 'free' functions">
585+
"classic 'malloc', 'aligned_alloc' and 'free' functions">,
586+
Option<"useOpaquePointers", "use-opaque-pointers", "bool",
587+
/*default=*/"false", "Generate LLVM IR using opaque pointers "
588+
"instead of typed pointers">
586589
];
587590
}
588591

mlir/include/mlir/Dialect/LLVMIR/FunctionCallUtils.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,24 @@ LLVM::LLVMFuncOp lookupOrCreatePrintI64Fn(ModuleOp moduleOp);
3636
LLVM::LLVMFuncOp lookupOrCreatePrintU64Fn(ModuleOp moduleOp);
3737
LLVM::LLVMFuncOp lookupOrCreatePrintF32Fn(ModuleOp moduleOp);
3838
LLVM::LLVMFuncOp lookupOrCreatePrintF64Fn(ModuleOp moduleOp);
39-
LLVM::LLVMFuncOp lookupOrCreatePrintStrFn(ModuleOp moduleOp);
39+
LLVM::LLVMFuncOp lookupOrCreatePrintStrFn(ModuleOp moduleOp,
40+
bool opaquePointers);
4041
LLVM::LLVMFuncOp lookupOrCreatePrintOpenFn(ModuleOp moduleOp);
4142
LLVM::LLVMFuncOp lookupOrCreatePrintCloseFn(ModuleOp moduleOp);
4243
LLVM::LLVMFuncOp lookupOrCreatePrintCommaFn(ModuleOp moduleOp);
4344
LLVM::LLVMFuncOp lookupOrCreatePrintNewlineFn(ModuleOp moduleOp);
44-
LLVM::LLVMFuncOp lookupOrCreateMallocFn(ModuleOp moduleOp, Type indexType);
45-
LLVM::LLVMFuncOp lookupOrCreateAlignedAllocFn(ModuleOp moduleOp,
46-
Type indexType);
47-
LLVM::LLVMFuncOp lookupOrCreateFreeFn(ModuleOp moduleOp);
48-
LLVM::LLVMFuncOp lookupOrCreateGenericAllocFn(ModuleOp moduleOp,
49-
Type indexType);
45+
LLVM::LLVMFuncOp lookupOrCreateMallocFn(ModuleOp moduleOp, Type indexType,
46+
bool opaquePointers);
47+
LLVM::LLVMFuncOp lookupOrCreateAlignedAllocFn(ModuleOp moduleOp, Type indexType,
48+
bool opaquePointers);
49+
LLVM::LLVMFuncOp lookupOrCreateFreeFn(ModuleOp moduleOp, bool opaquePointers);
50+
LLVM::LLVMFuncOp lookupOrCreateGenericAllocFn(ModuleOp moduleOp, Type indexType,
51+
bool opaquePointers);
5052
LLVM::LLVMFuncOp lookupOrCreateGenericAlignedAllocFn(ModuleOp moduleOp,
51-
Type indexType);
52-
LLVM::LLVMFuncOp lookupOrCreateGenericFreeFn(ModuleOp moduleOp);
53+
Type indexType,
54+
bool opaquePointers);
55+
LLVM::LLVMFuncOp lookupOrCreateGenericFreeFn(ModuleOp moduleOp,
56+
bool opaquePointers);
5357
LLVM::LLVMFuncOp lookupOrCreateMemRefCopyFn(ModuleOp moduleOp, Type indexType,
5458
Type unrankedDescriptorType);
5559

mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,8 @@ class CoroBeginOpConversion : public OpConversionPattern<CoroBeginOp> {
378378

379379
// Allocate memory for the coroutine frame.
380380
auto allocFuncOp = LLVM::lookupOrCreateAlignedAllocFn(
381-
op->getParentOfType<ModuleOp>(), rewriter.getI64Type());
381+
op->getParentOfType<ModuleOp>(), rewriter.getI64Type(),
382+
/*TODO: opaquePointers=*/false);
382383
auto coroAlloc = rewriter.create<LLVM::CallOp>(
383384
loc, allocFuncOp, ValueRange{coroAlign, coroSize});
384385

@@ -412,8 +413,8 @@ class CoroFreeOpConversion : public OpConversionPattern<CoroFreeOp> {
412413
rewriter.create<LLVM::CoroFreeOp>(loc, i8Ptr, adaptor.getOperands());
413414

414415
// Free the memory.
415-
auto freeFuncOp =
416-
LLVM::lookupOrCreateFreeFn(op->getParentOfType<ModuleOp>());
416+
auto freeFuncOp = LLVM::lookupOrCreateFreeFn(
417+
op->getParentOfType<ModuleOp>(), /*TODO: opaquePointers=*/false);
417418
rewriter.replaceOpWithNewOp<LLVM::CallOp>(op, freeFuncOp,
418419
ValueRange(coroMem.getResult()));
419420

mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ static void createPrintMsg(OpBuilder &builder, Location loc, ModuleOp moduleOp,
7272
SmallVector<LLVM::GEPArg> indices(1, 0);
7373
Value gep = builder.create<LLVM::GEPOp>(
7474
loc, LLVM::LLVMPointerType::get(builder.getI8Type()), msgAddr, indices);
75-
Operation *printer = LLVM::lookupOrCreatePrintStrFn(moduleOp);
75+
Operation *printer =
76+
LLVM::lookupOrCreatePrintStrFn(moduleOp, /*TODO: opaquePointers=*/false);
7677
builder.create<LLVM::CallOp>(loc, TypeRange(), SymbolRefAttr::get(printer),
7778
gep);
7879
}

0 commit comments

Comments
 (0)