Skip to content

Commit 1a55c63

Browse files
authored
[flang][do concurrent] Use values yielded by local init regions (llvm#155223)
Similar to what is done for OpenMP `private` clauses, prefer the value yielded from the init region to the allocated private variable in case the region is operating on arguments by-value (e.g. Fortran character boxes). This changes provides the same results as llvm#154303 in both the LLVM and Fujitsu test suites (so no regressions). ``` Testing Time: 7216.26s Passed : 88522 Failed : 160 Executable Missing: 408 ```
1 parent 9cc89bb commit 1a55c63

File tree

2 files changed

+67
-5
lines changed

2 files changed

+67
-5
lines changed

flang/lib/Optimizer/Transforms/SimplifyFIROperations.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,19 +210,33 @@ class DoConcurrentConversion
210210
mapper.map(region.getArguments(), regionArgs);
211211
for (mlir::Operation &op : region.front().without_terminator())
212212
(void)rewriter.clone(op, mapper);
213+
214+
auto yield = mlir::cast<fir::YieldOp>(region.front().getTerminator());
215+
assert(yield.getResults().size() < 2);
216+
217+
return yield.getResults().empty()
218+
? mlir::Value{}
219+
: mapper.lookup(yield.getResults()[0]);
213220
};
214221

215-
if (!localizer.getInitRegion().empty())
216-
cloneLocalizerRegion(localizer.getInitRegion(), {localVar, localArg},
217-
rewriter.getInsertionPoint());
222+
if (!localizer.getInitRegion().empty()) {
223+
// Prefer the value yielded from the init region to the allocated
224+
// private variable in case the region is operating on arguments
225+
// by-value (e.g. Fortran character boxes).
226+
localAlloc = cloneLocalizerRegion(localizer.getInitRegion(),
227+
{localVar, localAlloc},
228+
rewriter.getInsertionPoint());
229+
assert(localAlloc);
230+
}
218231

219232
if (localizer.getLocalitySpecifierType() ==
220233
fir::LocalitySpecifierType::LocalInit)
221-
cloneLocalizerRegion(localizer.getCopyRegion(), {localVar, localArg},
234+
cloneLocalizerRegion(localizer.getCopyRegion(),
235+
{localVar, localAlloc},
222236
rewriter.getInsertionPoint());
223237

224238
if (!localizer.getDeallocRegion().empty())
225-
cloneLocalizerRegion(localizer.getDeallocRegion(), {localArg},
239+
cloneLocalizerRegion(localizer.getDeallocRegion(), {localAlloc},
226240
rewriter.getInsertionBlock()->end());
227241

228242
rewriter.replaceAllUsesWith(localArg, localAlloc);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Tests that for `boxchar` local values, we use the value yielded by the `init`
2+
// region rather than the local allocated storage.
3+
4+
// RUN: fir-opt --split-input-file --simplify-fir-operations %s | FileCheck %s
5+
6+
fir.local {type = local} @_QFtestEx_private_boxchar_c8xU : !fir.boxchar<1> init {
7+
^bb0(%arg0: !fir.boxchar<1>, %arg1: !fir.boxchar<1>):
8+
%0:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
9+
%1 = fir.allocmem !fir.char<1,?>(%0#1 : index) {bindc_name = "", uniq_name = ""}
10+
%2 = fir.emboxchar %1, %0#1 : (!fir.heap<!fir.char<1,?>>, index) -> !fir.boxchar<1>
11+
fir.yield(%2 : !fir.boxchar<1>)
12+
} dealloc {
13+
^bb0(%arg0: !fir.boxchar<1>):
14+
%0:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
15+
%1 = fir.convert %0#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.heap<!fir.char<1,?>>
16+
fir.freemem %1 : !fir.heap<!fir.char<1,?>>
17+
fir.yield
18+
}
19+
func.func @_QPtest(%arg0: !fir.boxchar<1> {fir.bindc_name = "x"}) {
20+
%0 = fir.dummy_scope : !fir.dscope
21+
%1:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
22+
%2:2 = hlfir.declare %1#0 typeparams %1#1 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.ref<!fir.char<1,?>>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
23+
%c1 = arith.constant 1 : index
24+
%c10 = arith.constant 10 : index
25+
fir.do_concurrent {
26+
%5 = fir.alloca i32 {bindc_name = "i"}
27+
%6:2 = hlfir.declare %5 {uniq_name = "_QFtestEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
28+
fir.do_concurrent.loop (%arg1) = (%c1) to (%c10) step (%c1) local(@_QFtestEx_private_boxchar_c8xU %2#0 -> %arg2 : !fir.boxchar<1>) {
29+
%7 = fir.convert %arg1 : (index) -> i32
30+
fir.store %7 to %6#0 : !fir.ref<i32>
31+
%8:2 = fir.unboxchar %arg2 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
32+
}
33+
}
34+
return
35+
}
36+
37+
// CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtestEx"}
38+
// CHECK: fir.do_loop %{{.*}} = %{{.*}} unordered {
39+
// CHECK: %[[X_UNBOX:.*]]:2 = fir.unboxchar %[[X_DECL:.*]]#0
40+
41+
// Verify that the value yielded by the `init` region is the one used through
42+
// out the loop region rather than the local allocation.
43+
// CHECK: %[[LOCAL_ALLOC:.*]] = fir.allocmem !fir.char<1,?>(%[[X_UNBOX]]#1 : index)
44+
// CHECK: %[[LOCAL_BOX:.*]] = fir.emboxchar %[[LOCAL_ALLOC]], %[[X_UNBOX]]#1
45+
// CHECK: %[[LOCAL_UNBOX:.*]]:2 = fir.unboxchar %[[LOCAL_BOX]]
46+
// CHECK: %[[LOCAL_CVT:.*]] = fir.convert %[[LOCAL_UNBOX]]#0
47+
// CHECK: fir.freemem %[[LOCAL_CVT]]
48+
// CHECK: }

0 commit comments

Comments
 (0)