[flang][debug] Describe submodules in the debug info (#225852)
A submodule had no presence of its own in the debug info. Everything it
defined was attributed to the module at the root of its ancestry, so a
debugger showed one module per source file, every one of them carrying
the
name and the line of that ancestor, and it listed the variables of a
submodule as if the ancestor had declared them.
This PR describes a submodule in its own right. There are two
independent strands to it, and they meet only in that both decide which
module an entity is scoped in.
## Thread A: describing the submodule
### Recording the ancestry
A submodule is not a first class entity in FIR. It is not mangled into
the name of anything it declares in a way that distinguishes it from a
[158 lines not shown]
[mlir][XeVM] Stop using `getAttrs()`: explicitly preserve properties when cloning operations (NFC) (#226420)
Pass raw attributes and serialized properties separately through
OperationState when cloning an operation.
Part of #155475
Assisted-by: Codex
[SROA] Pre-split overlapping move slices within a partition (#210061)
When we have an overlapping load and store within an alloca, e.g. due to
a memmove that has been transformed into a load+store by InstCombine,
then currently SROA can't do anything with it. By pre-splitting such
loads and stores we eliminate any overlap between slices and thus SROA
can optimize them.
[mlir] Avoid rewriting unreachable blocks in the greedy driver
A rewrite can disconnect a block after the iteration's initial CFG sweep.
Track reachability through rewriter notifications and skip worklist operations
in unreachable blocks until the next iteration removes them.
Cache reachability per region. Compare the final successors of changed blocks
after each rewrite, preserving the cache for successor-equivalent changes and
block merges that keep surviving blocks reachable. Recompute for other CFG
changes. This avoids repeated full CFG scans during branch canonicalization.
Cover inserted and redirected blocks, blocks connected before rewrite
completion, nested regions, and explicit op-list behavior.
Assisted-by: Codex
[mlir][LLVM] Stop using Operation::getAttrs in custom printers (NCF) (#226418)
At the moment, the assembly format for these operations mixes
discardable and inherent attributes. We should fix it. But for now, stop
using the `getAttrs()` API that is on its way to deprecation.
Part of #155475
Assisted-by: Codex
[AMDGPU] Make setImpSCCDefDead default to true. NFC. (#226406)
In SILowerControlFlow, in helper function setImpSCCDefDead, make
parameter IsDead default to true to match MachineOperand::setIsDead.
[mlir][Quant] Stop using Operation::getAttrs (NFC) (#226413)
Pass raw attributes separately from property storage when recreating an
operation.
Part of #155475
Assisted-by: Codex
[mlir][OpenACC] Stop using getAttrs() and copy function properties separately (NFC) (#226414)
Copy inherent properties and discardable attributes explicitly when
staging a device function.
Part of #155475
Assisted-by: Codex
[mlir][Tensor] Stop using `getAttrs()` and only copy discardable call attributes explicitly (#226412)
Preserve discardable metadata when recreating a typed direct call; its
builder supplies the inherent fields.
Part of #155475
Assisted-by: Codex
emacs: improve module framework
With a lot of help from Showta Ishizaki.
It now supports the features we expect from a module framework:
- allow specifying supported versions
- allow specifying unsupported versions
- reduce conflicts between versions (this is not as important as
e.g. for Python, because the base emacs* and xemacs* packages still
conflict with each other)
- tag the PKGNAME with the version it was built for; so e.g. "magit"
is now called "emacs30-magit" etc. depending on the version it was
built for
- build all supported versions of a module in bulk builds
[11 lines not shown]
[LLD][ELF] Skip symbols to dead mergeable section pieces for --why-live (#226238)
Before this change, `--why-live=*` in "why-live.test" incorrectly prints
`live symbol: b.o:(dead)`.
[flang][NFC] Say which control successors are not incoming branches
The map records branches, not every control successor: a construct
transferring control between its own statements is not a branch
(F2023 11.2.1 p1), so the successors analyzeBranches sets directly are
absent from it. Say so, rather than calling the map a plain inverse.
[flang] Resolve an assigned GO TO's targets from the completed assign map
An assigned GO TO reaches any label ASSIGNed to its variable, and a label
list does not bound that: lowering allows a branch to any ASSIGNed label
whether or not the list names it. Branch analysis only sees the ASSIGNs
preceding the GO TO in program order, so the successors it records, and the
incoming branches derived from them, can be incomplete.
The symbol-to-labels map is complete once branch analysis has finished,
which is when the classification runs. Ask it for the full target set
instead of trusting the recorded successors, so a loop whose assigned GO TO
stays within its body is still recognised.
[flang] Record the evaluations that branch to each evaluation
The PFT records where each branch goes, but not where it comes from, so
asking whether anything branches into a construct means walking the whole
procedure.
Record the reverse edges beside the forward ones, and print them in PFT
dumps so both directions of the branch graph are visible.
[flang] Lower loops whose branching is confined to their body structurally
Such a loop was classified separately by a previous change but still
lowered as unstructured, so its structured form was lost.
Lower it structurally instead, with its body folded into a region that can
hold the branching. The loop keeps its bounds on the op, so it remains
available to whatever transforms or parallelizes it. Only the body is
folded: the loop control statements are emitted as they are for any
structured loop, since a branch from outside may target either of them.
Loops an OpenACC or OpenMP directive owns are lowered the same way, so
they keep their form too.
[flang] Honor the execute-region wrap flag when detecting loop internals
A loop whose branching is confined to its body is lowered with that body
in an scf.execute_region, since the CFG needs more than the single block
fir.do_loop's region admits. With the wrap disabled there is nowhere to
put those blocks, so skip the reclassification and leave the loop
unstructured.
[flang] Keep loops with a non-terminating body unstructured
A loop body that cannot run to completion must not be folded into an
scf.execute_region: the region carries no memory effects, so DCE deletes
it outright, dropping the non-termination and letting execution fall past
the loop. Branches survive that, being terminators.
An infinite DO was already rejected. Follow chains of unconditional GO TOs
as well and reject a body whose chain closes on itself, which is the same
bound the cf.br canonicalization applies to cyclic branches.
[flang] Detect loops whose branching is confined to their body
A DO loop is classified as either structured or unstructured, and a single
raw branch anywhere in its body forces the loop -- and every construct
enclosing it -- onto the unstructured path.
That is stronger than necessary. A loop keeps its structured control flow
as long as its branching neither leaves its body nor enters it from
outside. Classify such a loop separately from a fully unstructured one.
This only classifies: lowering is unchanged. PFT dumps mark the new
classification with '~', which is what the tests key on.
[flang][Test] Cover the lowering of loops with a non-terminating body
A previous change leaves such a loop unstructured. Check what that produces:
the cycle survives as a block branching to itself, no fir.do_loop is emitted
for the loop control, and a loop that only needs a block of its own still
gets the structured form with its body in a region.