Skip to content

Commit ed3de95

Browse files
committed
[mlir] Ptr dialect #73057
This patch introduces the Ptr dialect, a dialect to model pointer operations motivated by the goal of modularizing the LLVM dialect. More specifically, this patch introduces: - The pointer dialect and type. - The `MemorySpaceAttrInterface` interface, an interface to conceptualize memory models, giving proper semantical meaning to the Ptr dialect ops. - The `ptr::LoadOp` operation, an operation to load data from memory, with the semantics defined by `MemorySpaceAttrInterface` and translatable to LLVM IR. - The `SharedDialectTypeInterface` interface, an interface to delegate printing and parsing to a different dialect. - The introduction of `LLVM::AddressSpaceAttr`, an attribute to model LLVM memory semantics. - The replacement of `LLVMPointerType` with `ptr::PtrType`.
1 parent d312788 commit ed3de95

File tree

187 files changed

+5717
-2929
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

187 files changed

+5717
-2929
lines changed

flang/lib/Optimizer/CodeGen/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_flang_library(FIRCodeGen
2121
FIRDialect
2222
FIRDialectSupport
2323
FIRSupport
24+
MLIRPtrDialect
2425
MLIRComplexToLLVM
2526
MLIRComplexToStandard
2627
MLIRMathToFuncs

flang/lib/Optimizer/CodeGen/CodeGen.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "mlir/Dialect/LLVMIR/Transforms/AddComdats.h"
4545
#include "mlir/Dialect/OpenACC/OpenACC.h"
4646
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
47+
#include "mlir/Dialect/Ptr/IR/PtrDialect.h"
4748
#include "mlir/IR/BuiltinTypes.h"
4849
#include "mlir/IR/Matchers.h"
4950
#include "mlir/Pass/Pass.h"
@@ -3615,6 +3616,7 @@ class FIRToLLVMLowering
36153616
fir::populateOpenMPFIRToLLVMConversionPatterns(typeConverter, pattern);
36163617

36173618
mlir::ConversionTarget target{*context};
3619+
target.addLegalDialect<mlir::ptr::PtrDialect>();
36183620
target.addLegalDialect<mlir::LLVM::LLVMDialect>();
36193621
// The OpenMP dialect is legal for Operations without regions, for those
36203622
// which contains regions it is legal if the region contains only the

flang/lib/Optimizer/Support/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ add_flang_library(FIRSupport
2020
MLIROpenACCToLLVMIRTranslation
2121
MLIROpenMPToLLVMIRTranslation
2222
MLIRLLVMToLLVMIRTranslation
23+
MLIRPtrToLLVMIRTranslation
2324
MLIRTargetLLVMIRExport
2425
MLIRTargetLLVMIRImport
2526

flang/lib/Optimizer/Support/InitFIR.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
1212
#include "mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h"
1313
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
14+
#include "mlir/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.h"
1415

1516
void fir::support::registerLLVMTranslation(mlir::MLIRContext &context) {
1617
mlir::DialectRegistry registry;
@@ -22,5 +23,7 @@ void fir::support::registerLLVMTranslation(mlir::MLIRContext &context) {
2223
registerLLVMDialectTranslation(registry);
2324
// Register builtin dialect interface.
2425
registerBuiltinDialectTranslation(registry);
26+
// Register ptr dialect interface.
27+
registerPtrDialectTranslation(registry);
2528
context.appendDialectRegistry(registry);
2629
}

flang/test/Fir/convert-to-llvm-openmp-and-fir.fir

+32-32
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ func.func @_QPsb1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!
2929
// CHECK: omp.parallel {
3030
// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
3131
// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr
32-
// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
32+
// CHECK: %[[N:.*]] = ptr.load %[[N_REF]] : !llvm.ptr -> i32
3333
// CHECK: omp.wsloop nowait
3434
// CHECK-SAME: for (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) inclusive step (%[[ONE_2]]) {
35-
// CHECK: llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
36-
// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32
35+
// CHECK: ptr.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
36+
// CHECK: %[[I1:.*]] = ptr.load %[[I_VAR]] : !llvm.ptr -> i32
3737
// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
3838
// CHECK: %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]] : i64
3939
// CHECK: %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr
40-
// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
40+
// CHECK: ptr.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
4141
// CHECK: omp.yield
4242
// CHECK: }
4343
// CHECK: omp.terminator
@@ -63,8 +63,8 @@ func.func @_QPsb2(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}, %arg1: !fir.ref<i
6363
// CHECK-SAME: %[[X_REF:.*]]: !llvm.ptr {fir.bindc_name = "x"}, %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}) {
6464
// CHECK: omp.parallel {
6565
// CHECK: omp.master {
66-
// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
67-
// CHECK: llvm.store %[[N]], %[[X_REF]] : i32, !llvm.ptr
66+
// CHECK: %[[N:.*]] = ptr.load %[[N_REF]] : !llvm.ptr -> i32
67+
// CHECK: ptr.store %[[N]], %[[X_REF]] : i32, !llvm.ptr
6868
// CHECK: omp.terminator
6969
// CHECK: }
7070
// CHECK: omp.terminator
@@ -99,7 +99,7 @@ func.func @_QPsb(%arr: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "arr"}) {
9999
// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i32) : i32
100100
// CHECK: %[[C50:.*]] = llvm.mlir.constant(50 : i32) : i32
101101
// CHECK: omp.wsloop for (%[[INDX:.*]]) : i32 = (%[[C1]]) to (%[[C50]]) inclusive step (%[[C1]]) {
102-
// CHECK: llvm.store %[[INDX]], %{{.*}} : i32, !llvm.ptr
102+
// CHECK: ptr.store %[[INDX]], %{{.*}} : i32, !llvm.ptr
103103
// CHECK: omp.yield
104104
// CHECK: omp.terminator
105105
// CHECK: llvm.return
@@ -201,15 +201,15 @@ func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref
201201
// CHECK: omp.parallel {
202202
// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
203203
// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr
204-
// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
204+
// CHECK: %[[N:.*]] = ptr.load %[[N_REF]] : !llvm.ptr -> i32
205205
// CHECK: omp.simdloop
206206
// CHECK-SAME: (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) step (%[[ONE_2]]) {
207-
// CHECK: llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
208-
// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32
207+
// CHECK: ptr.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
208+
// CHECK: %[[I1:.*]] = ptr.load %[[I_VAR]] : !llvm.ptr -> i32
209209
// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
210210
// CHECK: %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]] : i64
211211
// CHECK: %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr
212-
// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
212+
// CHECK: ptr.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
213213
// CHECK: omp.yield
214214
// CHECK: }
215215
// CHECK: omp.terminator
@@ -386,24 +386,24 @@ func.func @_QPopenmp_target_data_region() {
386386
// CHECK: %[[VAL_16:.*]] = llvm.icmp "sgt" %[[VAL_14]], %[[VAL_15]] : i64
387387
// CHECK: llvm.cond_br %[[VAL_16]], ^bb2, ^bb3
388388
// CHECK: ^bb2:
389-
// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
390-
// CHECK: %[[VAL_17:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
391-
// CHECK: %[[VAL_18:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
389+
// CHECK: ptr.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
390+
// CHECK: %[[VAL_17:.*]] = ptr.load %[[VAL_3]] : !llvm.ptr -> i32
391+
// CHECK: %[[VAL_18:.*]] = ptr.load %[[VAL_3]] : !llvm.ptr -> i32
392392
// CHECK: %[[VAL_19:.*]] = llvm.sext %[[VAL_18]] : i32 to i64
393393
// CHECK: %[[VAL_20:.*]] = llvm.mlir.constant(1 : i64) : i64
394394
// CHECK: %[[VAL_21:.*]] = llvm.sub %[[VAL_19]], %[[VAL_20]] : i64
395395
// CHECK: %[[VAL_22:.*]] = llvm.getelementptr %[[VAL_1]][0, %[[VAL_21]]] : (!llvm.ptr, i64) -> !llvm.ptr
396-
// CHECK: llvm.store %[[VAL_17]], %[[VAL_22]] : i32, !llvm.ptr
396+
// CHECK: ptr.store %[[VAL_17]], %[[VAL_22]] : i32, !llvm.ptr
397397
// CHECK: %[[VAL_23:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64
398398
// CHECK: %[[VAL_24:.*]] = llvm.trunc %[[VAL_8]] : i64 to i32
399-
// CHECK: %[[VAL_25:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
399+
// CHECK: %[[VAL_25:.*]] = ptr.load %[[VAL_3]] : !llvm.ptr -> i32
400400
// CHECK: %[[VAL_26:.*]] = llvm.add %[[VAL_25]], %[[VAL_24]] : i32
401401
// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64
402402
// CHECK: %[[VAL_28:.*]] = llvm.mlir.constant(1 : index) : i64
403403
// CHECK: %[[VAL_29:.*]] = llvm.sub %[[VAL_14]], %[[VAL_28]] : i64
404404
// CHECK: llvm.br ^bb1(%[[VAL_27]], %[[VAL_26]], %[[VAL_29]] : i64, i32, i64)
405405
// CHECK: ^bb3:
406-
// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
406+
// CHECK: ptr.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
407407
// CHECK: omp.terminator
408408
// CHECK: }
409409
// CHECK: llvm.return
@@ -463,7 +463,7 @@ func.func @_QPomp_target() {
463463
// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(1 : i64) : i64
464464
// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(0 : i64) : i64
465465
// CHECK: %[[VAL_7:.*]] = llvm.getelementptr %[[ARG_0]][0, %[[VAL_6]]] : (!llvm.ptr, i64) -> !llvm.ptr
466-
// CHECK: llvm.store %[[VAL_3]], %[[VAL_7]] : i32, !llvm.ptr
466+
// CHECK: ptr.store %[[VAL_3]], %[[VAL_7]] : i32, !llvm.ptr
467467
// CHECK: omp.terminator
468468
// CHECK: }
469469
// CHECK: llvm.return
@@ -669,9 +669,9 @@ func.func @_QPsb() {
669669
// CHECK: %[[EXIT_COND:.*]] = llvm.icmp "sgt"
670670
// CHECK: llvm.cond_br %[[EXIT_COND]], ^[[BB_LOOP_BODY:.*]], ^[[BB_EXIT:.*]]
671671
// CHECK: ^[[BB_LOOP_BODY]]:
672-
// CHECK: %[[LI_VAL:.*]] = llvm.load %[[LI_REF]] : !llvm.ptr -> i32
672+
// CHECK: %[[LI_VAL:.*]] = ptr.load %[[LI_REF]] : !llvm.ptr -> i32
673673
// CHECK: %[[LI_INC:.*]] = llvm.add %[[LI_VAL]], %[[ONE]] : i32
674-
// CHECK: llvm.store %[[LI_INC]], %[[LI_REF]] : i32, !llvm.ptr
674+
// CHECK: ptr.store %[[LI_INC]], %[[LI_REF]] : i32, !llvm.ptr
675675
// CHECK: llvm.br ^[[BB_ENTRY]]({{.*}})
676676
// CHECK: ^[[BB_EXIT]]:
677677
// CHECK: omp.terminator
@@ -703,15 +703,15 @@ func.func @_QPsb() {
703703
// CHECK: omp.parallel {
704704
// CHECK: omp.wsloop reduction(@[[EQV_REDUCTION]] %[[RED_ACCUMULATOR]] -> %[[PRV:.+]] : !llvm.ptr) for
705705
// CHECK: %[[ARRAY_ELEM_REF:.*]] = llvm.getelementptr %[[ARRAY_REF]][0, %{{.*}}] : (!llvm.ptr, i64) -> !llvm.ptr
706-
// CHECK: %[[ARRAY_ELEM:.*]] = llvm.load %[[ARRAY_ELEM_REF]] : !llvm.ptr -> i32
707-
// CHECK: %[[LPRV:.+]] = llvm.load %[[PRV]] : !llvm.ptr -> i32
706+
// CHECK: %[[ARRAY_ELEM:.*]] = ptr.load %[[ARRAY_ELEM_REF]] : !llvm.ptr -> i32
707+
// CHECK: %[[LPRV:.+]] = ptr.load %[[PRV]] : !llvm.ptr -> i32
708708
// CHECK: %[[ZERO_1:.*]] = llvm.mlir.constant(0 : i64) : i32
709709
// CHECK: %[[ARGVAL_1:.*]] = llvm.icmp "ne" %[[LPRV]], %[[ZERO_1]] : i32
710710
// CHECK: %[[ZERO_2:.*]] = llvm.mlir.constant(0 : i64) : i32
711711
// CHECK: %[[ARGVAL_2:.*]] = llvm.icmp "ne" %[[ARRAY_ELEM]], %[[ZERO_2]] : i32
712712
// CHECK: %[[RES:.*]] = llvm.icmp "eq" %[[ARGVAL_2]], %[[ARGVAL_1]] : i1
713713
// CHECK: %[[RES_EXT:.*]] = llvm.zext %[[RES]] : i1 to i32
714-
// CHECK: llvm.store %[[RES_EXT]], %[[PRV]] : i32, !llvm.ptr
714+
// CHECK: ptr.store %[[RES_EXT]], %[[PRV]] : i32, !llvm.ptr
715715
// CHECK: omp.yield
716716
// CHECK: omp.terminator
717717
// CHECK: llvm.return
@@ -781,10 +781,10 @@ func.func @_QPs(%arg0: !fir.ref<!fir.complex<4>> {fir.bindc_name = "x"}) {
781781
//CHECK: omp.parallel {
782782
//CHECK: %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32
783783
//CHECK: %[[ALLOCA_1:.*]] = llvm.alloca %[[CONST_1:.*]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
784-
//CHECK: %[[LOAD:.*]] = llvm.load %[[ALLOCA]] : !llvm.ptr -> !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>
785-
//CHECK: llvm.store %[[LOAD]], %[[ALLOCA_1]] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>, !llvm.ptr
784+
//CHECK: %[[LOAD:.*]] = ptr.load %[[ALLOCA]] : !llvm.ptr -> !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>
785+
//CHECK: ptr.store %[[LOAD]], %[[ALLOCA_1]] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>, !llvm.ptr
786786
//CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ALLOCA_1]][0, 0] : (!llvm.ptr) -> !llvm.ptr
787-
//CHECK: %[[LOAD_2:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> !llvm.ptr
787+
//CHECK: %[[LOAD_2:.*]] = ptr.load %[[GEP]] : !llvm.ptr -> !llvm.ptr
788788
//CHECK: omp.terminator
789789
//CHECK: }
790790

@@ -864,13 +864,13 @@ func.func @sub_() {
864864
omp.flush(%arg0, %arg1, %arg2 : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>)
865865
// CHECK: omp.flush
866866
omp.flush
867-
// CHECK: %[[A_VAL:.*]] = llvm.load %[[ARG_A]] : !llvm.ptr -> i32
867+
// CHECK: %[[A_VAL:.*]] = ptr.load %[[ARG_A]] : !llvm.ptr -> i32
868868
%0 = fir.load %arg0 : !fir.ref<i32>
869-
// CHECK: %[[B_VAL:.*]] = llvm.load %[[ARG_B]] : !llvm.ptr -> i32
869+
// CHECK: %[[B_VAL:.*]] = ptr.load %[[ARG_B]] : !llvm.ptr -> i32
870870
%1 = fir.load %arg1 : !fir.ref<i32>
871871
// CHECK: %[[C_VAL:.*]] = llvm.add %[[A_VAL]], %[[B_VAL]] : i32
872872
%2 = arith.addi %0, %1 : i32
873-
// CHECK: llvm.store %[[C_VAL]], %[[ARG_C]] : i32, !llvm.ptr
873+
// CHECK: ptr.store %[[C_VAL]], %[[ARG_C]] : i32, !llvm.ptr
874874
fir.store %2 to %arg2 : !fir.ref<i32>
875875
// CHECK: omp.terminator
876876
omp.terminator
@@ -892,13 +892,13 @@ func.func @omp_critical_() {
892892
%1 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFomp_criticalEy"}
893893
// CHECK: omp.critical(@help)
894894
omp.critical(@help) {
895-
// CHECK: %[[X_VAL:.*]] = llvm.load %[[X_REF]] : !llvm.ptr -> i32
895+
// CHECK: %[[X_VAL:.*]] = ptr.load %[[X_REF]] : !llvm.ptr -> i32
896896
%2 = fir.load %0 : !fir.ref<i32>
897-
// CHECK: %[[Y_VAL:.*]] = llvm.load %[[Y_REF]] : !llvm.ptr -> i32
897+
// CHECK: %[[Y_VAL:.*]] = ptr.load %[[Y_REF]] : !llvm.ptr -> i32
898898
%3 = fir.load %1 : !fir.ref<i32>
899899
// CHECK: %[[RESULT:.*]] = llvm.add %[[X_VAL]], %[[Y_VAL]] : i32
900900
%4 = arith.addi %2, %3 : i32
901-
// CHECK: llvm.store %[[RESULT]], %[[X_REF]] : i32, !llvm.ptr
901+
// CHECK: ptr.store %[[RESULT]], %[[X_REF]] : i32, !llvm.ptr
902902
fir.store %4 to %0 : !fir.ref<i32>
903903
// CHECK: omp.terminator
904904
omp.terminator

0 commit comments

Comments
 (0)