[ADT] Reland: Remove CRTP from FoldingSet and ContextualFoldingSet (NFC) (#217058)
This patch relands #216830 with a fix for MSVC build failures.
In the original patch, FoldingSetInfo was defined as a static constexpr
member variable of FoldingSetImpl. On MSVC, instantiating
FoldingSetImpl<T> (e.g. in LLVMContextImpl.h) eagerly evaluates the
static constexpr member variable and its lambdas containing
static_cast<T *>(N). When T is an incomplete type (such as AttributeImpl
forward-declared in LLVMContextImpl.h and compiled in Metadata.cpp),
this
caused MSVC to fail with C2440 because static_cast requires a complete
type.
This patch wraps FoldingSetInfo in a static getFoldingSetInfo() member
function so that instantiation is deferred until the function is
actually
called, such as during InsertNode or FindNodeOrInsertPos.
Assisted-by: Antigravity
[M68k] Use ISD::getSetCCInverse instead of ISD::GlobalISel::getSetCCInverse. NFCI (#216871)
It's odd to use a GlobalISel named function in SelectionDAG code. This
code path isn't exercised by lit, but I think this should be equivalent.
[NewPM] Port ImplicitNullChecks to the new pass manager (#216965)
Adds a newPM pass for ImplicitNullChecks.
- Refactors base logic into an ImplicitNullChecks class
- Renames old pass with the "Legacy" suffix
- Adds the new pass manager pass ImplicitNullChecksPass
- Updates MachinePassRegistry.def, PassBuilder, and CodeGenPassBuilder
- Updated existing .mir tests to also test with the New Pass Manager
Assisted-by: Gemini / Next
[CIR] Handle an empty C++ class in x86_64 callconv lowering (#214742)
CIR lays a C++ empty class out as a record that is nothing but padding,
and isSupportedType rejected every padded record, so any signature
naming one failed the pass with an NYI. Ordinary C++ hits this
constantly through tag dispatch, allocators, and empty bases.
Implement empty C++ class support. Every record member now carries a
kind, so a record holds no data exactly when none of them is marked
data, which `RecordType::isEmptyForABI()` answers and the pass reads. An
empty record then maps with no fields, so the classifier drops it on its
own.
Assisted-by: Cursor / claude-opus-5
[llvm-nm][GOFF] Display archive attributes in GOFF archives through --print-armap
GOFF archive symbol table entries contain an attribute word in addition
to the archive member offset. The low three bits describe whether the symbol is
64-bit, uses XPLink, or belongs to the WSA namespace (which was briefly mentioned
in e2c8fa09872cfacba7f73599dcf8557971ebe865).
This patch extends `llvm-nm --print-armap` to print the attribute value (in hex) and
its decoded description beside a symbol and its corresponding member when processing
a GOFF archive. This will functionality will be used to help validate full support for writing
GOFF archives in a subsequent llvm-ar patch.
The output for non-z/OS archives is unchanged.
[BOLT] Skip data-hole filling unless data reordering is enabled
BinaryContext::postProcessSymbolTable unconditionally called
fixBinaryDataHoles(), which walks every allocatable section and, for
each gap in its address space, either grows a zero-sized data symbol
or creates a synthetic "HOLEat" BinaryData (plus an MCSymbol and
GlobalSymbols/BinaryDataMap entries). This machinery was introduced
(0e4d86bf, 2017) for one purpose: to give static data reordering
(-reorder-data) a movable object covering every byte of a section. It
has no other consumer.
On a large binary, these synthetic objects are live from
buildFunctionsCFG through the end of the run and, at the RSS peak
(during debug info rewriting), fixBinaryDataHoles accounted for 1669
MB (2.5%) of peak RSS -- memory spent entirely for a feature that is
off by default.
Gate fixBinaryDataHoles() (and the zero-sized-symbol validation loop
that presumes it ran) on a non-empty opts::ReorderData, keeping
generateSymbolHashes() unconditional.
[BOLT] Key GlobalSymbols on MCContext-owned names to reduce memory (#214891)
BinaryContext::registerNameAtAddress registers every symbol name twice.
It first calls MCContext::getOrCreateSymbol(Name), which interns the
name in MCContext's symbol table (the MCSymbol owns the string via its
table entry). It then also stored the name in the GlobalSymbols map,
which was a StringMap<BinaryData *>. StringMap owns its keys, so each
global name was duplicated: one copy in MCContext and a second copy in
GlobalSymbols. Both grow with the number of symbols and, for large
binaries with long mangled names, this duplication is a meaningful
source of memory use during file object discovery.
This change makes MCContext the single owner of these name strings and
have GlobalSymbols merely reference them. GlobalSymbols becomes a
DenseMap<StringRef, BinaryData *> keyed on the MCContext-owned name
(MCSymbol::getName() of the symbol just created/looked up). No string is
copied into the map: each entry is a fixed-size (StringRef, pointer)
pair regardless of name length. Lookups (getBinaryDataByName, count) are
unchanged because DenseMap<StringRef> hashes and compares by content,
[7 lines not shown]
[AMDGPU] Correct DS FIFO buffer size semantics
There was some ambiguity in how buffersize 0 and 1 are handled. The
correct semantics are:
- `BufferSize == 0`: unlimited, no FIFO stall
- `BufferSize == 1`: unbuffered, only one instruction in flight
- `BufferSize > 1`: buffered FIFO
[BOLT] Page out .dwo files (#214903)
Split-DWARF inputs at big binaries scale ship 100+ GiB of .dwo files.
BOLT opened a fair number of them during readDebugInfo, putting a lot of
pressure on the OS memory management: mmap'd reads always populate the
page cache; with every .dwo mapped at once those pages accumulated,
refaulted, and registered as memory pressure that got the process
oomd-killed.
Now, .dwo page-cache pages are reclaimed as soon as BOLT is done with
each file: madvise(MADV_PAGEOUT) on the live mapping, then
posix_fadvise(POSIX_FADV_DONTNEED) once it is unmapped. Controlled by
-drop-dwo-page-cache, OFF by default, as it is unlikely upstream will be
processing gigantic sets of dwo files.
[BOLT] Create and release .dwo DWARF contexts incrementally (#214900)
BOLT opened a DWARFContext for every .dwo during
readDebugInfo and kept them all alive until teardown. On large
split-DWARF targets that is tens of GiB held resident through emission,
the point of peak RSS.
Make the DWOCUs map a lazily-populated cache instead:
* Use the newly added DWARFUnit::clearDWO()/hasDWO() to directly manage
DWARFUnit's DIE caching mechanism.
* BinaryContext::getDWOCU() opens a context on demand (keyed off a
stable DWOId -> skeleton CU map).
* Release contexts as soon as they are done with: all of them at the end
of readDebugInfo, and per-bucket at the DWARF rewrite merge point.
* Remove DWOCUs map, which became redundant and whose purpose can now be
served by the new id-to-skeleton map, and then fetching the split CU
from the skeleton via getNonSkeletonUnitDIE().
[3 lines not shown]
[CIR][NFC] Fix loop op examples in CIROps.td (#216457)
### summary
The cir.while example had cond and body swapped, and several loop
examples used outdated cir.condition / cir.for syntax. Also add short
examples of the optional per-iteration cleanup region.
Generated by Grok 4.6, but manually reviewed.
[BOLT] Page out .dwo files
Split-DWARF inputs at big binaries scale ship 100+ GiB of .dwo
files. BOLT opened a fair number of them during readDebugInfo, putting
a lot of pressure on the OS memory management: mmap'd reads always
populate the page cache; with every .dwo mapped at once those pages
accumulated, refaulted, and registered as memory pressure that got the
process oomd-killed.
Now, .dwo page-cache pages are reclaimed as soon as BOLT is done with
each file: madvise(MADV_PAGEOUT) on the live mapping, then
posix_fadvise(POSIX_FADV_DONTNEED) once it is unmapped. Controlled by
-drop-dwo-page-cache, OFF by default, as it is unlikely upstream
will be processing gigantic sets of dwo files.
[BOLT] Create and release .dwo DWARF contexts incrementally
BOLT opened a DWARFContext for every .dwo during
readDebugInfo and kept them all alive until teardown. On large
split-DWARF targets that is tens of GiB held resident through
emission, the point of peak RSS.
Make the DWOCUs map a lazily-populated cache instead:
* Use the newly added DWARFUnit::clearDWO()/hasDWO() to directly
manage DWARFUnit's DIE caching mechanism.
* BinaryContext::getDWOCU() opens a context on demand (keyed off a
stable DWOId -> skeleton CU map).
* Release contexts as soon as they are done with: all of them at the
end of readDebugInfo, and per-bucket at the DWARF rewrite merge
point.
* Remove DWOCUs map, which became redundant and whose purpose can
now be served by the new id-to-skeleton map, and then fetching
the split CU from the skeleton via getNonSkeletonUnitDIE().
[5 lines not shown]
[DebugInfo] Add DWARFUnit::clearDWO() (#214899)
Add DWARFUnit::clearDWO() so a skeleton unit can drop the DWO context it
owns without being destroyed itself. Also add DWARFUnit::getDWO() to
answer, without creating a new one, if that skeleton CU is currently
caching a DWO context.
For example, BOLT opened a DWARFContext for every .dwo during
readDebugInfo and kept them all alive until teardown. On large
split-DWARF targets that is tens of GiB held
resident. clearDWO()/getDWO() expose to users DWARFUnit's caching
capacity, allowing them to spontaneously drop the cache/look it
up/re-load it for memory management. To demonstrate this, in
llvm-dwarfdump we now make use of the same technique to avoid ballooning
peak RSS when dumping binaries with dwos. Whenever --debug-info --dwo is
used, during the loop dumping non-skeleton DIEs, we clearDWO as soon as
we're done with that unit. Testing on a large binary, this was shown to
reduce peakRSS from 50GB to 590MB.
Handle DS FIFO accounting edge cases
Saturate hardware-unit pressure decrements and treat buffer sizes zero
and one as disabling buffering to avoid underflow and inconsistent stall
costs.
[AMDGPU] Use DS latency for FIFO scheduling
Use instruction latency for DS hardware-unit cycle accounting so the FIFO
model can identify a full buffer. Add focused MIR coverage for the resulting
stall cost and scheduling decision, and regenerate the integration checks.
Change-Id: I2f4df2e97d145af4935872dbd43108e1b55077ab