Skip to content

cl: deduplicate same-line panic PC anchors - #2360

Merged
xushiwei merged 1 commit into
xgo-dev:mainfrom
zhouguangyuan0718:codex/dedup-pcline-sites
Aug 18, 2026
Merged

cl: deduplicate same-line panic PC anchors#2360
xushiwei merged 1 commit into
xgo-dev:mainfrom
zhouguangyuan0718:codex/dedup-pcline-sites

Conversation

@zhouguangyuan0718

Copy link
Copy Markdown
Contributor

Summary

  • deduplicate recover-visible PC-line anchors for repeated implicit panic checks on the same file and line within one SSA basic block
  • reset deduplication at every basic-block boundary so control-flow paths keep a reachable anchor
  • cover both same-block deduplication and cross-block preservation

Motivation

PR #2293 made implicit panic locations visible to runtime.Caller, but expressions that lower to several checks on one source line emitted redundant __llgo_pcl records.

In an XGo Darwin A/B build:

This recovers 705,920 bytes, or 88.9% of the observed binary-size regression, while retaining panic line information.

Testing

  • go test ./cl -run "TestCompileRuntimeCallerPanicPCLineMetadata|TestRuntimeCallerFuncSetKeepsRecoverObservableCallees|TestRuntimeCallerAnalysisEdgeCases" -count=1
  • go test -vet=off ./test/go -run "TestRuntimeStatementLineInfo|TestRuntimeDeferredPanicLine" -count=1
  • go test -vet=off ./test/go (full package, 244.486s)
  • full main-module package run: all packages passed except four internal/build cache tests when the whole run was forced through LLGO_BUILD_CACHE=off; those four passed after rerunning with the normal cache setting

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Deduplicate PC-line metadata sites

This is a clean, well-scoped change. Same-line PC-line anchors within a single SSA basic block are now deduplicated by tracking the last emitted (file, line) on context and resetting it at each compileBlock entry.

Strengths

  • Dedup guard in emitPCLineLabel is O(1) with no new allocations, and pcLineSeq is only incremented after the check passes, so label IDs stay dense and collision-free.
  • Resetting the anchor at the top of compileBlock correctly prevents dedup from crossing control-flow edges (a jump target must not lose its nearest anchor). This also implicitly resets across functions, so no state leaks.
  • Dropping the column from the dedup key is correct and intentional: the encoded runtime PC-line record stores only file + line, verified down to EncodedPCLineRecord.
  • Test coverage locks both directions: same-line panics in one block collapse to 1 record; the same across separate blocks stay at 2.
  • Comments accurately describe the behavior across all changed files.

All four review dimensions (quality, performance, security, documentation) found no blocking issues. One optional maintainability note is inline.

Comment thread cl/compile.go
// last emitted position within one SSA basic block so repeated checks for a
// single source line can share an anchor.
lastPCLineFile string
lastPCLineLine int

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: the correctness of these dedup fields depends on two invariants — compileBlock resetting them at each block entry, and compilation being single-threaded. Both hold today, but a future refactor that parallelizes compilation would silently corrupt this shared state. Consider a one-line note here recording that dependency so the invariant is visible at the field declaration.

@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

Copy link
Copy Markdown

LLGo baseline benchmarks

0e360c4ecdc4 | workflow run | long-term charts

Program measurements

Platform Workload File size vs base Build vs base Run vs base
Linux cprintf 19304 B -80 B / -0.4% (better) 349.957 ms +89.69 ms / +34.5% (worse) 1.075 ms +12.79 us / +1.2% (worse)
Linux fmtprintf 1870232 B -10544 B / -0.6% (better) 2.112 s +31.51 ms / +1.5% (worse) 2.842 ms +96.08 us / +3.5% (worse)
Linux println 68880 B 0 B / +0.0% 338.357 ms +68.78 ms / +25.5% (worse) 1.362 ms +28.47 us / +2.1% (worse)
macOS cprintf 84672 B 0 B / +0.0% 318.057 ms -189.6 ms / -37.3% (better) 2.426 ms -605.5 us / -20.0% (better)
macOS fmtprintf 1892208 B 0 B / +0.0% 2.297 s -868.6 ms / -27.4% (better) 12.678 ms -252.9 us / -2.0% (better)
macOS println 121376 B 0 B / +0.0% 302.619 ms -168.8 ms / -35.8% (better) 3.190 ms -2.96 ms / -48.1% (better)
Core language and compiler benchmarks
Platform Benchmark ns/op vs base
Linux BenchmarkLookupPCRandom 9.551 ns/op -0.007 ns/op / -0.1% (better)
Linux BenchmarkMergeCompilerFlags 112 ns/op +0.2 ns/op / +0.2% (worse)
Linux BenchmarkMergeLinkerFlags 73.010 ns/op -1.06 ns/op / -1.4% (better)
Linux BenchmarkChannelBuffered 28.390 ns/op +0.25 ns/op / +0.9% (worse)
Linux BenchmarkChannelHandoff 19263 ns/op -97 ns/op / -0.5% (better)
Linux BenchmarkDefer 35.170 ns/op +1.98 ns/op / +6.0% (worse)
Linux BenchmarkDirectCall 1.364 ns/op 0 ns/op / +0.0%
Linux BenchmarkGlobalRead 1.364 ns/op +0.001 ns/op / +0.1% (worse)
Linux BenchmarkGlobalWrite 2.180 ns/op 0 ns/op / +0.0%
Linux BenchmarkGoroutine 24396 ns/op +5 ns/op / +0.0205% (worse)
Linux BenchmarkInterfaceCall 6.821 ns/op -0.497 ns/op / -6.8% (better)
Linux BenchmarkRuntimeGetG 1.638 ns/op +0.261 ns/op / +19.0% (worse)
macOS BenchmarkLookupPCRandom 10.630 ns/op -3.92 ns/op / -26.9% (better)
macOS BenchmarkMergeCompilerFlags 132.600 ns/op -6.9 ns/op / -4.9% (better)
macOS BenchmarkMergeLinkerFlags 74.550 ns/op -27.05 ns/op / -26.6% (better)
macOS BenchmarkChannelBuffered 25.550 ns/op +0.92 ns/op / +3.7% (worse)
macOS BenchmarkChannelHandoff 7110 ns/op +1754 ns/op / +32.7% (worse)
macOS BenchmarkDefer 25.880 ns/op -3.5 ns/op / -11.9% (better)
macOS BenchmarkDirectCall 0.943 ns/op -0.0383 ns/op / -3.9% (better)
macOS BenchmarkGlobalRead 0.993 ns/op -0.0278 ns/op / -2.7% (better)
macOS BenchmarkGlobalWrite 0.944 ns/op -0.081 ns/op / -7.9% (better)
macOS BenchmarkGoroutine 35840 ns/op +4496 ns/op / +14.3% (worse)
macOS BenchmarkInterfaceCall 5.358 ns/op -0.685 ns/op / -11.3% (better)
macOS BenchmarkRuntimeGetG 2.303 ns/op +0.323 ns/op / +16.3% (worse)

Compared with 95b3ff5d135e measured in the same runner job.

@xushiwei
xushiwei merged commit efbc66a into xgo-dev:main Aug 18, 2026
42 checks passed
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.

2 participants