This is an archive of the discontinued LLVM Phabricator instance.

[WIP][Flang] Extracting internal constants from scalar literals
Needs ReviewPublic

Authored by d-smirnov on Jul 19 2023, 3:04 AM.

Details

Summary

Constants actual arguments in function/subroutine calls are currently lowered as allocas + store. This can sometimes inhibit LTO and the constant will not be propagated to the called function. Particularly in cases where the function/subroutine call happens inside a condition.

This patch changes the lowering of these constant actual arguments to a global constant + fir.address_of_op. This lowering makes it easier for LTO to propagate the constant.

Patch benefits spec2017/503.bwaves_r with LTO.

Diff Detail

Event Timeline

d-smirnov created this revision.Jul 19 2023, 3:04 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJul 19 2023, 3:04 AM
Herald added a subscriber: mehdi_amini. · View Herald Transcript
d-smirnov requested review of this revision.Jul 19 2023, 3:04 AM
kiranchandramohan retitled this revision from [WIP] Extracting internal constants from scalar literals to [WIP][Flang] Extracting internal constants from scalar literals.Jul 19 2023, 4:39 AM
kiranchandramohan edited the summary of this revision. (Show Details)
tschuett added inline comments.
flang/lib/Lower/ConvertExpr.cpp
3040 ↗(On Diff #541929)

Independent of whether this is a cute solution or the root cause is somewhere else. This atomic variable seems to be dead.

flang/lib/Lower/ConvertExpr.cpp
3010 ↗(On Diff #541929)

What is the case here? Do you have a test?

3021 ↗(On Diff #541929)

getUniqueLitName seems to be already doing this and maintaining a uniqueLitId, so why is it required to do this again?

3040 ↗(On Diff #541929)

It is used above in line 3021.

3040 ↗(On Diff #541929)

Why does this need to an atomic?

tschuett added inline comments.Jul 19 2023, 8:13 AM
flang/lib/Lower/ConvertExpr.cpp
3040 ↗(On Diff #541929)

It is a variable declaration and hides the variable at line 3021.

Why can't you pass constant arguments directly as SSA values to call operations? Why did you go though memory/allocas?

kiranchandramohan requested changes to this revision.Jul 19 2023, 9:30 AM
kiranchandramohan added a subscriber: vzakhari.

Why can't you pass constant arguments directly as SSA values to call operations? Why did you go though memory/allocas?

Because the called function expects that due to copy-in copy-out semantics.

We discussed this in the call today. There is general agreement that is a good change. But there are also concerns that there could be situations where it might break existing code. The recommendation from @vzakhari is to do this in a pass.

This revision now requires changes to proceed.Jul 19 2023, 9:30 AM

Passing by reference/pointer is fine, but allocas seem to be cleaner than global constants. I bet the root issue is somewhere else.

Passing by reference/pointer is fine, but allocas seem to be cleaner than global constants. I bet the root issue is somewhere else.

From what we saw the Dead Argument Elimination pass (llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp) can kick in and remove the constant arguments that are passed if they are represented as a global constant. I believe this is because the called function can access the constant even without the argument and hence the argument is effectively dead. This is not possible with the allocas since allocas do not have visibility outside the calling function. This is the pass where we see a difference between the global constant and the alloca constant approach. We can think of providing TBAA information to constant allocas to distinguish it from other allocas, but it was not immediately clear whether the pass makes use of this information.

d-smirnov updated this revision to Diff 556447.Sep 11 2023, 9:57 AM

Separate pass now

d-smirnov updated this revision to Diff 557795.Oct 19 2023, 2:00 PM

Updated + minor bugfix