Skip to content

Multi-origin vOrigins with per-node cap#11

Open
robtaylor wants to merge 105 commits into
mainfrom
origin-tracking-clean
Open

Multi-origin vOrigins with per-node cap#11
robtaylor wants to merge 105 commits into
mainfrom
origin-tracking-clean

Conversation

@robtaylor

Copy link
Copy Markdown
Owner

CI test PR for berkeley-abc#487.

5 commits adding per-object origin tracking to Gia_Man_t, for propagating Yosys \src attributes through ABC optimization passes.

See upstream PR for full description and discussion.

@robtaylor robtaylor force-pushed the origin-tracking-clean branch 2 times, most recently from 43bc82f to 4f03583 Compare April 3, 2026 01:08
alanminko and others added 28 commits April 3, 2026 21:18
fix timing inconsistency in calculating the "timeOther" in Ssw_ManPrintStats in sswMan.c
Bring test in line with all other tests for mach based MacOS builds,
and ensure the code in question is not enabled with mach on GNU Hurd.
The buffer length is used in a static array returned from
Extra_FileNameGenericAppend(), used many places in the code, and a
more dynamic approach would require a huge refactoring.  There is no
guarantee that the 4096 value picked is large enough, but it matches
common values found on Linux.
…work.

Otherwise the abc will refuse to output trivial functions(constant 1 or 0).

The issue was originally submitted to
<URL: https://bitbucket.org/alanmi/abc/issue/27/assertion-failure-in-write_pla-command >,
now available via
<URL: https://web.archive.org/web/20200621081236/https://bitbucket.org/alanmi/abc/issues/27/assertion-failure-in-write_pla-command >.
Sadly the example demonstrated the problem was not archived.

This issue was also reported as <URL: https://bugs.debian.org/780450 >.
It is a convention inherited from GNU automake to use CPPFLAGS
for compiler flag intended for the preprocessor, while CFLAGS and
and CXXFLAGS provide flags intended for the C and C++ compiler.
Adjust build rules to include CPPFLAGS ensure any preprocessor
flags in build systems using this environment variable work out of
the box.

This allow Debian builds to pass on hardening flags without modifying
the build setup.

Patch from Ruben Undheim via Debian
…assert-relaxed

Relaxed assert in Io_WritePla() to avoid failure with too shallow network.
…lags

Use CPPFLAGS alongside CFLAGS and CXXFLAGS during build.
Added fix for write_cnf adding extra clauses on direct PI-PO
Fix intermittent assert failures in lutpack functions
heshpdx and others added 29 commits June 16, 2026 15:33
The cast to char** is a violation of strict aliasing rules.
Compilers may generate incorrect code due to this issue.
Using memcpy to avoid the issue. Not expecting perf difference.
…-nSize-reload

misc: Prevent Vec_IntRemove from loading nSize in every iteration
Fix issue with constant replacements
With GCC and Clang, look for the __SIZEOF_INT128__ define only defined
when __int128 is present before trying to use it.

This fixes build problem on all 32 bit Linux architectures.
Signed-off-by: JingrenWang <wjrforcyber@163.com>
…m-merge

Add dynamic SRM and incremental simulation into &scorr -i ; Fix a bug of &scorr -i ;
Improve support for -D 3 together with -X
Add lightweight origin tracking that propagates source-location
provenance through ABC's optimization passes. This enables the
Yosys abc9 flow to preserve \src attributes on LUT cells after
technology mapping, achieving ~100% coverage on tested designs
with negligible overhead (~0.6% time, ~3% memory on picorv32).

Changes:
- Add Vec_Int_t *vOrigins field to Gia_Man_t with inline accessors
- Read/write origins via AIGER "y" extension (sentinel -1 for unmapped)
- Propagate through all Gia_ManDup* variants via Gia_ManOriginsDup()
- Propagate through structural hashing (AND/XOR/MUX) in giaHash.c
- Recover origins after GIA→AIG→GIA round-trips (&dc2, &dch) via
  Gia_ManOriginsAfterRoundTrip() using CO driver + top-down propagation
- Propagate through IF mapper using iCopy correspondence
- Instrument giaEquiv, giaMuxes, giaTim, giaBalAig, dauGia

Co-developed-by: Claude Code v2.1.44 (claude-opus-4-6)
Extend origin tracking to cover the complete abc9 optimization
pipeline. Add Gia_ManOriginsDupVec for functions that use Vec_Int_t
copy vectors instead of the Value field.

Engines instrumented:
- &dc2, &dch: Round-trip recovery (giaAig.c)
- &if: iCopy-based propagation in SopBalance/DsdBalance (giaIf.c),
  plus DupHashMapping/DupUnhashMapping for timing paths
- &jf, &lf: OriginsDupVec in Jf_ManDeriveGia/Lf_ManDeriveMappingGia
- &syn2, &synch2: Sub-operations (Jf/Lf mappers) + round-trip
  recovery in Gia_ManAigSynch2Choices, DupFromBarBufs/DupToBarBufs
  for box designs (giaScript.c)
- &sweep: Gia_ManFraigReduceGia, Gia_ManDupWithBoxes (giaSweep.c)
- &scorr: Gia_ManCorrReduce (cecCorr.c)
- &mfs: Custom propagation via vMfs2Old/vMfs2Gia (giaMfs.c)
- Supporting: Gia_ManDupCollapse/DupNormalize/DupUnnormalize (giaTim.c),
  DupUnshuffleInputs/DupMoveLast (giaTim.c),
  EquivToChoices (giaEquiv.c), DupMuxes (giaMuxes.c),
  BalanceInt (giaBalAig.c), DauMergePart (dauGia.c),
  DupWithAttributes (giaDup.c)

Add bounds checks in Gia_ObjOrigin and Gia_ObjSetOrigin for GIAs
that grow after vOrigins is allocated (e.g., AreaBalance adding nodes).

Coverage verified by static analysis finding all Gia_Man_t* functions
that call Gia_ManStart without Gia_ManOriginsDup — 23 functions
covered, remaining 167 are outside the abc9 pipeline.

Co-developed-by: Claude Code v2.1.58 (claude-opus-4-6)
Replace single-origin-per-object vOrigins with a union-based scheme
that stores up to GIA_ORIGINS_INLINE (default 4) origins inline, with
overflow to a heap-allocated array for outliers. This captures merge
events from structural hashing and optimization that previously lost
origin information.

Data structure (Gia_OriginsEntry_t union, 16 bytes on 64-bit):
- Inline mode: 4 inline int slots (-1 = unused)
- Overflow mode: sentinel (INT_MIN) + count + heap pointer
- Stride = sizeof(entry)/sizeof(int) = 4 ints per object

Key changes:
- gia.h: Union type, stride constants, inline accessors
  (Gia_ObjOriginsNum, Gia_ObjOriginsGet, Gia_ObjForEachOrigin),
  updated Gia_ObjOrigin/Gia_ObjSetOrigin for backward compat
- giaDup.c: Gia_ObjAddOrigin (dedup + promote), Gia_ObjUnionOrigins,
  Gia_ManOriginsFreeOverflows; updated OriginsDup/DupVec/AfterRoundTrip
  for strided multi-origin propagation
- giaHash.c: Union all input origins on hash miss AND hash hit (captures
  structural sharing from different source paths)
- giaAiger.c: Variable-length "y" extension format [count, lit0, lit1,...]
  with backward-compatible reader for old single-origin format
- giaIf.c, giaMfs.c: Mapper propagation via Gia_ObjUnionOrigins
- giaMan.c: Free overflow arrays before vOrigins cleanup

Co-developed-by: Claude Code v2.1.58 (claude-opus-4-6)

Harden multi-origin vOrigins: leak guards, geometric growth, format sentinel

- Add free-before-alloc guards in all OriginsDup functions to prevent
  memory leaks when vOrigins is already populated (e.g. Gia_ManDup
  followed by Gia_ManDupWithAttributes)
- Replace O(n²) realloc-by-1 with geometric doubling in overflow
  arrays (8-slot initial capacity, double at powers of 2)
- Add sentinel int -2 to AIGER "y" extension writer/reader for
  unambiguous new-vs-old format detection (fixes edge case where
  nInts == nAigObjs with all-zero origins)
- Extract Gia_ManOriginsDupIf() helper to deduplicate 3 identical
  14-line IF mapper origin propagation blocks
- Replace Gia_ManOriginsGrow push-loop with Vec_IntFillExtra
- Add vNodes NULL guard in AIGER reader
- Remove orphaned duplicate comment block

Co-developed-by: Claude Code v2.1.58 (claude-opus-4-6)

Simplify vOrigins: extract OriginsReset, fix free(), hoist iteration count

Code review cleanup:
- Extract Gia_ManOriginsReset() helper to replace 5 identical
  free-overflows + free-vec leak-guard blocks
- Use ABC_FREE() instead of bare free() in Gia_ObjSetOrigin
  for allocator consistency
- Hoist Gia_ObjOriginsNum() call out of Gia_ObjForEachOrigin
  macro loop condition (callers declare _nOrig)
- Add compile-time assertion that GIA_ORIGINS_INLINE is large
  enough to cover the overflow header on the target platform

Co-developed-by: Claude Code v2.1.83 (claude-opus-4-6)
- &origins: prints multi-origin statistics (entry count, total origins,
  average/max per node, overflow count, histogram). Origins are
  populated either from XAIGER "y" extension (normal abc9 flow) or
  by &origins_id (testing).
- &origins_id: sets identity origins (each AND node -> itself) for
  testing origin propagation in standalone ABC sessions. Not needed
  in the normal abc9 flow where origins come from Yosys via XAIGER.

Co-developed-by: Claude Code v2.1.58 (claude-opus-4-6)
Shared fanin cones can accumulate origins from all CO drivers,
causing O(n²) dedup cost in Gia_ObjAddOrigin. Add nOriginsMax
field to Gia_Man_t that short-circuits overflow-mode AddOrigin
when the node has reached the limit. Cap is set via &origins_id -M.

Pathological case (10K outputs, shared 50-deep cone):
  No cap:   5.70s, 1.01M total origins, max 10000/node
  -M 256:   0.79s, 45K total origins, max 256/node (7.2x faster)
Normal designs (i10.aig, max 165/node): identical results.

Co-developed-by: Claude Code v2.1.89 (claude-opus-4-6)
PR berkeley-abc#487 shipped no tests; this adds a gtest suite (test/gia/origins_test.cc,
consistent with the existing gia_test.cc) covering:

- core infra: set/get, add-with-dedup, inline->overflow promotion,
  cross-manager union, and the nOriginsMax cap;
- propagation through Gia_ManDup;
- the AIGER "y" extension write/read round-trip;
- preservation through the &nf standard-cell mapper (driven via read_genlib +
  &read + &nf using a small bundled genlib fixture). &nf maps in place, so
  origins survive standard-cell mapping with no dedicated propagation code.

All 8 cases pass under ctest.

Co-developed-by: Claude Code v2.1.195 (claude-opus-4-8)
Gia_AigerReadFromMemory's extension loop is a chain of `else if (*pCur ==
<char>)` terminated by `else break`. The writer emits an uppercase "M"
(cell-mapping doc) section, but the reader had no case for it, so reading a
cell-mapped AIGER hit "M", fell through to `else break`, and abandoned every
later extension -- including the "y" origin mapping, which is written after
"M". Result: origins were silently lost when reading back any std-cell-mapped
GIA (e.g. after &nf).

Add an "M" branch that skips the section (its contents are consumed by external
readers such as Yosys's read_xaiger2, not by ABC's GIA reader) so the loop
continues to "y". "M" was the only writer-emitted section the reader did not
handle.

Adds a regression test (MappedAigerRoundTripPreservesOrigins) that maps with
&nf, writes (emitting "M" then "y"), reads back, and asserts origins survive.

Co-developed-by: Claude Code v2.1.195 (claude-opus-4-8)
…onv)

Balancing (Gia_ManBalanceInt, Dam_ManMultiAig) and MUX<->AND conversion
(Gia_ManDupMuxes/NoMuxes) rebuild the AIG via Gia_ManHashAnd/MuxReal, creating
new nodes with no 1:1 correspondence to the source. The post-hoc
Gia_ManOriginsDup (keyed on pObj->Value) cannot seed those new nodes, so their
vOrigins — and the \src of any cell later mapped from them — were dropped.

Add Gia_ManOriginsDupFill: Gia_ManOriginsDup for the survivors, then a single
bottom-up pass giving each remaining AND node the union of its fanins' origins
(incl. the MUX 3rd fanin). GIA's topological order makes one forward pass
sufficient. Use it at the four rebuild sites.

Effect: e.g. a sequential design with reset/enable through `&syn2` goes from 94%
to 100% \src; `&b`/`&dc2`/`&dch` origin coverage is hardened. The change is
additive (only ever adds origins), so engines already at full coverage are
unaffected. Regression test: AreaBalancePreservesOriginCoverage.

Note: heavy restructuring still dissolves the original \src-bearing AND nodes,
so nodes that become pure functions of CIs get only CI-level provenance (CIs
carry no map2 \src) — an inherent limit, not addressed here. The default
std-cell flow uses `&dch;&nf`, which reaches 100% precise \src.

Co-developed-by: Claude Code v2.1.195 (claude-opus-4-8)
@robtaylor robtaylor force-pushed the origin-tracking-clean branch from 2daf32f to 3632a04 Compare July 6, 2026 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.