Skip to content

Commit 376402b

Browse files
committed
[flang][openacc] Add basic lowering to new data operations for acc.enter_data
This is an initial patch that lowers acc.enter_data copyin/create/attach clauses to the newly added data operand operations. Follow up patches will add support for array section and derived type and derived type component as well as support in other data operation. Reviewed By: razvanlupusoru Differential Revision: https://reviews.llvm.org/D148721
1 parent 2b4efd2 commit 376402b

File tree

2 files changed

+143
-34
lines changed

2 files changed

+143
-34
lines changed

flang/lib/Lower/OpenACC.cpp

Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,80 @@ genObjectList(const Fortran::parser::AccObjectList &objectList,
100100
}
101101
}
102102

103+
template <typename Op>
104+
static void
105+
genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
106+
Fortran::lower::AbstractConverter &converter,
107+
Fortran::semantics::SemanticsContext &semanticsContext,
108+
Fortran::lower::StatementContext &stmtCtx,
109+
llvm::SmallVectorImpl<mlir::Value> &dataOperands,
110+
mlir::acc::DataClause dataClause, bool structured) {
111+
112+
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
113+
114+
auto createOpAndAddOperand = [&](Fortran::lower::SymbolRef sym,
115+
llvm::StringRef name, mlir::Location loc) {
116+
mlir::Value symAddr = converter.getSymbolAddress(sym);
117+
// TODO: Might need revisiting to handle for non-shared clauses
118+
if (!symAddr) {
119+
if (const auto *details =
120+
sym->detailsIf<Fortran::semantics::HostAssocDetails>())
121+
symAddr = converter.getSymbolAddress(details->symbol());
122+
}
123+
124+
if (!symAddr)
125+
llvm::report_fatal_error("could not retrieve symbol address");
126+
127+
Op op = builder.create<Op>(loc, symAddr.getType(), symAddr);
128+
op.setNameAttr(builder.getStringAttr(name));
129+
op.setStructured(structured);
130+
op.setDataClause(dataClause);
131+
op->setAttr(Op::getOperandSegmentSizeAttr(),
132+
builder.getDenseI32ArrayAttr({1, 0, 0}));
133+
dataOperands.push_back(op.getAccPtr());
134+
};
135+
136+
for (const auto &accObject : objectList.v) {
137+
std::visit(
138+
Fortran::common::visitors{
139+
[&](const Fortran::parser::Designator &designator) {
140+
mlir::Location operandLocation =
141+
converter.genLocation(designator.source);
142+
if (auto expr{Fortran::semantics::AnalyzeExpr(semanticsContext,
143+
designator)}) {
144+
if ((*expr).Rank() > 0 &&
145+
Fortran::parser::Unwrap<Fortran::parser::ArrayElement>(
146+
designator)) {
147+
TODO(operandLocation, "OpenACC array section data operand");
148+
} else if (Fortran::parser::Unwrap<
149+
Fortran::parser::StructureComponent>(
150+
designator)) {
151+
TODO(operandLocation, "OpenACC derived-type data operand");
152+
} else {
153+
// Scalar or full array.
154+
if (const auto *dataRef{std::get_if<Fortran::parser::DataRef>(
155+
&designator.u)}) {
156+
const Fortran::parser::Name &name =
157+
Fortran::parser::GetLastName(*dataRef);
158+
createOpAndAddOperand(*name.symbol, name.ToString(),
159+
operandLocation);
160+
} else { // Unsupported
161+
llvm::report_fatal_error(
162+
"Unsupported type of OpenACC operand");
163+
}
164+
}
165+
}
166+
},
167+
[&](const Fortran::parser::Name &name) {
168+
mlir::Location operandLocation =
169+
converter.genLocation(name.source);
170+
createOpAndAddOperand(*name.symbol, name.ToString(),
171+
operandLocation);
172+
}},
173+
accObject.u);
174+
}
175+
}
176+
103177
template <typename Clause>
104178
static void genObjectListWithModifier(
105179
const Clause *x, Fortran::lower::AbstractConverter &converter,
@@ -794,18 +868,33 @@ genACCEnterDataOp(Fortran::lower::AbstractConverter &converter,
794868
copyinClause->v;
795869
const auto &accObjectList =
796870
std::get<Fortran::parser::AccObjectList>(listWithModifier.t);
797-
genObjectList(accObjectList, converter, semanticsContext, stmtCtx,
798-
copyinOperands);
871+
genDataOperandOperations<mlir::acc::CopyinOp>(
872+
accObjectList, converter, semanticsContext, stmtCtx,
873+
dataClauseOperands, mlir::acc::DataClause::acc_copyin, false);
799874
} else if (const auto *createClause =
800875
std::get_if<Fortran::parser::AccClause::Create>(&clause.u)) {
801-
genObjectListWithModifier<Fortran::parser::AccClause::Create>(
802-
createClause, converter, semanticsContext, stmtCtx,
803-
Fortran::parser::AccDataModifier::Modifier::Zero, createZeroOperands,
804-
createOperands);
876+
const Fortran::parser::AccObjectListWithModifier &listWithModifier =
877+
createClause->v;
878+
const auto &accObjectList =
879+
std::get<Fortran::parser::AccObjectList>(listWithModifier.t);
880+
const auto &modifier =
881+
std::get<std::optional<Fortran::parser::AccDataModifier>>(
882+
listWithModifier.t);
883+
if (modifier &&
884+
(*modifier).v == Fortran::parser::AccDataModifier::Modifier::Zero) {
885+
genDataOperandOperations<mlir::acc::CreateOp>(
886+
accObjectList, converter, semanticsContext, stmtCtx,
887+
dataClauseOperands, mlir::acc::DataClause::acc_create_zero, false);
888+
} else {
889+
genDataOperandOperations<mlir::acc::CreateOp>(
890+
accObjectList, converter, semanticsContext, stmtCtx,
891+
dataClauseOperands, mlir::acc::DataClause::acc_create, false);
892+
}
805893
} else if (const auto *attachClause =
806894
std::get_if<Fortran::parser::AccClause::Attach>(&clause.u)) {
807-
genObjectList(attachClause->v, converter, semanticsContext, stmtCtx,
808-
attachOperands);
895+
genDataOperandOperations<mlir::acc::AttachOp>(
896+
attachClause->v, converter, semanticsContext, stmtCtx,
897+
dataClauseOperands, mlir::acc::DataClause::acc_attach, false);
809898
} else {
810899
llvm::report_fatal_error(
811900
"Unknown clause in ENTER DATA directive lowering");

flang/test/Lower/OpenACC/acc-enter-data.f90

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,62 +8,82 @@ subroutine acc_enter_data
88
real, pointer :: d
99
logical :: ifCondition = .TRUE.
1010

11-
!CHECK: [[A:%.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ea"}
12-
!CHECK: [[B:%.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Eb"}
13-
!CHECK: [[C:%.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ec"}
14-
!CHECK: [[D:%.*]] = fir.alloca !fir.box<!fir.ptr<f32>> {bindc_name = "d", uniq_name = "{{.*}}Ed"}
11+
!CHECK: %[[A:.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ea"}
12+
!CHECK: %[[B:.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Eb"}
13+
!CHECK: %[[C:.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ec"}
14+
!CHECK: %[[D:.*]] = fir.alloca !fir.box<!fir.ptr<f32>> {bindc_name = "d", uniq_name = "{{.*}}Ed"}
1515

1616
!$acc enter data create(a)
17-
!CHECK: acc.enter_data create([[A]] : !fir.ref<!fir.array<10x10xf32>>){{$}}
17+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
18+
!CHECK: acc.enter_data dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>){{$}}
1819

1920
!$acc enter data create(a) if(.true.)
21+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
2022
!CHECK: [[IF1:%.*]] = arith.constant true
21-
!CHECK: acc.enter_data if([[IF1]]) create([[A]] : !fir.ref<!fir.array<10x10xf32>>){{$}}
23+
!CHECK: acc.enter_data if([[IF1]]) dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>){{$}}
2224

2325
!$acc enter data create(a) if(ifCondition)
26+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
2427
!CHECK: [[IFCOND:%.*]] = fir.load %{{.*}} : !fir.ref<!fir.logical<4>>
2528
!CHECK: [[IF2:%.*]] = fir.convert [[IFCOND]] : (!fir.logical<4>) -> i1
26-
!CHECK: acc.enter_data if([[IF2]]) create([[A]] : !fir.ref<!fir.array<10x10xf32>>){{$}}
29+
!CHECK: acc.enter_data if([[IF2]]) dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>){{$}}
2730

2831
!$acc enter data create(a) create(b) create(c)
29-
!CHECK: acc.enter_data create([[A]], [[B]], [[C]] : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>){{$}}
32+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
33+
!CHECK: %[[CREATE_B:.*]] = acc.create varPtr(%[[B]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "b", structured = false}
34+
!CHECK: %[[CREATE_C:.*]] = acc.create varPtr(%[[C]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "c", structured = false}
35+
!CHECK: acc.enter_data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>){{$}}
3036

3137
!$acc enter data create(a) create(b) create(zero: c)
32-
!CHECK: acc.enter_data create([[A]], [[B]] : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>) create_zero([[C]] : !fir.ref<!fir.array<10x10xf32>>){{$}}
38+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
39+
!CHECK: %[[CREATE_B:.*]] = acc.create varPtr(%[[B]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "b", structured = false}
40+
!CHECK: %[[CREATE_C:.*]] = acc.create varPtr(%[[C]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {dataClause = 8 : i64, name = "c", structured = false}
41+
!CHECK: acc.enter_data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>){{$}}
3342

3443
!$acc enter data copyin(a) create(b) attach(d)
35-
!CHECK: acc.enter_data copyin([[A]] : !fir.ref<!fir.array<10x10xf32>>) create([[B]] : !fir.ref<!fir.array<10x10xf32>>) attach([[D]] : !fir.ref<!fir.box<!fir.ptr<f32>>>){{$}}
44+
!CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
45+
!CHECK: %[[CREATE_B:.*]] = acc.create varPtr(%[[B]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "b", structured = false}
46+
!CHECK: %[[ATTACH_D:.*]] = acc.attach varPtr(%[[D]] : !fir.ref<!fir.box<!fir.ptr<f32>>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>> {name = "d", structured = false}
47+
!CHECK: acc.enter_data dataOperands(%[[COPYIN_A]], %[[CREATE_B]], %[[ATTACH_D]] : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.box<!fir.ptr<f32>>>){{$}}
3648

3749
!$acc enter data create(a) async
38-
!CHECK: acc.enter_data create([[A]] : !fir.ref<!fir.array<10x10xf32>>) attributes {async}
50+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
51+
!CHECK: acc.enter_data dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>) attributes {async}
3952

4053
!$acc enter data create(a) wait
41-
!CHECK: acc.enter_data create([[A]] : !fir.ref<!fir.array<10x10xf32>>) attributes {wait}
54+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
55+
!CHECK: acc.enter_data dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>) attributes {wait}
4256

4357
!$acc enter data create(a) async wait
44-
!CHECK: acc.enter_data create([[A]] : !fir.ref<!fir.array<10x10xf32>>) attributes {async, wait}
58+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
59+
!CHECK: acc.enter_data dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>) attributes {async, wait}
4560

4661
!$acc enter data create(a) async(1)
47-
!CHECK: [[ASYNC1:%.*]] = arith.constant 1 : i32
48-
!CHECK: acc.enter_data async([[ASYNC1]] : i32) create([[A]] : !fir.ref<!fir.array<10x10xf32>>)
62+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
63+
!CHECK: %[[ASYNC1:.*]] = arith.constant 1 : i32
64+
!CHECK: acc.enter_data async(%[[ASYNC1]] : i32) dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>)
4965

5066
!$acc enter data create(a) async(async)
51-
!CHECK: [[ASYNC2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
52-
!CHECK: acc.enter_data async([[ASYNC2]] : i32) create([[A]] : !fir.ref<!fir.array<10x10xf32>>)
67+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
68+
!CHECK: %[[ASYNC2:.*]] = fir.load %{{.*}} : !fir.ref<i32>
69+
!CHECK: acc.enter_data async(%[[ASYNC2]] : i32) dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>)
5370

5471
!$acc enter data create(a) wait(1)
55-
!CHECK: [[WAIT1:%.*]] = arith.constant 1 : i32
56-
!CHECK: acc.enter_data wait([[WAIT1]] : i32) create([[A]] : !fir.ref<!fir.array<10x10xf32>>)
72+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
73+
!CHECK: %[[WAIT1:.*]] = arith.constant 1 : i32
74+
!CHECK: acc.enter_data wait(%[[WAIT1]] : i32) dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>)
5775

5876
!$acc enter data create(a) wait(queues: 1, 2)
59-
!CHECK: [[WAIT2:%.*]] = arith.constant 1 : i32
60-
!CHECK: [[WAIT3:%.*]] = arith.constant 2 : i32
61-
!CHECK: acc.enter_data wait([[WAIT2]], [[WAIT3]] : i32, i32) create([[A]] : !fir.ref<!fir.array<10x10xf32>>)
77+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
78+
!CHECK: %[[WAIT2:.*]] = arith.constant 1 : i32
79+
!CHECK: %[[WAIT3:.*]] = arith.constant 2 : i32
80+
!CHECK: acc.enter_data wait(%[[WAIT2]], %[[WAIT3]] : i32, i32) dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>)
6281

6382
!$acc enter data create(a) wait(devnum: 1: queues: 1, 2)
64-
!CHECK: [[WAIT4:%.*]] = arith.constant 1 : i32
65-
!CHECK: [[WAIT5:%.*]] = arith.constant 2 : i32
66-
!CHECK: [[WAIT6:%.*]] = arith.constant 1 : i32
67-
!CHECK: acc.enter_data wait_devnum([[WAIT6]] : i32) wait([[WAIT4]], [[WAIT5]] : i32, i32) create([[A]] : !fir.ref<!fir.array<10x10xf32>>)
83+
!CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false}
84+
!CHECK: %[[WAIT4:.*]] = arith.constant 1 : i32
85+
!CHECK: %[[WAIT5:.*]] = arith.constant 2 : i32
86+
!CHECK: %[[WAIT6:.*]] = arith.constant 1 : i32
87+
!CHECK: acc.enter_data wait_devnum(%[[WAIT6]] : i32) wait(%[[WAIT4]], %[[WAIT5]] : i32, i32) dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>)
6888

6989
end subroutine acc_enter_data

0 commit comments

Comments
 (0)