[mlir][OpenMP] Allow multi-block omp.iterator regions
Frontends lower a locator inside an omp.iterator region like any other
expression, so the region can contain control flow. For example, Flang
lowers LEN_TRIM in `depend(iterator(i=1:n), in: a(i+len_trim(s)))` to a
loop, and later passes inline SUM or COUNT as loops. After control-flow
conversion the region has several blocks, which the single-block
omp.iterator rejects:
%it = omp.iterator(%i: i64) = (%c1 to %n step %c1) {
llvm.br ^scan(%slen : i64)
^scan(%k: i64): // LEN_TRIM skips trailing blanks
...
llvm.cond_br %blank, ^scan(%km1 : i64), ^done
^done:
... // address of a(i+len_trim(s))
omp.yield(%addr : !llvm.ptr)
} -> !omp.iterated<!llvm.ptr>
Allow the region to have several blocks. Exactly one of them ends in
omp.yield, and every other block branches within the region, as for
omp.private. Translation keeps the single-block path; for multi-block
regions it converts the blocks in dominance order and reads the yielded
value after the yield. OpenMPIRBuilder::createIteratorLoop now branches the
body's single unterminated block to the latch and rejects bodies that
branch out of the loop.
Assisted with Copilot and Claude Opus 5.