================ @@ -361,6 +361,64 @@ void sinkLoopIVArgs(mlir::ConversionPatternRewriter &rewriter, ++idx; } } + +/// Collects values that are local to a loop: "loop-local values". A loop-local +/// value is one that is used exclusively inside the loop but allocated outside +/// of it. This usually corresponds to temporary values that are used inside the +/// loop body for initialzing other variables for example. +/// +/// See `flang/test/Transforms/DoConcurrent/locally_destroyed_temp.f90` for an +/// example of why we need this. +/// +/// \param [in] doLoop - the loop within which the function searches for values +/// used exclusively inside. +/// +/// \param [out] locals - the list of loop-local values detected for \p doLoop. +void collectLoopLocalValues(fir::DoLoopOp doLoop, + llvm::SetVector<mlir::Value> &locals) { + doLoop.walk([&](mlir::Operation *op) { + for (mlir::Value operand : op->getOperands()) { + if (locals.contains(operand)) + continue; + + bool isLocal = true; + + if (!mlir::isa_and_present<fir::AllocaOp>(operand.getDefiningOp())) + continue; + + // Values defined inside the loop are not interesting since they do not + // need to be localized. + if (doLoop->isAncestor(operand.getDefiningOp())) + continue; + + for (auto *user : operand.getUsers()) { + if (!doLoop->isAncestor(user)) { + isLocal = false; + break; + } + } + + if (isLocal) + locals.insert(operand); ---------------- skatrak wrote:
Nit: I think something like this might be a bit more concise, but feel free to disagree. In that case, the `isLocal` declaration might be good to move it closer to the loop. ```suggestion auto users = operand.getUsers(); if (llvm::find_if(users, [&](mlir::Operation *user) { return !doLoop->isAncestor(user); }) == users.end()) locals.insert(operand); ``` https://github.com/llvm/llvm-project/pull/127635 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits