cl, ssa: fix zero-sized global init, fold composite literal alloc stores, and add LTO baseline benchmarks - #2376
cl, ssa: fix zero-sized global init, fold composite literal alloc stores, and add LTO baseline benchmarks#2376cpunion wants to merge 8 commits into
Conversation
…res, and harden static init helpers
There was a problem hiding this comment.
FennoAI Review
This PR cleanly extends the static-init folding optimization to cover struct/array literals that the front-end materializes through a temporary stack alloc reached via pointer indirection (*(&tmp)). The recursive tracing is cycle-guarded (visited), the failure path is safe (partial stores/instrs are discarded when candidate.invalid short-circuits at static_init.go:177), appendStaticInitPath correctly avoids slice-aliasing, and staticInitConstIndex is now hardened against nil/non-int/out-of-range constants. Test coverage is thorough, and the benchmark -lto=full variants plus the merge-base checkout change are sound. The workflow uses the safe pull_request trigger with persist-credentials: false, so no injection risk.
One correctness gap is worth confirming before merge (inline), plus a couple of minor notes below.
Minor
cl/static_init.go:248-251/265-268: whenhandleStoreValclassifies a value as a constant, the element store is recorded both inout(→staticInitStores) and ininstrs(→staticInitInstrs). This is harmless (both suppression checks are independent, andstaticInitInstrsis checked first incompileInstr) but is easy to misread — a one-line comment noting the intentional double-tracking would help.ssa/decl.go:177,186: the sentinel guard relies on a per-callg.impl.Name()string comparison. SincedoNewVarExalready returns a distinguishedaGlobalwrapping the shared sentinelExpr, comparing against the known sentinel value/pointer would make the invariant more explicit and avoid the string compare. Functionally correct as-is.
Note: a full go test ./cl/... could not be run in the review sandbox (LLVM C headers unavailable); findings are from static analysis of the diff.
LLGo baseline benchmarks
Program measurements
Core language and compiler benchmarks
Compared with |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…and add unit tests
Summary
Folds package-level composite literal initializers into LLVM static constants, removing runtime allocation loops in
init()functions, fixes zero-sized global constant initializers, and adds baseline LTO workload measurements.Key Changes
Composite Literal Static Folding (
cl/static_init.go):*(&alloc)).staticInitNodeand compiles them directly into LLVM static constant globals (@global = constant ...).init()function.appendStaticInitPath) and type kind checks (constant.Int).Zero-Sized Global Init Guard (
ssa/decl.go):[0]int{}) aliased to the shared__llgo.moduleZeroSizedAlloc$sentinel (underLinkOnceODRLinkage) are not mutated byInit/InitNil.Baseline Benchmark Measurements (
.github/workflows/benchmark.yml,benchmark/baseline/):-lto=fullworkload measurements (cprintf_lto,println_lto,fmtprintf_lto).merge-basecomputation for exact baseline comparisons.Test Coverage (
cl/rewrite_internal_test.go):cl/static_init.goto 86.6% (and all internal helper functions to 100%).