|
17 | 17 | #include "flang/Lower/SymbolMap.h"
|
18 | 18 | #include "flang/Optimizer/Builder/HLFIRTools.h"
|
19 | 19 | #include "flang/Optimizer/Builder/Todo.h"
|
| 20 | +#include "flang/Optimizer/HLFIR/HLFIROps.h" |
20 | 21 | #include "flang/Semantics/tools.h"
|
21 | 22 |
|
22 | 23 | namespace Fortran {
|
@@ -127,8 +128,52 @@ void DataSharingProcessor::copyFirstPrivateSymbol(
|
127 | 128 | void DataSharingProcessor::copyLastPrivateSymbol(
|
128 | 129 | const semantics::Symbol *sym,
|
129 | 130 | [[maybe_unused]] mlir::OpBuilder::InsertPoint *lastPrivIP) {
|
130 |
| - if (sym->test(semantics::Symbol::Flag::OmpLastPrivate)) |
131 |
| - converter.copyHostAssociateVar(*sym, lastPrivIP); |
| 131 | + if (sym->test(semantics::Symbol::Flag::OmpLastPrivate)) { |
| 132 | + bool allocatable = semantics::IsAllocatable(sym->GetUltimate()); |
| 133 | + if (!allocatable) { |
| 134 | + converter.copyHostAssociateVar(*sym, lastPrivIP); |
| 135 | + return; |
| 136 | + } |
| 137 | + |
| 138 | + // copyHostAssociateVar doesn't work properly if the privatised copy was |
| 139 | + // reallocated (e.g. by assignment): it will only copy if the ultimate |
| 140 | + // symbol was already allocated, and it only copies data so any reallocated |
| 141 | + // lengths etc are lost |
| 142 | + |
| 143 | + // 1) Fetch the original copy of the variable. |
| 144 | + assert(sym->has<Fortran::semantics::HostAssocDetails>() && |
| 145 | + "No host-association found"); |
| 146 | + const Fortran::semantics::Symbol &hsym = sym->GetUltimate(); |
| 147 | + Fortran::lower::SymbolBox hsb = symTable->lookupOneLevelUpSymbol(hsym); |
| 148 | + assert(hsb && "Host symbol box not found"); |
| 149 | + |
| 150 | + // 2) Fetch the copied one that will mask the original. |
| 151 | + Fortran::lower::SymbolBox sb = symTable->shallowLookupSymbol(sym); |
| 152 | + assert(sb && "Host-associated symbol box not found"); |
| 153 | + assert(hsb.getAddr() != sb.getAddr() && |
| 154 | + "Host and associated symbol boxes are the same"); |
| 155 | + |
| 156 | + // 3) Perform the assignment. |
| 157 | + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); |
| 158 | + mlir::Location loc = converter.genLocation(sym->name()); |
| 159 | + mlir::OpBuilder::InsertPoint insPt = builder.saveInsertionPoint(); |
| 160 | + if (lastPrivIP && lastPrivIP->isSet()) |
| 161 | + builder.restoreInsertionPoint(*lastPrivIP); |
| 162 | + else |
| 163 | + builder.setInsertionPointAfter(sb.getAddr().getDefiningOp()); |
| 164 | + |
| 165 | + hlfir::Entity dst{hsb.getAddr()}; |
| 166 | + hlfir::Entity src{sb.getAddr()}; |
| 167 | + builder.create<hlfir::AssignOp>( |
| 168 | + loc, src, dst, /*isWholeAllocatableAssignment=*/allocatable, |
| 169 | + /*keepLhsLengthInAllocatableAssignment=*/false, |
| 170 | + /*temporary_lhs=*/false); |
| 171 | + |
| 172 | + if (lastPrivIP && lastPrivIP->isSet() && |
| 173 | + sym->test(Fortran::semantics::Symbol::Flag::OmpLastPrivate)) { |
| 174 | + builder.restoreInsertionPoint(insPt); |
| 175 | + } |
| 176 | + } |
132 | 177 | }
|
133 | 178 |
|
134 | 179 | void DataSharingProcessor::collectOmpObjectListSymbol(
|
|
0 commit comments