This is an archive of the discontinued LLVM Phabricator instance.

[flang][driver] Re-organise the code-gen actions (nfc)
ClosedPublic

Authored by awarzynski on Apr 29 2022, 2:43 AM.

Details

Summary

All frontend actions that generate code (MLIR, LLVM IR/BC,
Assembly/Object Code) are re-factored as essentially one action,
CodeGenAction, with minor specialisations. To facilate all this,
CodeGenAction is extended to hold TargetMachine and backend action
type (MLIR vs LLVM IR vs LLVM BC vs Assembly vs Object Code).

CodeGenAction is no longer a pure abstract class and the
corresponding ExecuteAction is implemented so that it covers all use
cases. All this allows a much better code re-use.

Key functionality is extracted into some helpful hooks:

  • SetUpTargetMachine
  • GetOutputStream
  • EmitObjectCodeHelper
  • EmitBCHelper

I hope that this clarifies the overall structure. I suspect that we may
need to revisit this again as the functionality grows in complexity.

Depends on D124664

Diff Detail

Event Timeline

awarzynski created this revision.Apr 29 2022, 2:43 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptApr 29 2022, 2:43 AM
awarzynski requested review of this revision.Apr 29 2022, 2:43 AM

@rovka That's a bit "bolder" change compared to what you suggested in https://reviews.llvm.org/D123211. WDYT?

I have only nits and questions about the patch:

flang/include/flang/Frontend/FrontendActions.h
175–179

Do we really need Backend_ prefix here? Seems obsolete.

flang/lib/Frontend/FrontendActions.cpp
419

Why not to define the destructor in the header?

517–540

I'd suggest to unify variable names in the function

539

I'm not quite familiar with legacy pass manager, so I have a question: will CodeGenPasses delete the pass that created here?

@unterumarmung , thanks for taking a look!

flang/include/flang/Frontend/FrontendActions.h
175–179

Naming is hard :)

  1. Consistency with Clang means that navigation will be easier for people familiar with it. It also means that design-wise the drivers are similar.
  2. These actions use either LLVM or MLIR to run the final phase of code-gen/lowering. From the point of view of Flang, LLVM and MLIR are backends for the Flang Fortran frontend. So, these actions are "backend" actions.

Also, note that e.g. EmitObj is also defined in FrontendOptions.h. It's a completely different enum (so technically there would be no name clash), but wouldn't unique names be a bit less ambiguous?

flang/lib/Frontend/FrontendActions.cpp
419

Good question!

When you define a destructor for CodeGenAction in the header file, it will be available in every translation unit that includes that header, e.g. ExecuteCompilerInvocation.cpp. This would mean that the corresponding symbol would be defined in the flangFrontendTool library. However, that's not desirable.

The destructor for CodeGenAction needs to know how to destroy its member variables, e.g.llvm::TargetMachine. So, it depends on the library that defines the corresponding destructor. But flangFrontendTool is meant as a lightweight utility lib. It should only depend on flangFrontend (which defines CodeGenAction) and be oblivious to its implementation details.

That's a lot of text for one line of code! Does it make sense?

517–540

Sadly, the coding style in the driver is a bit of a mix.

We started with Flang's C++ style as that was the only style that was in use in LLVM Flang back then. However, lowering and code-gen that was introduced later uses the MLIR style (from Allocatable.cpp):

// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/

As the driver also depends on Clang and uses various LLVM libs (e.g. for machine code generation), it in fact mixes 3 different styles. Not ideal and a ton of confusing - most/all of my own making!

I like your suggestion, but I'd prefer to address it in a separate patch. In fact, I intend to suggest refactoring the driver to use the MLIR style soon (probably this week). This should fix the consistency in other places too. Would that be OK with you?

539

I don't consider an expert myself :)

Sadly, there's not a single hint in the method declaration. However, there are multiple deletes in LegacyPassManager.cpp. That's a good sign!

I am also assuming that Clang would definitely be doing the right thing: CodeGenPasses.add. llc and opt do the same, see here and here. So based on that, I assume that this is OK.

rovka added inline comments.May 2 2022, 12:48 AM
flang/include/flang/Frontend/FrontendActions.h
175–179

Actually, since this isn't part of a class, I think the coding style says we should use something like CGAT_EmitBlah (although CG_EmitBlah might also be ok). I don't feel strongly either way, so use whatever names you prefer :)

flang/lib/Frontend/FrontendActions.cpp
511–533

Nit: ObjectCode makes me think more about bc and object files than about assembly and object files (I'm not sure MachineCode is much better, since assembly is not technically machine code, but I'm looking for something that suggests that we're running the actual backend passes and generating some kind of machine/target-specific representation).

Also a small comment saying that it only works for Backend_EmitAssembly and Backend_EmitObj would be nice (or better yet, start the body with an assert about that).

556–569
631

Nit: I would move this above the other if, so it's closer to the EmitLL handling.

unterumarmung accepted this revision.May 2 2022, 9:38 AM
unterumarmung added inline comments.
flang/include/flang/Frontend/FrontendActions.h
175–179

@awarzynski, thank you for the explanation! I agree with the chosen naming now.

flang/lib/Frontend/FrontendActions.cpp
419

Sure it does! Thank you for the explanation

517–540

Sure!

539

Seems reasonable!

This revision is now accepted and ready to land.May 2 2022, 9:38 AM
awarzynski added inline comments.May 3 2022, 3:22 AM
flang/include/flang/Frontend/FrontendActions.h
175–179

Actually, since this isn't part of a class, I think the coding style says we should use something like CGAT_EmitBlah (although CG_EmitBlah might also be ok). I don't feel strongly either way, so use whatever names you prefer :)

Glad to see that at least one of us _actually_ read the coding style guideline :)

This clearly needs updating then. I will try BackendActionTy for the enum and then the actual fields can be kept intact. Unless I misunderstood the guideline 🤔 . WDTY?

flang/lib/Frontend/FrontendActions.cpp
511–533

Good points!

I feel that GenerateMachineCode would be a bit too similar to GenerateLLVMIR. But that is a member method that will change the internal state of the corresponding FrontendAction (it sets CodeGenAction::llvmModule). This is a free function though. Let me try GenerateMachineCodeOrAssemblyImpl instead - this way we also make sure that machine-code vs assembly distinction is addressed.

Also a small comment saying that it only works for Backend_EmitAssembly and Backend_EmitObj would be nice (or better yet, start the body with an assert about that).

Will add a comment, an assert and rename to make this limitation clear :)

556–569

Let me try GenerateLLVMBCImpl instead, just to differentiate this a bit from GenerateLLVMIR (see my earlier comment). WDYT?

631

Good point, moved!

awarzynski updated this revision to Diff 426629.May 3 2022, 3:24 AM

Address comments from Diana

Moved some code around, simplified a bit, added comments, renamed CodeGenActionTy as BackendActionTy.

awarzynski updated this revision to Diff 427027.May 4 2022, 8:55 AM

Rebase on top of main

rovka accepted this revision.May 5 2022, 6:13 AM

Just one microscopic issue, otherwise looks great, thanks!

flang/lib/Frontend/FrontendActions.cpp
525

Nit: && "" ? :) Are you going to put a message there? If not you can just remove that part.

awarzynski added inline comments.May 5 2022, 6:22 AM
flang/lib/Frontend/FrontendActions.cpp
525

I swear there used to be some very useful message there before 🤔 :)

Good catch, will update before merging!

This revision was landed with ongoing or failed builds.May 5 2022, 7:06 AM
This revision was automatically updated to reflect the committed changes.