[flang-commits] [flang] [llvm] [mlir] [openmp] [Flang][OpenMP] Lower scan directive and inscan reduction modifier (PR #206747)
via flang-commits
flang-commits at lists.llvm.org
Thu Jul 23 13:49:13 PDT 2026
================
@@ -670,6 +707,97 @@ findCurrentLoopInfo(LLVM::ModuleTranslation &moduleTranslation) {
return loopInfo;
}
+/// Find the scan loop information structure for the scan loop nest being
+/// translated. It will return a `null` value unless called from the
+/// translation function for a loop wrapper operation after successfully
+/// translating its body.
+static llvm::CanonicalLoopInfo *
+findCurrentScanLoopInfo(LLVM::ModuleTranslation &moduleTranslation) {
+ llvm::CanonicalLoopInfo *scanLoopInfo = nullptr;
+ moduleTranslation.stackWalk<OpenMPLoopInfoStackFrame>(
+ [&](OpenMPLoopInfoStackFrame &frame) {
+ scanLoopInfo = frame.scanloopInfo;
+ return WalkResult::interrupt();
+ });
+ return scanLoopInfo;
+}
+
+/// Find the `ScanInfo` stored on the loop stack frame. Upon encountering an
+/// `inscan` reduction modifier, `scanInfoInitialize` initializes the
+/// `ScanInfo`, which is then used when a `scan` directive is encountered in the
+/// body of the loop nest.
+static llvm::ScanInfo *
+findScanInfo(LLVM::ModuleTranslation &moduleTranslation) {
+ llvm::ScanInfo *scanInfo = nullptr;
+ moduleTranslation.stackWalk<OpenMPLoopInfoStackFrame>(
+ [&](OpenMPLoopInfoStackFrame &frame) {
+ scanInfo = frame.scanInfo;
+ return WalkResult::interrupt();
+ });
+ return scanInfo;
+}
+
+/// The types of reduction variables are used for lowering a `scan` directive
+/// that appears in the body of the loop. The types are stored in the loop frame
+/// when the reduction clause is encountered and used when the `scan` directive
+/// is encountered.
+static llvm::DenseMap<llvm::Value *, llvm::Type *> *
+findReductionVarTypes(LLVM::ModuleTranslation &moduleTranslation) {
+ llvm::DenseMap<llvm::Value *, llvm::Type *> *reductionVarToType = nullptr;
+ moduleTranslation.stackWalk<OpenMPLoopInfoStackFrame>(
+ [&](OpenMPLoopInfoStackFrame &frame) {
+ if (!frame.reductionVarToType)
+ frame.reductionVarToType =
+ std::make_unique<llvm::DenseMap<llvm::Value *, llvm::Type *>>();
+ reductionVarToType = frame.reductionVarToType.get();
+ return WalkResult::interrupt();
+ });
+ return reductionVarToType;
+}
+
+/// Scan reduction requires a shared buffer to be allocated to perform the
+/// reduction. The allocation needs to be done outside the parallel region in
+/// which the scan operation is used.
+static llvm::OpenMPIRBuilder::InsertPointTy
+findParallelAllocaIP(llvm::IRBuilderBase &builder,
----------------
chichunchen wrote:
Orphand worksharing loop seems not handled properly. findParallelAllocaIp() cannot find the enclosing omp.parallel and fallback to the entry block of run_scan.
```
subroutine run_scan(result, x, n)
implicit none
integer :: n, result(n), x, i
!$omp do reduction(inscan, +: x)
do i = 1, n
x = x + 1
!$omp scan inclusive(x)
result(i) = x
end do
!$omp end do
end subroutine
program example
implicit none
integer :: x, result(8)
x = 0
!$omp parallel shared(x, result)
call run_scan(result, x, 8)
!$omp end parallel
end program
```
https://github.com/llvm/llvm-project/pull/206747
More information about the flang-commits
mailing list