Skip to content

Commit d757811

Browse files
committed
[flang][hlfir] Generate temporary storage in Forall/Where [1/2]
Generate temporary storage inline inside WHERE and FORALL when possible. A following patch will use the runtime to cover the generic cases. Reviewed By: vzakhari Differential Revision: https://reviews.llvm.org/D151247
1 parent 116a31e commit d757811

File tree

6 files changed

+795
-65
lines changed

6 files changed

+795
-65
lines changed

flang/include/flang/Optimizer/Builder/TemporaryStorage.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,52 @@ class HomogeneousScalarStack {
9393
/// Temporary storage.
9494
mlir::Value temp;
9595
};
96+
97+
/// Structure to hold the value of a single entity.
98+
class SimpleCopy {
99+
public:
100+
SimpleCopy(mlir::Location loc, fir::FirOpBuilder &builder,
101+
hlfir::Entity source, llvm::StringRef tempName);
102+
103+
void pushValue(mlir::Location loc, fir::FirOpBuilder &builder,
104+
mlir::Value value) {
105+
assert(false && "must not be called: value already set");
106+
}
107+
void resetFetchPosition(mlir::Location loc, fir::FirOpBuilder &builder){};
108+
mlir::Value fetch(mlir::Location loc, fir::FirOpBuilder &builder) {
109+
return copy.getBase();
110+
}
111+
void destroy(mlir::Location loc, fir::FirOpBuilder &builder);
112+
113+
public:
114+
/// Temporary storage for the copy.
115+
hlfir::AssociateOp copy;
116+
};
117+
118+
/// Generic wrapper over the different sorts of temporary storages.
119+
class TemporaryStorage {
120+
public:
121+
template <typename T>
122+
TemporaryStorage(T &&impl) : impl{std::forward<T>(impl)} {}
123+
124+
void pushValue(mlir::Location loc, fir::FirOpBuilder &builder,
125+
mlir::Value value) {
126+
std::visit([&](auto &temp) { temp.pushValue(loc, builder, value); }, impl);
127+
}
128+
void resetFetchPosition(mlir::Location loc, fir::FirOpBuilder &builder) {
129+
std::visit([&](auto &temp) { temp.resetFetchPosition(loc, builder); },
130+
impl);
131+
}
132+
mlir::Value fetch(mlir::Location loc, fir::FirOpBuilder &builder) {
133+
return std::visit([&](auto &temp) { return temp.fetch(loc, builder); },
134+
impl);
135+
}
136+
void destroy(mlir::Location loc, fir::FirOpBuilder &builder) {
137+
std::visit([&](auto &temp) { temp.destroy(loc, builder); }, impl);
138+
}
139+
140+
private:
141+
std::variant<HomogeneousScalarStack, SimpleCopy> impl;
142+
};
96143
} // namespace fir::factory
97144
#endif // FORTRAN_OPTIMIZER_BUILDER_TEMPORARYSTORAGE_H

flang/lib/Optimizer/Builder/TemporaryStorage.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
//===----------------------------------------------------------------------===//
1111

1212
#include "flang/Optimizer/Builder/TemporaryStorage.h"
13+
#include "flang/Optimizer/Builder/FIRBuilder.h"
1314
#include "flang/Optimizer/Builder/HLFIRTools.h"
14-
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
1515
#include "flang/Optimizer/Builder/Todo.h"
1616
#include "flang/Optimizer/HLFIR/HLFIROps.h"
1717

@@ -133,3 +133,24 @@ hlfir::Entity fir::factory::HomogeneousScalarStack::moveStackAsArrayExpr(
133133
auto hlfirExpr = builder.create<hlfir::AsExprOp>(loc, temp, mustFree);
134134
return hlfir::Entity{hlfirExpr};
135135
}
136+
137+
//===----------------------------------------------------------------------===//
138+
// fir::factory::SimpleCopy implementation.
139+
//===----------------------------------------------------------------------===//
140+
141+
fir::factory::SimpleCopy::SimpleCopy(mlir::Location loc,
142+
fir::FirOpBuilder &builder,
143+
hlfir::Entity source,
144+
llvm::StringRef tempName) {
145+
// Use hlfir.as_expr and hlfir.associate to create a copy and leave
146+
// bufferization deals with how best to make the copy.
147+
if (source.isVariable())
148+
source = hlfir::Entity{builder.create<hlfir::AsExprOp>(loc, source)};
149+
copy = hlfir::genAssociateExpr(loc, builder, source,
150+
source.getFortranElementType(), tempName);
151+
}
152+
153+
void fir::factory::SimpleCopy::destroy(mlir::Location loc,
154+
fir::FirOpBuilder &builder) {
155+
builder.create<hlfir::EndAssociateOp>(loc, copy);
156+
}

0 commit comments

Comments
 (0)