llvm / llvm/llvm-project

[flang] Hoist SIMPLE procedure calls with loop-invariant arguments out of loops

Open
#222,360 1 comment 1 reaction 1 assignee Claimed by @cenewcombe View on GitHub
flang flang:fir-hlfir
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Fortran 2023 `SIMPLE` procedures compute their result solely from their
arguments, with no effects beyond those arguments and no reference to host- or
use-associated data, COMMON, or other external state. That is strictly stronger
than `PURE`, which may still read host- and use-associated data, and it is what
makes a call hoistable: a `SIMPLE` call whose arguments are loop-invariant
produces the same result on every iteration.

Flang does not currently take advantage of this. A `SIMPLE` call in a loop body
is re-evaluated on every iteration even when all of its arguments are invariant.

## Current state

- The FIR `simple` procedure attribute already exists (`FIRAttr.td`), but
lowering never sets it — there is a TODO in `CallInterface.cpp`'s
`getProcedureAttrs`. A `simple` function currently lowers with only
`#fir.proc_attrs`, so the information never reaches the optimizer.
- The FIR/HLFIR LICM pass (added in #173438, enabled above `-O0` in #218703)
does not hoist calls, since it has no way to reason about their side effects.

## Goal

Hoist calls to `SIMPLE` procedures out of loops when their arguments are
loop-invariant. The FIR LICM pass is the natural place for this.

The design is open, but it will need some way to represent the absence of side
effects for a simple call in FIR, plus the conditions under which the pass may
move one. Points that will need working through:

- `SIMPLE` guarantees no effects beyond its arguments, but says nothing about
termination or traps, so hoisting out of a loop that may run zero times needs
care.
- An operand being loop-invariant is not sufficient: memory referenced through
it must also be unmodified within the loop.
- Temporaries materialized inside the loop — result buffers, argument
copy-in/copy-out — may have to move along with the call.
- How widely to expose the no-side-effect property: confining it to LICM is more
conservative than making it visible to CSE and dead-code elimination as well.

## Dependencies

Depends on the `SIMPLE` feature implementation work tracked in #221457.

Assisted-by: Copilot

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.