Supporting function pointers and components in lowering

Hi!

I have noticed that there is no support for any kind of function references, pointer, components in the lowering part right now. And also it is not implemented in fir-dev branch of f18 repository. So it should be implemented from scratch.

I’d like to implement and contribute it to the upstream. I’ve been trying to come up with some kind of prototype for a few past days, yet I couldn’t make something that would work.

So, is there any notes on this? What should I do first? What do I have to consider?

Any tips are appreciated!

Procedure pointers are a Fortran 2003 feature with extensions in Fortran 2008. As you might know the current focus is on finishing the codegen for Fortran 95, so this has not yet been high priority.

There is some work for supporting procedure pointers in FIR. These include FIR operations like emboxproc, unboxproc, boxproc_host and the type boxproc. The conversion of these operations to LLVM are all marked as TODO in llvm-project/flang but there exists initial prototype implementation in fir-dev in flang/lib/Optimizer/CodeGen/CodeGen.cpp. This is probably not complete and will need further work.

Eric discussed this a bit in ⚙ D113879 [Flang] Notify conversion failure for Proc ops, types.

fir.boxproc most likely needs some more work. I don’t think it has been used, so it’s more of a placeholder.

It is ultimately intended for creating thunks at runtime to implement function pointers. In Fortran, we can have “normal” function pointers and function pointers that must adjust to the calling context as the callee requires access to the host activation on the stack. The boxproc is an abstraction that lets one bind the function pointer and the pointer to the host’s data.

I suspect that the intent was something like ptr<struct<ptr, ptr>>.

The codegen to build the thunk using the LLVM trampoline intrinsics (LLVM Language Reference Manual — LLVM 15.0.0git documentation) should be completed here.

Please wait for a more informed answer from the FIR team before proceeding.

Thank you for the pointers, @kiranchandramohan! They really helped me to proceed with a prototype implementation.

I have submitted the draft: ⚙ D127490 Implement procedure components & theirs assignment (wip)
Basically, it implements:

  • procedure components in derived types generated as !fir.boxproc<() -> ()> where () -> () is replaced with an actual signature
  • assignments of procedures to procedure components

Both of these “features” are only for the PFT → FIR lowering.

This allows to compile the following code to MLIR:

The main point was to lower program main.

Does the lowering seems correct?

According to the test suite, pointer components of derived type are converted to !fir.box<!fir.ptr<T>>. so this type

  type real_p0
    real, pointer :: p
  end type

is converted to !fir.type<_QMpcompTreal_p0{p:!fir.box<!fir.ptr<f32>>}>.
But I assumed that we do not need to add the !fir.ptr past when we deal with procedures components. Is this correct?
Also, should we ptrize regular procedure pointer variables?

Nice to see that you are able to make some progress here. I haven’t had a chance to look into the technical details here. I believe we have some non-technical issues,

  1. The FIR team is currently adding TODOs (fail with hard todo error) for all features which are in Fortran 2003 and above and ensuring the compiler generates correct code for Fortran 95 and earlier standards.
  2. For the procedure pointer patch to be accepted now, it has to be rock-solid and cover all the cases.
  3. You might have to try out a few things and then finally submit an RFC to handle the procedure-pointers. For this you might have to try out the entire flow from Fortran to LLVM IR.
  4. There will probably be a delay in reviewing this patch and approving it due to issues in 1.

I’d like to give it a shot. But my lack of in-depth experience with Flang and FIR particularly makes it harder.

Is there some documentation or discussion about how the lowering to MLIR has to be implemented?
Is there someone who can answer my technical & design questions from the FIR team? I noticed that @clementval committed a lot near procedure pointers TODOs.

Sorry, I don’t have much to say unless spending more time on this.