Skip to content

Commit a1c736e

Browse files
committed
[Flang] Cray pointer Lowering
This patch is to add cray pointer (aka integer pointer) support to flang. Syntax and semantic checking were already available in flang. Cray pointers reference (https://gcc.gnu.org/onlinedocs/gfortran/Cray-pointers.html) In order to implement the feature we create the following sequence for a simple scalar load and store: ``` integer pte, i pointer(ptr, pte) i = pte ``` ``` %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"} %2 = fir.alloca i32 {bindc_name = "pte", uniq_name = "_QFEpte"} %3 = fir.alloca i64 {bindc_name = "ptr", uniq_name = "_QFEptr"} ... %7 = fir.embox %3 : (!fir.ref<i64>) -> !fir.box<i64> %8 = fir.box_addr %7 : (!fir.box<i64>) -> !fir.ref<i64> %9 = fir.convert %8 : (!fir.ref<i64>) -> !fir.ref<!fir.ptr<i32>> %10 = fir.load %9 : !fir.ref<!fir.ptr<i32>> %11 = fir.load %10 : !fir.ptr<i32> fir.store %11 to %1 : !fir.ref<i32> ``` ``` integer pte, i pointer(ptr, pte) pte = i ``` ``` %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"} %2 = fir.alloca i32 {bindc_name = "pte", uniq_name = "_QFEpte"} %3 = fir.alloca i64 {bindc_name = "ptr", uniq_name = "_QFEptr"} %7 = fir.load %1 : !fir.ref<i32> %8 = fir.embox %3 : (!fir.ref<i64>) -> !fir.box<i64> %9 = fir.box_addr %8 : (!fir.box<i64>) -> !fir.ref<i64> %10 = fir.convert %9 : (!fir.ref<i64>) -> !fir.ref<!fir.ptr<i32>> %11 = fir.load %10 : !fir.ref<!fir.ptr<i32>> fir.store %7 to %11 : !fir.ptr<i32> ``` The sequence is very similar for array element cases with the addition of fir.coordinate_of for the specific element. The whole array case is slightly different but uses the same sequence before the fir.array_load and fir.array_merge_store. Reviewed By: kkwli0 Differential Revision: https://reviews.llvm.org/D151478
1 parent d3d4d78 commit a1c736e

File tree

4 files changed

+519
-2
lines changed

4 files changed

+519
-2
lines changed

flang/include/flang/Lower/ConvertExpr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ inline mlir::NamedAttribute getAdaptToByRefAttr(fir::FirOpBuilder &builder) {
234234
builder.getUnitAttr()};
235235
}
236236

237+
Fortran::semantics::SymbolRef getPointer(Fortran::semantics::SymbolRef sym);
238+
mlir::Value addCrayPointerInst(mlir::Location loc, fir::FirOpBuilder &builder,
239+
mlir::Value ptrVal, mlir::Type ptrTy,
240+
mlir::Type pteTy);
237241
} // namespace Fortran::lower
238242

239243
#endif // FORTRAN_LOWER_CONVERTEXPR_H

flang/lib/Lower/Bridge.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3578,6 +3578,26 @@ class FirConverter : public Fortran::lower::AbstractConverter {
35783578
// to a result variable of one of the other types requires
35793579
// conversion to the actual type.
35803580
mlir::Type toTy = genType(assign.lhs);
3581+
3582+
// If Cray pointee, need to handle the address
3583+
// Array is handled in genCoordinateOp.
3584+
if (sym->test(Fortran::semantics::Symbol::Flag::CrayPointee) &&
3585+
sym->Rank() == 0) {
3586+
// get the corresponding Cray pointer
3587+
3588+
auto ptrSym = Fortran::lower::getPointer(*sym);
3589+
fir::ExtendedValue ptr =
3590+
getSymbolExtendedValue(ptrSym, nullptr);
3591+
mlir::Value ptrVal = fir::getBase(ptr);
3592+
mlir::Type ptrTy = genType(*ptrSym);
3593+
3594+
fir::ExtendedValue pte =
3595+
getSymbolExtendedValue(*sym, nullptr);
3596+
mlir::Value pteVal = fir::getBase(pte);
3597+
mlir::Value cnvrt = Fortran::lower::addCrayPointerInst(
3598+
loc, *builder, ptrVal, ptrTy, pteVal.getType());
3599+
addr = builder->create<fir::LoadOp>(loc, cnvrt);
3600+
}
35813601
mlir::Value cast =
35823602
isVector ? val
35833603
: builder->convertWithSemantics(loc, toTy, val);

flang/lib/Lower/ConvertExpr.cpp

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ class ScalarExprLowering {
849849
ExtValue genval(Fortran::semantics::SymbolRef sym) {
850850
mlir::Location loc = getLoc();
851851
ExtValue var = gen(sym);
852-
if (const fir::UnboxedValue *s = var.getUnboxed())
852+
if (const fir::UnboxedValue *s = var.getUnboxed()) {
853853
if (fir::isa_ref_type(s->getType())) {
854854
// A function with multiple entry points returning different types
855855
// tags all result variables with one of the largest types to allow
@@ -861,9 +861,23 @@ class ScalarExprLowering {
861861
if (addr.getType() != resultType)
862862
addr = builder.createConvert(loc, builder.getRefType(resultType),
863863
addr);
864+
} else if (sym->test(Fortran::semantics::Symbol::Flag::CrayPointee)) {
865+
// get the corresponding Cray pointer
866+
auto ptrSym = Fortran::lower::getPointer(sym);
867+
ExtValue ptr = gen(ptrSym);
868+
mlir::Value ptrVal = fir::getBase(ptr);
869+
mlir::Type ptrTy = converter.genType(*ptrSym);
870+
871+
ExtValue pte = gen(sym);
872+
mlir::Value pteVal = fir::getBase(pte);
873+
874+
mlir::Value cnvrt = Fortran::lower::addCrayPointerInst(
875+
loc, builder, ptrVal, ptrTy, pteVal.getType());
876+
addr = builder.create<fir::LoadOp>(loc, cnvrt);
864877
}
865878
return genLoad(addr);
866879
}
880+
}
867881
return var;
868882
}
869883

@@ -1553,6 +1567,21 @@ class ScalarExprLowering {
15531567
args.push_back(builder.create<mlir::arith::SubIOp>(loc, ty, val, lb));
15541568
}
15551569
mlir::Value base = fir::getBase(array);
1570+
1571+
auto baseSym = getFirstSym(aref);
1572+
if (baseSym.test(Fortran::semantics::Symbol::Flag::CrayPointee)) {
1573+
// get the corresponding Cray pointer
1574+
auto ptrSym = Fortran::lower::getPointer(baseSym);
1575+
1576+
fir::ExtendedValue ptr = gen(ptrSym);
1577+
mlir::Value ptrVal = fir::getBase(ptr);
1578+
mlir::Type ptrTy = ptrVal.getType();
1579+
1580+
mlir::Value cnvrt = Fortran::lower::addCrayPointerInst(
1581+
loc, builder, ptrVal, ptrTy, base.getType());
1582+
base = builder.create<fir::LoadOp>(loc, cnvrt);
1583+
}
1584+
15561585
mlir::Type eleTy = fir::dyn_cast_ptrOrBoxEleTy(base.getType());
15571586
if (auto classTy = eleTy.dyn_cast<fir::ClassType>())
15581587
eleTy = classTy.getEleTy();
@@ -5632,7 +5661,8 @@ class ArrayExprLowering {
56325661
}
56335662

56345663
/// Base case of generating an array reference,
5635-
CC genarr(const ExtValue &extMemref, ComponentPath &components) {
5664+
CC genarr(const ExtValue &extMemref, ComponentPath &components,
5665+
mlir::Value CrayPtr = nullptr) {
56365666
mlir::Location loc = getLoc();
56375667
mlir::Value memref = fir::getBase(extMemref);
56385668
mlir::Type arrTy = fir::dyn_cast_ptrOrBoxEleTy(memref.getType());
@@ -5777,6 +5807,16 @@ class ArrayExprLowering {
57775807
}
57785808
auto arrLoad = builder.create<fir::ArrayLoadOp>(
57795809
loc, arrTy, memref, shape, slice, fir::getTypeParams(extMemref));
5810+
5811+
if (CrayPtr) {
5812+
mlir::Type ptrTy = CrayPtr.getType();
5813+
mlir::Value cnvrt = Fortran::lower::addCrayPointerInst(
5814+
loc, builder, CrayPtr, ptrTy, memref.getType());
5815+
auto addr = builder.create<fir::LoadOp>(loc, cnvrt);
5816+
arrLoad = builder.create<fir::ArrayLoadOp>(loc, arrTy, addr, shape, slice,
5817+
fir::getTypeParams(extMemref));
5818+
}
5819+
57805820
mlir::Value arrLd = arrLoad.getResult();
57815821
if (isProjectedCopyInCopyOut()) {
57825822
// Semantics are projected copy-in copy-out.
@@ -6930,6 +6970,21 @@ class ArrayExprLowering {
69306970
return genImplicitArrayAccess(x.GetComponent(), components);
69316971
}
69326972

6973+
CC genImplicitArrayAccess(const Fortran::semantics::Symbol &x,
6974+
ComponentPath &components) {
6975+
mlir::Value ptrVal = nullptr;
6976+
if (x.test(Fortran::semantics::Symbol::Flag::CrayPointee)) {
6977+
auto ptrSym = Fortran::lower::getPointer(x);
6978+
ExtValue ptr = converter.getSymbolExtendedValue(ptrSym);
6979+
ptrVal = fir::getBase(ptr);
6980+
}
6981+
components.reversePath.push_back(ImplicitSubscripts{});
6982+
ExtValue exv = asScalarRef(x);
6983+
lowerPath(exv, components);
6984+
auto lambda = genarr(exv, components, ptrVal);
6985+
return [=](IterSpace iters) { return lambda(components.pc(iters)); };
6986+
}
6987+
69336988
template <typename A>
69346989
CC genAsScalar(const A &x) {
69356990
mlir::Location loc = getLoc();
@@ -7573,3 +7628,37 @@ void Fortran::lower::createArrayMergeStores(
75737628
esp.resetBindings();
75747629
esp.incrementCounter();
75757630
}
7631+
7632+
Fortran::semantics::SymbolRef
7633+
Fortran::lower::getPointer(Fortran::semantics::SymbolRef sym) {
7634+
assert(!sym->owner().crayPointers().empty() &&
7635+
"empty Cray pointer/pointee map");
7636+
for (const auto &[pointee, pointer] : sym->owner().crayPointers()) {
7637+
if (pointee == sym->name()) {
7638+
Fortran::semantics::SymbolRef v{pointer.get()};
7639+
return v;
7640+
}
7641+
}
7642+
llvm_unreachable("corresponding Cray pointer cannot be found");
7643+
}
7644+
7645+
mlir::Value Fortran::lower::addCrayPointerInst(mlir::Location loc,
7646+
fir::FirOpBuilder &builder,
7647+
mlir::Value ptrVal,
7648+
mlir::Type ptrTy,
7649+
mlir::Type pteTy) {
7650+
7651+
mlir::Value empty;
7652+
mlir::ValueRange emptyRange;
7653+
auto boxTy = fir::BoxType::get(ptrTy);
7654+
auto box = builder.create<fir::EmboxOp>(loc, boxTy, ptrVal, empty, empty,
7655+
emptyRange);
7656+
mlir::Value addrof =
7657+
(ptrTy.isa<fir::ReferenceType>())
7658+
? builder.create<fir::BoxAddrOp>(loc, ptrTy, box)
7659+
: builder.create<fir::BoxAddrOp>(loc, builder.getRefType(ptrTy), box);
7660+
7661+
auto refPtrTy =
7662+
builder.getRefType(fir::PointerType::get(fir::dyn_cast_ptrEleTy(pteTy)));
7663+
return builder.createConvert(loc, refPtrTy, addrof);
7664+
}

0 commit comments

Comments
 (0)