This is an archive of the discontinued LLVM Phabricator instance.

[Flang] Add support for lowering the goto statement
ClosedPublic

Authored by kiranchandramohan on Feb 4 2022, 2:58 AM.

Details

Summary

This patch adds support for lowering the Fortran goto statement from
parse-tree to MLIR. The goto statement in Fortran is a form of
unstructured control flow. The statement transfers control to the
code starting at the label specified in the statement. This can be
faithfully represented in MLIR by a branch instruction.

To assist the lowering of code with unstructured control flow, blocks
are created in advance and associated with the relevant pre-fir tree
evaluations.

This is part of the upstreaming effort from the fir-dev branch in [1].

[1] https://github.com/flang-compiler/f18-llvm-project

Originally written by:
Co-authored-by: V Donaldson <vdonaldson@nvidia.com>
Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>

Diff Detail

Event Timeline

kiranchandramohan requested review of this revision.Feb 4 2022, 2:58 AM
kiranchandramohan edited the summary of this revision. (Show Details)Feb 4 2022, 2:59 AM
awarzynski added inline comments.Feb 4 2022, 4:03 AM
flang/lib/Lower/Bridge.cpp
137

[nit] Could you add a message here?

199–201

Otherwise you might be setting the insertion point more than once, right?

200

Wouldn't genFIRBranch(newBlock) above create a terminator? So that this if condition is always true?

254–263

I don't fully follow this comment. For example, it mentions "global" and "local" blocks, but there's no mention of "global" or "local" in the actual code. Perhaps that's just me?

Thanks @awarzynski for the comments.

flang/lib/Lower/Bridge.cpp
137

Will do.

199–201

As mentioned in the previous comment this change will change the block on which the function blockIsUnterminated will be called.

200

Note the setting of insertion point to the newBlock in the line above. So these two are called for different blocks.
I can add a comment if that helps. I was also a bit confused and had to read again.

254–263

The comment just says what kind (= global) of blocks are created here. Blocks are either created due to explicit control-flow (goto like statements) or due to implicit control flow (like the back edges of loops).

They are called global because they can be target of other branch instructions, whereas local blocks are targets of implicit branches that are inside a construct.

Note: I also had to read it twice. But not sure whether the above helps or not.

clementval accepted this revision.Feb 4 2022, 5:16 AM

Thanks for the help. LG

This revision is now accepted and ready to land.Feb 4 2022, 5:16 AM

Thanks for all the answers, Kiran! Accepting as in, all my suggestions are nits.

flang/lib/Lower/Bridge.cpp
200

Ah, now I see, thanks! getFIRBranch updates the current block. builder->setInsertionPointToStart updates the builder. When reading this function I just assumed that only the current block is updated. My bad.

I can add a comment if that helps.

It would be nice, yes. Not a blocker though!

254–263

Thanks for clarifying, Kiran! I totally missed that from the comment. Perhaps createEmptyGlobalBlocks instead of createEmptyBlocks would make more sense?

awarzynski accepted this revision.Feb 4 2022, 7:32 AM
vdonaldson accepted this revision.Feb 4 2022, 9:34 AM
schweitz accepted this revision.Feb 4 2022, 2:05 PM

Rebase, add message with assert, add comment.