Follow-up to #7106.
--opt-report records at select() / deny() sites inside the per-value
rules. A value that is filtered out before it becomes a candidate produces
no entry at all, so the report cannot distinguish:
- the analysis considered this value and rejected it (a rule, arguable), from
- the analysis never looked at this value (nothing to point at).
This is the same ambiguity the census was built to remove, one stage upstream —
and it is why 8 of the census's 18 real workloads read "zero candidates".
The canonical-slot half of this is fixed (module-init contexts and value-level
canonical-i32 rules now record denials). Ptr<Shape>, Ptr<NumArray> and
int-valued-TA still have the hole, at their candidate-collection pre-filters.
Mechanisms still blind
Ptr<NumArray> — whole-analysis kill switches.
crates/perry-codegen/src/collectors/ptr_numarray.rs:220-234:
collect_num_array_locals returns an empty map outright when the module has a
shape-barrier site, a numarray prototype-index barrier, or an opaque prototype
mutation. Every array local in the module vanishes from the report with no
indication that a module-wide barrier was the cause.
Ptr<NumArray> — element-type pre-filter.
ptr_numarray.rs:352-364: only HirType::Array(Number|Int32) (or the
Array<…> generic form) reaches provenance(). A boolean[] — e.g.
benchmarks/suite/11_prime_sieve.ts's sieve — is silently not a candidate.
That verdict is correct, but it is a verdict, and the report throws it away.
Ptr<Shape> has the analogous structure in
crates/perry-codegen/src/collectors/ptr_shape.rs (provenance pass 1 gates
before the containment walk that does record denials).
Evidence
benchmarks/suite/11_prime_sieve.ts reports 0 ptr-numarray candidates.
Read naively that says "this program has no array worth promoting". It has a
1,000,000-element array, in the hot loop, indexed by a proven integer. The real
answer — "declared boolean[], and the analysis only admits numeric element
types" — is a good answer that nothing in the tooling will tell you.
Ask
Record a denial at each pre-filter, with the module-wide kills recorded once per
module rather than once per local. Then candidates == 0 means "this program
has no values of this shape", and nothing else — which is what a reader
currently, and wrongly, assumes it means.
Gate
The census now fails a corpus workload whose candidate total is zero across
every analysis (check_analysis_reach, ZERO_CANDIDATE_ALLOWLIST in
scripts/compiler_output_harness/repsel_census.py). That catches the
whole-workload case. It does not catch a per-analysis zero, which is what this
issue is about.
Follow-up to #7106.
--opt-reportrecords atselect()/deny()sites inside the per-valuerules. A value that is filtered out before it becomes a candidate produces
no entry at all, so the report cannot distinguish:
This is the same ambiguity the census was built to remove, one stage upstream —
and it is why 8 of the census's 18 real workloads read "zero candidates".
The canonical-slot half of this is fixed (module-init contexts and value-level
canonical-i32 rules now record denials).
Ptr<Shape>,Ptr<NumArray>andint-valued-TA still have the hole, at their candidate-collection pre-filters.
Mechanisms still blind
Ptr<NumArray>— whole-analysis kill switches.crates/perry-codegen/src/collectors/ptr_numarray.rs:220-234:collect_num_array_localsreturns an empty map outright when the module has ashape-barrier site, a numarray prototype-index barrier, or an opaque prototype
mutation. Every array local in the module vanishes from the report with no
indication that a module-wide barrier was the cause.
Ptr<NumArray>— element-type pre-filter.ptr_numarray.rs:352-364: onlyHirType::Array(Number|Int32)(or theArray<…>generic form) reachesprovenance(). Aboolean[]— e.g.benchmarks/suite/11_prime_sieve.ts'ssieve— is silently not a candidate.That verdict is correct, but it is a verdict, and the report throws it away.
Ptr<Shape>has the analogous structure incrates/perry-codegen/src/collectors/ptr_shape.rs(provenance pass 1 gatesbefore the containment walk that does record denials).
Evidence
benchmarks/suite/11_prime_sieve.tsreports 0ptr-numarraycandidates.Read naively that says "this program has no array worth promoting". It has a
1,000,000-element array, in the hot loop, indexed by a proven integer. The real
answer — "declared
boolean[], and the analysis only admits numeric elementtypes" — is a good answer that nothing in the tooling will tell you.
Ask
Record a denial at each pre-filter, with the module-wide kills recorded once per
module rather than once per local. Then
candidates == 0means "this programhas no values of this shape", and nothing else — which is what a reader
currently, and wrongly, assumes it means.
Gate
The census now fails a corpus workload whose candidate total is zero across
every analysis (
check_analysis_reach,ZERO_CANDIDATE_ALLOWLISTinscripts/compiler_output_harness/repsel_census.py). That catches thewhole-workload case. It does not catch a per-analysis zero, which is what this
issue is about.