13#ifndef FORTRAN_LOWER_ITERATIONSPACE_H
14#define FORTRAN_LOWER_ITERATIONSPACE_H
16#include "flang/Evaluate/tools.h"
17#include "flang/Lower/StatementContext.h"
18#include "flang/Lower/SymbolMap.h"
19#include "flang/Optimizer/Builder/FIRBuilder.h"
35using FrontEndExpr =
const evaluate::Expr<evaluate::SomeType> *;
36using FrontEndSymbol =
const semantics::Symbol *;
38class AbstractConverter;
53 llvm::iterator_range<A> range)
54 : inArg{inArg}, outRes{outRes}, indices{range.begin(), range.end()} {}
58 : inArg(from.inArg), outRes(from.outRes), element(from.element),
66 : inArg(from.inArg), outRes(from.outRes), element(from.element) {
67 indices.assign(prefix.begin(), prefix.end());
68 indices.append(from.indices.begin(), from.indices.end());
69 indices.append(suffix.begin(), suffix.end());
72 bool empty()
const {
return indices.empty(); }
88 mlir::Value iterValue(std::size_t i)
const {
89 assert(i < indices.size());
95 assert(i < indices.size());
100 indices.assign(vals.begin(), vals.end());
103 void insertIndexValue(std::size_t i, mlir::Value av) {
104 assert(i <= indices.size());
105 indices.insert(indices.begin() + i, av);
111 assert(!
fir::getBase(element) &&
"result element already set");
125 void clearIndices() { indices.clear(); }
134using GenerateElementalArrayFunc =
140 bool empty()
const {
return stack.empty(); }
142 void growStack() { stack.push_back(A{}); }
146 vmap.insert({e, std::move(fun)});
152 bind(e, std::move(fun));
158 llvm::report_fatal_error(
159 "evaluate::Expr is not in the map of lowered mask expressions");
160 return vmap.lookup(e);
183 llvm::DenseMap<FrontEndExpr, GenerateElementalArrayFunc> vmap;
188 StatementContext stmtCtx;
191class ImplicitIterSpace;
192llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const ImplicitIterSpace &);
210 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
213 LLVM_DUMP_METHOD
void dump()
const;
217 getMasks().back().push_back(e);
222 for (
size_t i = 1, d = getMasks().size(); i < d; ++i)
223 maskList.append(getMasks()[i].begin(), getMasks()[i].end());
230 mlir::Value header) {
231 maskVarMap.try_emplace(exp, std::make_tuple(var, shape, header));
237 return std::get<0>(maskVarMap.lookup(exp));
243 return std::get<1>(maskVarMap.lookup(exp));
247 return std::get<2>(maskVarMap.lookup(exp));
267 llvm::DenseMap<FrontEndExpr,
268 std::tuple<mlir::Value, mlir::Value, mlir::Value>>
272class ExplicitIterSpace;
273llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const ExplicitIterSpace &);
283 ExplicitIterSpace &esp);
284using ExplicitSpaceArrayBases =
285 std::variant<FrontEndSymbol,
const evaluate::Component *,
286 const evaluate::ArrayRef *>;
288unsigned getHashValue(
const ExplicitSpaceArrayBases &x);
289bool isEqual(
const ExplicitSpaceArrayBases &x,
290 const ExplicitSpaceArrayBases &y);
296struct DenseMapInfo<
Fortran::lower::ExplicitSpaceArrayBases> {
297 static inline Fortran::lower::ExplicitSpaceArrayBases getEmptyKey() {
300 static inline Fortran::lower::ExplicitSpaceArrayBases getTombstoneKey() {
304 getHashValue(
const Fortran::lower::ExplicitSpaceArrayBases &v) {
305 return Fortran::lower::getHashValue(v);
307 static bool isEqual(
const Fortran::lower::ExplicitSpaceArrayBases &lhs,
308 const Fortran::lower::ExplicitSpaceArrayBases &rhs) {
309 return Fortran::lower::isEqual(lhs, rhs);
329 std::tuple<FrontEndSymbol, FrontEndExpr, FrontEndExpr, FrontEndExpr>;
330 using ConcurrentSpec =
331 std::pair<llvm::SmallVector<IterSpaceDim>,
FrontEndExpr>;
332 using ArrayBases = ExplicitSpaceArrayBases;
342 bool isActive()
const {
return forallContextOpen != 0; }
374 void enter() { forallContextOpen++; }
379 void pushLoopNest(std::function<
void()> lambda) {
380 ccLoopNest.push_back(lambda);
389 for (
auto &arg : args)
390 innerArgs.push_back(arg);
404 assert(offset < innerArgs.size());
405 innerArgs[offset] = val;
411 for (
auto &arg : innerArgs)
412 result.push_back(arg.getType());
418 void bindLoad(ArrayBases base, fir::ArrayLoadOp load) {
419 loadBindings.try_emplace(std::move(base), load);
422 fir::ArrayLoadOp findBinding(
const ArrayBases &base) {
423 return loadBindings.lookup(base);
429 bool isLHS(fir::ArrayLoadOp load) {
437 return innerArgs[*opt];
438 llvm_unreachable(
"array load argument not found");
441 size_t argPosition(mlir::Value arg) {
442 for (
auto i : llvm::enumerate(innerArgs))
443 if (arg == i.value())
445 llvm_unreachable(
"inner argument value was not found");
448 std::optional<fir::ArrayLoadOp> getLhsLoad(
size_t i) {
449 assert(i < lhsBases.size());
450 if (lhsBases[counter])
451 return findBinding(*lhsBases[counter]);
457 assert(outerLoop.has_value());
466 for (
auto &lambda : ccLoopNest)
479 bool isOutermostForall()
const {
480 assert(forallContextOpen);
481 return forallContextOpen == 1;
497 LLVM_DUMP_METHOD
void dump()
const;
500 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
501 const ExplicitIterSpace &);
507 loopStack.push_back(loops);
510 void clearLoops() { loopStack.clear(); }
518 void conditionalCleanup();
520 StatementContext outerContext;
526 llvm::DenseMap<ArrayBases, fir::ArrayLoadOp> loadBindings;
532 StatementContext stmtCtx;
535 std::optional<fir::DoLoopOp> outerLoop;
538 std::size_t forallContextOpen = 0;
539 std::size_t counter = 0;
547 for (
const auto &sym : exprSyms)
548 if (llvm::is_contained(ctrlSet, &sym.get()))
557 const A &subscripts) {
558 for (
auto &sub : subscripts) {
559 if (
const auto *expr =
560 std::get_if<evaluate::IndirectSubscriptIntegerExpr>(&sub.u))
Definition: AbstractConverter.h:82
Definition: IterationSpace.h:326
StatementContext & stmtContext()
Get the statement context.
Definition: IterationSpace.h:345
void resetInnerArgs()
Reset the outermost array_load arguments to the loop nest.
Definition: IterationSpace.h:394
void popLevel()
Close the construct.
Definition: IterationSpace.cpp:305
void finalizeContext()
Finalize the current body statement context.
Definition: IterationSpace.h:504
mlir::Value findArgumentOfLoad(fir::ArrayLoadOp load)
Definition: IterationSpace.h:435
mlir::ValueRange getInnerArgs() const
Get the inner arguments that correspond to the output arrays.
Definition: IterationSpace.h:384
void setInnerArgs(llvm::ArrayRef< mlir::BlockArgument > args)
Set the inner arguments for the next loop level.
Definition: IterationSpace.h:387
friend void createArrayMergeStores(AbstractConverter &converter, ExplicitIterSpace &esp)
friend void createArrayLoads(AbstractConverter &converter, ExplicitIterSpace &esp, SymMap &symMap)
void resetBindings()
Clear the array_load bindings.
Definition: IterationSpace.h:471
llvm::SmallVector< mlir::Type > innerArgTypes() const
Get the types of the output arrays.
Definition: IterationSpace.h:409
void leave()
Leave a FORALL context.
Definition: IterationSpace.cpp:265
void enter()
Enter a FORALL context.
Definition: IterationSpace.h:374
void genLoopNest()
Generate the explicit loop nest.
Definition: IterationSpace.h:465
void incrementCounter()
Increment the counter value to the next assignment statement.
Definition: IterationSpace.h:477
std::optional< size_t > findArgPosition(fir::ArrayLoadOp load)
load must be a LHS array_load. Returns std::nullopt on error.
Definition: IterationSpace.cpp:326
void bindLoad(ArrayBases base, fir::ArrayLoadOp load)
Definition: IterationSpace.h:418
void pushLevel()
Open a new construct. The analysis phase starts here.
Definition: IterationSpace.cpp:301
void addSymbol(FrontEndSymbol sym)
Add new concurrent header control variable symbol.
Definition: IterationSpace.cpp:271
void setInnerArg(size_t offset, mlir::Value val)
Sets the inner loop argument at position offset to val.
Definition: IterationSpace.h:403
fir::DoLoopOp getOuterLoop()
Return the outermost loop in this FORALL nest.
Definition: IterationSpace.h:456
void setOuterLoop(fir::DoLoopOp loop)
Capture the current outermost loop.
Definition: IterationSpace.h:397
void exprBase(FrontEndExpr x, bool lhs)
Collect array bases from the expression, x.
Definition: IterationSpace.cpp:277
llvm::SmallVector< FrontEndSymbol > collectAllSymbols()
Return all the active control variables on the stack.
Definition: IterationSpace.cpp:339
void endAssign()
Called at the end of a assignment statement.
Definition: IterationSpace.cpp:299
StatementContext & outermostContext()
Return the statement context for the entire, outermost FORALL construct.
Definition: IterationSpace.h:462
bool isActive() const
Definition: IterationSpace.h:342
std::size_t getCounter() const
Get the current counter value.
Definition: IterationSpace.h:474
Definition: IterationSpace.h:205
mlir::Value lookupMaskVariable(FrontEndExpr exp)
Definition: IterationSpace.h:236
mlir::Value lookupMaskShapeBuffer(FrontEndExpr exp)
Definition: IterationSpace.h:242
void addMaskVariable(FrontEndExpr exp, mlir::Value var, mlir::Value shape, mlir::Value header)
Definition: IterationSpace.h:229
Definition: IterationSpace.h:47
mlir::Value getElement() const
Definition: IterationSpace.h:117
IterationSpace(const IterationSpace &from, llvm::ArrayRef< mlir::Value > prefix, llvm::ArrayRef< mlir::Value > suffix)
Definition: IterationSpace.h:63
mlir::Value innerArgument() const
Definition: IterationSpace.h:77
fir::ExtendedValue elementExv() const
Get the element as an extended value.
Definition: IterationSpace.h:123
mlir::Value outerResult() const
Definition: IterationSpace.h:82
llvm::SmallVector< mlir::Value > iterVec() const
Definition: IterationSpace.h:86
void setElement(fir::ExtendedValue &&ele)
Definition: IterationSpace.h:110
void setIndexValue(std::size_t i, mlir::Value v)
Set (rewrite) the Value at a given index.
Definition: IterationSpace.h:94
Definition: IterationSpace.h:138
bool isLowered(FrontEndExpr e) const
Has the front-end expression, e, been lowered and bound?
Definition: IterationSpace.h:164
void rebind(FrontEndExpr e, GenerateElementalArrayFunc &&fun)
Replace the binding of front-end expression e with a new closure.
Definition: IterationSpace.h:150
void bind(FrontEndExpr e, GenerateElementalArrayFunc &&fun)
Bind a front-end expression to a closure.
Definition: IterationSpace.h:145
GenerateElementalArrayFunc getBoundClosure(FrontEndExpr e) const
Get the closure bound to the front-end expression, e.
Definition: IterationSpace.h:156
Definition: StatementContext.h:46
void finalizeAndReset()
Make cleanup calls. Clear the stack top list.
Definition: StatementContext.h:90
Definition: SymbolMap.h:146
Definition: BoxValue.h:478
Definition: FIRBuilder.h:55
Definition: AbstractConverter.h:59
bool symbolSetsIntersect(llvm::ArrayRef< FrontEndSymbol > ctrlSet, const A &exprSyms)
Definition: IterationSpace.h:545
void createArrayMergeStores(AbstractConverter &converter, ExplicitIterSpace &esp)
Definition: ConvertExpr.cpp:7689
bool symbolsIntersectSubscripts(llvm::ArrayRef< FrontEndSymbol > ctrlSet, const A &subscripts)
Definition: IterationSpace.h:556
void createArrayLoads(AbstractConverter &converter, ExplicitIterSpace &esp, SymMap &symMap)
Definition: ConvertExpr.cpp:7667
Definition: bit-population-count.h:20
mlir::Value getBase(const ExtendedValue &exv)
Definition: BoxValue.cpp:21