Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
14d7115
[flang][OpenMP] MSVC buildbot fix
Meinersbur Aug 14, 2025
cdd8543
Merge remote-tracking branch 'official/main'
Meinersbur Aug 18, 2025
a8c74a7
Merge remote-tracking branch 'official/main'
Meinersbur Aug 19, 2025
871777f
Merge remote-tracking branch 'official/main'
Meinersbur Aug 21, 2025
036ee24
Initial implementation of tiling.
jsjodin Mar 14, 2025
69cfb03
Fix tests and limit the nesting of construct to only tiling.
jsjodin Jun 10, 2025
34888b1
Enable stand-alone tiling, but it gives a warning and converting to s…
jsjodin Jun 10, 2025
79270ac
Add minimal test, remove debug print.
jsjodin Jun 11, 2025
dd943a8
Fix formatting
jsjodin Jun 13, 2025
822fd82
Fix formatting
jsjodin Jun 14, 2025
48bcab4
Fix test.
jsjodin Jun 19, 2025
90320a9
Add more mlir tests. Set collapse value when lowering from SCF to Ope…
jsjodin Jun 20, 2025
d8a976f
Use llvm::SmallVector instead of std::stack
jsjodin Jun 20, 2025
1d133e9
Improve test a bit to make sure IVs are used as expected.
jsjodin Jun 21, 2025
04e73de
Fix comments to clarify canonicalization.
jsjodin Jun 21, 2025
e46d100
Special handling of tile directive when dealing with start end end lo…
jsjodin Jun 21, 2025
9cacf3c
Inline functions.
jsjodin Jun 21, 2025
279ee72
Remove debug code.
jsjodin Jun 23, 2025
ace5268
Reuse loop op lowering, add comment.
jsjodin Jun 23, 2025
57b37f0
Fix formatting.
jsjodin Jun 23, 2025
9ac5cce
Remove curly braces.
jsjodin Jun 23, 2025
7447e37
Avoid attaching the sizes clause to the parent construct, instead fin…
jsjodin Jun 25, 2025
7c7b6f1
Fix formatting
jsjodin Jun 25, 2025
47b75c3
Fix unparse and add a test for nested loop constructs.
jsjodin Jun 26, 2025
2203a35
Use more convenient function to get OpenMPLoopConstruct. Fix comments.
jsjodin Jun 26, 2025
99cb790
Fix formatting.
jsjodin Jun 26, 2025
1ff74ef
Fix merge problems related to the different representations used for …
jsjodin Aug 9, 2025
e49a301
Fix bugs introduced when merging.
jsjodin Aug 9, 2025
9b770ab
Move include
jsjodin Aug 11, 2025
d6ceeb0
Remove unused code. Currently the canonicalize-omp can only handle a …
jsjodin Aug 19, 2025
dd74eac
Address review comments.
jsjodin Aug 22, 2025
432273a
Undo unrelated change.
jsjodin Aug 22, 2025
f182f9c
Merge remote-tracking branch 'official/main'
Meinersbur Aug 25, 2025
eba7709
Merge branch 'main' into HEAD
Meinersbur Aug 25, 2025
5dafa14
Proof-of-concept implementation of loop interchange
Meinersbur Aug 25, 2025
2d09183
Remove stand-alone tiling.
jsjodin Aug 26, 2025
66818b3
Revert unused changes.
jsjodin Aug 26, 2025
f934fa6
Don't do codegen for tiling if it is an inner construct.
jsjodin Aug 26, 2025
8f793a6
successful interchange
Meinersbur Aug 26, 2025
b675870
Remove in-development marker
Meinersbur Aug 26, 2025
9704ddb
Merge branch 'main' into flang_interchange
Meinersbur Aug 26, 2025
2c6fcf5
Reduce change noise
Meinersbur Aug 26, 2025
f266c24
Merge remote-tracking branch 'jsjodin/jleyonberg/tiling' into flang_i…
Meinersbur Aug 26, 2025
70dbb33
Allow tests written in Fortran
Meinersbur Aug 28, 2025
b6d2a7e
Merge remote-tracking branch 'official/main' into openmp_fortran-tests
Meinersbur Aug 28, 2025
9447706
Merge commit 'd452e67ee7b5d17aa040f71d8997abc1a47750e4^' into flang_i…
Meinersbur Sep 10, 2025
f3ec693
Revert "[flang][OpenMP] Enable tiling (#143715)"
Meinersbur Sep 11, 2025
6985ef1
Merge commit '9447706ad8ed' into HEAD
Meinersbur Sep 11, 2025
2510e0f
Backport tblgen changes
Meinersbur Sep 11, 2025
86b7a5c
Merge remote-tracking branch 'github/openmp_fortran-tests' into HEAD
Meinersbur Sep 11, 2025
de3c360
add Fortran testing
Meinersbur Sep 11, 2025
0a5a05c
systematic testing
Meinersbur Sep 11, 2025
e844230
Implement standalone interchange
Meinersbur Sep 11, 2025
0f6ab39
clang-format
Meinersbur Sep 11, 2025
d77da88
Add tests
Meinersbur Sep 11, 2025
2377831
Reduce diff
Meinersbur Sep 11, 2025
8ebe17b
Reduce diff from trunk
Meinersbur Sep 11, 2025
a646a1d
Add tests
Meinersbur Sep 11, 2025
9c7155a
Reduce diff
Meinersbur Sep 11, 2025
ac41158
Reduce diff size
Meinersbur Sep 11, 2025
7a3c46c
Reduce diff size
Meinersbur Sep 11, 2025
6ed3cea
Reduce diff size
Meinersbur Sep 11, 2025
2df55ce
Merge commit 'e75e28ad3c9558c2cca32cd16cd5681b5219ff8d^' into flang_i…
Meinersbur Sep 19, 2025
5e1d0e9
Merge commit 'e75e28ad3c9558c2cca32cd16cd5681b5219ff8d' into flang_in…
Meinersbur Sep 19, 2025
3660ee4
Post-merge fixes
Meinersbur Sep 20, 2025
82ea715
cleanup
Meinersbur Sep 20, 2025
6a8b6cc
cleanup
Meinersbur Sep 20, 2025
b1e9f65
Merge branch 'main' into flang_interchange
Meinersbur Sep 22, 2025
573d910
Merge commit '727aad15f0a897826fc9102b5a090b977c554097^' into flang_i…
Meinersbur Oct 3, 2025
359f3d0
Merge commit '727aad15f0a897826fc9102b5a090b977c554097' into flang_in…
Meinersbur Oct 3, 2025
3cdb4ae
Merge commit 'cd4c5280c73d42fd41819cc8927d00787ade88e0^' into flang_i…
Meinersbur Oct 3, 2025
7a2cc3b
Merge commit 'cd4c5280c73d42fd41819cc8927d00787ade88e0' into flang_in…
Meinersbur Oct 3, 2025
65e7ef9
Merge commit '375f48942b9a3f3fbd82133390af25b6c96f1460^' into flang_i…
Meinersbur Oct 3, 2025
8f13330
Merge commit '375f48942b9a3f3fbd82133390af25b6c96f1460' into flang_in…
Meinersbur Oct 3, 2025
eb98bbe
[OpenMP][test] .f90 -> .F90
Meinersbur Oct 3, 2025
0d7030f
post-merge fix
Meinersbur Oct 4, 2025
a47d559
Merge branch 'main' into flang_interchange
Meinersbur Oct 4, 2025
947f513
Don't XFAIL intdo
Meinersbur Oct 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions flang/include/flang/Lower/AbstractConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,10 @@ class AbstractConverter {

virtual mlir::StateStack &getStateStack() = 0;

virtual void
genPermutatedLoops(llvm::ArrayRef<Fortran::lower::pft::Evaluation *> doStmts,
Fortran::lower::pft::Evaluation *innermostDo) = 0;

private:
/// Options controlling lowering behavior.
const Fortran::lower::LoweringOptions &loweringOptions;
Expand Down
118 changes: 118 additions & 0 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2197,6 +2197,124 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// so no clean-up needs to be generated for these entities.
}

void
genPermutatedLoops(llvm::ArrayRef<Fortran::lower::pft::Evaluation *> doStmts,
Fortran::lower::pft::Evaluation *innermostDo) override {
// Fortran::lower::pft::Evaluation &eval = getEval();
// bool unstructuredContext = eval.lowerAsUnstructured();

llvm::SmallVector<mlir::Block *> headerBlocks;
llvm::SmallVector<IncrementLoopNestInfo, 1> loopInfos;

auto enterLoop = [&](Fortran::lower::pft::Evaluation &eval) {
bool unstructuredContext = eval.lowerAsUnstructured();

// Collect loop nest information.
// Generate begin loop code directly for infinite and while loops.
Fortran::lower::pft::Evaluation &doStmtEval =
eval.getFirstNestedEvaluation();
auto *doStmt = doStmtEval.getIf<Fortran::parser::NonLabelDoStmt>();
const auto &loopControl =
std::get<std::optional<Fortran::parser::LoopControl>>(doStmt->t);
mlir::Block *preheaderBlock = doStmtEval.block;
mlir::Block *beginBlock =
preheaderBlock ? preheaderBlock : builder->getBlock();
auto createNextBeginBlock = [&]() {
// Step beginBlock through unstructured preheader, header, and mask
// blocks, created in outermost to innermost order.
return beginBlock = beginBlock->splitBlock(beginBlock->end());
};
mlir::Block *headerBlock =
unstructuredContext ? createNextBeginBlock() : nullptr;
headerBlocks.push_back(headerBlock);
mlir::Block *bodyBlock = doStmtEval.lexicalSuccessor->block;
mlir::Block *exitBlock = doStmtEval.parentConstruct->constructExit->block;
IncrementLoopNestInfo &incrementLoopNestInfo = loopInfos.emplace_back();
const Fortran::parser::ScalarLogicalExpr *whileCondition = nullptr;
bool infiniteLoop = !loopControl.has_value();
if (infiniteLoop) {
assert(unstructuredContext && "infinite loop must be unstructured");
startBlock(headerBlock);
} else if ((whileCondition =
std::get_if<Fortran::parser::ScalarLogicalExpr>(
&loopControl->u))) {
assert(unstructuredContext && "while loop must be unstructured");
maybeStartBlock(preheaderBlock); // no block or empty block
startBlock(headerBlock);
genConditionalBranch(*whileCondition, bodyBlock, exitBlock);
} else if (const auto *bounds =
std::get_if<Fortran::parser::LoopControl::Bounds>(
&loopControl->u)) {
// Non-concurrent increment loop.
IncrementLoopInfo &info = incrementLoopNestInfo.emplace_back(
*bounds->name.thing.symbol, bounds->lower, bounds->upper,
bounds->step);
if (unstructuredContext) {
maybeStartBlock(preheaderBlock);
info.hasRealControl = info.loopVariableSym->GetType()->IsNumeric(
Fortran::common::TypeCategory::Real);
info.headerBlock = headerBlock;
info.bodyBlock = bodyBlock;
info.exitBlock = exitBlock;
}
} else {
llvm_unreachable("Cannot permute DO CONCURRENT");
}

// Increment loop begin code. (Infinite/while code was already generated.)
if (!infiniteLoop && !whileCondition)
genFIRIncrementLoopBegin(incrementLoopNestInfo, doStmtEval.dirs);
};

auto leaveLoop = [&](Fortran::lower::pft::Evaluation &eval,
mlir::Block *headerBlock,
IncrementLoopNestInfo &incrementLoopNestInfo) {
bool unstructuredContext = eval.lowerAsUnstructured();

Fortran::lower::pft::Evaluation &doStmtEval =
eval.getFirstNestedEvaluation();
auto *doStmt = doStmtEval.getIf<Fortran::parser::NonLabelDoStmt>();

const auto &loopControl =
std::get<std::optional<Fortran::parser::LoopControl>>(doStmt->t);
bool infiniteLoop = !loopControl.has_value();
const Fortran::parser::ScalarLogicalExpr *whileCondition =
std::get_if<Fortran::parser::ScalarLogicalExpr>(&loopControl->u);

auto iter = std::prev(eval.getNestedEvaluations().end());

// An EndDoStmt in unstructured code may start a new block.
Fortran::lower::pft::Evaluation &endDoEval = *iter;
assert(endDoEval.getIf<Fortran::parser::EndDoStmt>() && "no enddo stmt");
if (unstructuredContext)
maybeStartBlock(endDoEval.block);

// Loop end code.
if (infiniteLoop || whileCondition)
genBranch(headerBlock);
else
genFIRIncrementLoopEnd(incrementLoopNestInfo);

// This call may generate a branch in some contexts.
genFIR(endDoEval, unstructuredContext);
};

for (auto l : doStmts)
enterLoop(*l);

// Loop body code.
bool innermostUnstructuredContext = innermostDo->lowerAsUnstructured();

auto iter = innermostDo->getNestedEvaluations().begin();
for (auto end = --innermostDo->getNestedEvaluations().end(); iter != end;
++iter)
genFIR(*iter, innermostUnstructuredContext);

for (auto &&[l, headerBlock, li] :
llvm::zip_equal(doStmts, headerBlocks, loopInfos))
leaveLoop(*l, headerBlock, li);
}

/// Generate FIR for a DO construct. There are six variants:
/// - unstructured infinite and while loops
/// - structured and unstructured increment loops
Expand Down
29 changes: 27 additions & 2 deletions flang/lib/Lower/OpenMP/Decomposer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,39 @@ ConstructQueue buildConstructQueue(
return decompose.output;
}

// from clang
static bool isOpenMPLoopTransformationDirective(llvm::omp::Directive DKind) {
return DKind == llvm::omp::Directive::OMPD_tile ||
DKind == llvm::omp::Directive::OMPD_unroll ||
DKind == llvm::omp::Directive::OMPD_reverse ||
DKind == llvm::omp::Directive::OMPD_interchange ||
DKind == llvm::omp::Directive::OMPD_stripe;
}

llvm::iterator_range<ConstructQueue::const_iterator> getNonTransformQueue(
llvm::iterator_range<ConstructQueue::const_iterator> range) {
// remove trailing loop transformations
auto b = range.begin();
auto e = range.end();
while (e != b) {
auto e2 = e - 1;
if (!isOpenMPLoopTransformationDirective(e2->id))
break;
e = e2;
}

return llvm::make_range(b, e);
}

bool matchLeafSequence(ConstructQueue::const_iterator item,
const ConstructQueue &queue,
llvm::omp::Directive directive) {
llvm::ArrayRef<llvm::omp::Directive> leafDirs =
llvm::omp::getLeafConstructsOrSelf(directive);

for (auto [dir, leaf] :
llvm::zip_longest(leafDirs, llvm::make_range(item, queue.end()))) {
for (auto [dir, leaf] : llvm::zip_longest(
leafDirs,
getNonTransformQueue(llvm::make_range(item, queue.end())))) {
if (!dir.has_value() || !leaf.has_value())
return false;

Expand Down
4 changes: 4 additions & 0 deletions flang/lib/Lower/OpenMP/Decomposer.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ bool isLastItemInQueue(ConstructQueue::const_iterator item,
bool matchLeafSequence(ConstructQueue::const_iterator item,
const ConstructQueue &queue,
llvm::omp::Directive directive);

llvm::iterator_range<ConstructQueue::const_iterator> getNonTransformQueue(
llvm::iterator_range<ConstructQueue::const_iterator> range);

} // namespace Fortran::lower::omp

#endif // FORTRAN_LOWER_OPENMP_DECOMPOSER_H
Loading
Loading