Skip to content

Commit

Permalink
[flang][hlfir] Generate temporary storage in Forall/Where [1/2]
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jeanPerier committed May 25, 2023
1 parent 116a31e commit d757811
Show file tree
Hide file tree
Showing 6 changed files with 795 additions and 65 deletions.
47 changes: 47 additions & 0 deletions flang/include/flang/Optimizer/Builder/TemporaryStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,52 @@ class HomogeneousScalarStack {
/// Temporary storage.
mlir::Value temp;
};

/// Structure to hold the value of a single entity.
class SimpleCopy {
public:
SimpleCopy(mlir::Location loc, fir::FirOpBuilder &builder,
hlfir::Entity source, llvm::StringRef tempName);

void pushValue(mlir::Location loc, fir::FirOpBuilder &builder,
mlir::Value value) {
assert(false && "must not be called: value already set");
}
void resetFetchPosition(mlir::Location loc, fir::FirOpBuilder &builder){};
mlir::Value fetch(mlir::Location loc, fir::FirOpBuilder &builder) {
return copy.getBase();
}
void destroy(mlir::Location loc, fir::FirOpBuilder &builder);

public:
/// Temporary storage for the copy.
hlfir::AssociateOp copy;
};

/// Generic wrapper over the different sorts of temporary storages.
class TemporaryStorage {
public:
template <typename T>
TemporaryStorage(T &&impl) : impl{std::forward<T>(impl)} {}

void pushValue(mlir::Location loc, fir::FirOpBuilder &builder,
mlir::Value value) {
std::visit([&](auto &temp) { temp.pushValue(loc, builder, value); }, impl);
}
void resetFetchPosition(mlir::Location loc, fir::FirOpBuilder &builder) {
std::visit([&](auto &temp) { temp.resetFetchPosition(loc, builder); },
impl);
}
mlir::Value fetch(mlir::Location loc, fir::FirOpBuilder &builder) {
return std::visit([&](auto &temp) { return temp.fetch(loc, builder); },
impl);
}
void destroy(mlir::Location loc, fir::FirOpBuilder &builder) {
std::visit([&](auto &temp) { temp.destroy(loc, builder); }, impl);
}

private:
std::variant<HomogeneousScalarStack, SimpleCopy> impl;
};
} // namespace fir::factory
#endif // FORTRAN_OPTIMIZER_BUILDER_TEMPORARYSTORAGE_H
23 changes: 22 additions & 1 deletion flang/lib/Optimizer/Builder/TemporaryStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
//===----------------------------------------------------------------------===//

#include "flang/Optimizer/Builder/TemporaryStorage.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"

Expand Down Expand Up @@ -133,3 +133,24 @@ hlfir::Entity fir::factory::HomogeneousScalarStack::moveStackAsArrayExpr(
auto hlfirExpr = builder.create<hlfir::AsExprOp>(loc, temp, mustFree);
return hlfir::Entity{hlfirExpr};
}

//===----------------------------------------------------------------------===//
// fir::factory::SimpleCopy implementation.
//===----------------------------------------------------------------------===//

fir::factory::SimpleCopy::SimpleCopy(mlir::Location loc,
fir::FirOpBuilder &builder,
hlfir::Entity source,
llvm::StringRef tempName) {
// Use hlfir.as_expr and hlfir.associate to create a copy and leave
// bufferization deals with how best to make the copy.
if (source.isVariable())
source = hlfir::Entity{builder.create<hlfir::AsExprOp>(loc, source)};
copy = hlfir::genAssociateExpr(loc, builder, source,
source.getFortranElementType(), tempName);
}

void fir::factory::SimpleCopy::destroy(mlir::Location loc,
fir::FirOpBuilder &builder) {
builder.create<hlfir::EndAssociateOp>(loc, copy);
}
Loading

0 comments on commit d757811

Please sign in to comment.