|
17 | 17 | #include "flang/Lower/ConvertVariable.h" |
18 | 18 | #include "flang/Lower/PFTBuilder.h" |
19 | 19 | #include "flang/Lower/SymbolMap.h" |
| 20 | +#include "flang/Optimizer/Builder/BoxValue.h" |
20 | 21 | #include "flang/Optimizer/Builder/HLFIRTools.h" |
21 | 22 | #include "flang/Optimizer/Builder/Todo.h" |
22 | 23 | #include "flang/Optimizer/HLFIR/HLFIROps.h" |
@@ -94,8 +95,60 @@ void DataSharingProcessor::insertDeallocs() { |
94 | 95 |
|
95 | 96 | void DataSharingProcessor::cloneSymbol(const semantics::Symbol *sym) { |
96 | 97 | bool isFirstPrivate = sym->test(semantics::Symbol::Flag::OmpFirstPrivate); |
97 | | - bool success = converter.createHostAssociateVarClone( |
98 | | - *sym, /*skipDefaultInit=*/isFirstPrivate); |
| 98 | + |
| 99 | + // If we are doing eager-privatization on a symbol created using delayed |
| 100 | + // privatization there could be incompatible types here e.g. |
| 101 | + // fir.ref<fir.box<fir.array<>>> |
| 102 | + bool success = false; |
| 103 | + [&]() { |
| 104 | + const auto *details = |
| 105 | + sym->detailsIf<Fortran::semantics::HostAssocDetails>(); |
| 106 | + assert(details && "No host-association found"); |
| 107 | + const Fortran::semantics::Symbol &hsym = details->symbol(); |
| 108 | + mlir::Value addr = converter.getSymbolAddress(hsym); |
| 109 | + |
| 110 | + if (auto refTy = mlir::dyn_cast<fir::ReferenceType>(addr.getType())) { |
| 111 | + if (auto boxTy = mlir::dyn_cast<fir::BoxType>(refTy.getElementType())) { |
| 112 | + if (auto arrayTy = |
| 113 | + mlir::dyn_cast<fir::SequenceType>(boxTy.getElementType())) { |
| 114 | + // FirConverter/fir::ExtendedValue considers all references to boxes |
| 115 | + // as mutable boxes. Outside of OpenMP it doesn't make sense to have a |
| 116 | + // mutable box of an array. Work around this here by loading the |
| 117 | + // reference so it is a normal boxed array. |
| 118 | + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); |
| 119 | + mlir::Location loc = converter.genLocation(hsym.name()); |
| 120 | + fir::ExtendedValue hexv = converter.getSymbolExtendedValue(hsym); |
| 121 | + |
| 122 | + llvm::SmallVector<mlir::Value> extents = |
| 123 | + fir::factory::getExtents(loc, builder, hexv); |
| 124 | + |
| 125 | + // TODO: uniqName, name |
| 126 | + mlir::Value allocVal = |
| 127 | + builder.allocateLocal(loc, arrayTy, /*uniqName=*/"", |
| 128 | + /*name=*/"", extents, /*typeParams=*/{}, |
| 129 | + sym->GetUltimate().attrs().test( |
| 130 | + Fortran::semantics::Attr::TARGET)); |
| 131 | + mlir::Value shape = builder.genShape(loc, extents); |
| 132 | + mlir::Value box = builder.createBox(loc, boxTy, allocVal, shape, |
| 133 | + nullptr, {}, nullptr); |
| 134 | + |
| 135 | + // This can't be a CharArrayBoxValue because otherwise |
| 136 | + // boxTy.getElementType() would be a charcater type. |
| 137 | + // Assume the array element type isn't polymorphic because we are |
| 138 | + // privatizing. |
| 139 | + fir::ExtendedValue newExv = fir::ArrayBoxValue{box, extents}; |
| 140 | + |
| 141 | + converter.bindSymbol(*sym, newExv); |
| 142 | + success = true; |
| 143 | + return; |
| 144 | + } |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + // Normal case: |
| 149 | + success = converter.createHostAssociateVarClone( |
| 150 | + *sym, /*skipDefaultInit=*/isFirstPrivate); |
| 151 | + }(); |
99 | 152 | (void)success; |
100 | 153 | assert(success && "Privatization failed due to existing binding"); |
101 | 154 |
|
|
0 commit comments