This is an archive of the discontinued LLVM Phabricator instance.

[flang] do not merge block after lowering
ClosedPublic

Authored by jeanPerier on Jun 27 2023, 5:00 AM.

Details

Summary

Lowering relies on dead code generation / unreachable block deletion
to delete some code that is potentially invalid.

However, calling mlir::simplifyRegion also merges block, which may
promote SSA values to block arguments. Not all FIR types are intended
to be block arguments.
The added test shows an example where block merging led to
fir.shape<> being block arguments (and a failure later in codegen).

Diff Detail

Event Timeline

jeanPerier created this revision.Jun 27 2023, 5:00 AM
jeanPerier requested review of this revision.Jun 27 2023, 5:00 AM
This revision is now accepted and ready to land.Jun 27 2023, 8:07 AM

Does block coalescing still happen later in the compilation pipeline? That's a nice optimization that we don't want to completely lose.

flang/lib/Lower/Bridge.cpp
4181

Is this FIXME comment (still) valid?

Does block coalescing still happen later in the compilation pipeline? That's a nice optimization that we don't want to completely lose.

It will still happen in LLVM after MLIR depending on what optimization levels are set.

If we want it at the MLIR level, we will need to add options to the MLIR one so that it has some sort of idea of the cost of merging blocks (creating block arguments implies forcing the codegen of the related type to some runtime representation. Depending on the SSA type this may or may not be cheap. So the MLIR pass should be provided some kind of interface to decide whether or not block merging is profitable).
Or we will need to share the some logic with MLIR but do our own pass.

So far I am assuming that LLVM is able to do a good job for simple small blocks/extra jumps and that we do not really need to do this at the MLIR level.

flang/lib/Lower/Bridge.cpp
4181

It is not recommended by MLIR to use IRRewriter directly, that is why I am leaving it. But I do not see us changing this anytime soon.

vdonaldson accepted this revision.Jun 27 2023, 9:49 AM

Thanks for the explanations. Looks ok to me.

tblah accepted this revision.Jun 27 2023, 9:51 AM

LGTM

This revision was automatically updated to reflect the committed changes.

Does block coalescing still happen later in the compilation pipeline? That's a nice optimization that we don't want to completely lose.

It will still happen in LLVM after MLIR depending on what optimization levels are set.

If we want it at the MLIR level, we will need to add options to the MLIR one so that it has some sort of idea of the cost of merging blocks (creating block arguments implies forcing the codegen of the related type to some runtime representation. Depending on the SSA type this may or may not be cheap. So the MLIR pass should be provided some kind of interface to decide whether or not block merging is profitable).
Or we will need to share the some logic with MLIR but do our own pass.

So far I am assuming that LLVM is able to do a good job for simple small blocks/extra jumps and that we do not really need to do this at the MLIR level.

Canonicalization can also merge blocks. Would we run into the same issue (with block arguments) there?