Skip to content

Add ENABLE_CONSTANT_TRACER prototype (Stage 1 partial) - #260

Open
PhilippGrulich wants to merge 2 commits into
mainfrom
claude/constant-value-tracer-BTcHn
Open

Add ENABLE_CONSTANT_TRACER prototype (Stage 1 partial)#260
PhilippGrulich wants to merge 2 commits into
mainfrom
claude/constant-value-tracer-BTcHn

Conversation

@PhilippGrulich

Copy link
Copy Markdown
Member

Introduces LazyTracedRef, a lazy state holder for val that is either
a pure compile-time constant (no trace footprint, no aliveVars entry) or
a materialized TypedValueRef. Materialization happens on the first
implicit conversion to TypedValueRef, so existing code that passes
value.state to trace*Op functions keeps working unchanged.

When ENABLE_CONSTANT_TRACER is ON (default OFF), val and
val:

  • skip the eager traceConstant call in their value/copy constructors,
  • fold pure binary/unary ops eagerly when both inputs are Constant,
  • fold casts on Constant arithmetic vals,
  • skip traceBool entirely when the condition is Constant
    (dead-branch elimination),
  • materialize lazily and cache the resulting TypedValueRef the first
    time anyone reads state as a TypedValueRef.

When OFF, val behavior is byte-identical to before; all 165 existing
tests still pass with the option disabled.

KNOWN INCOMPLETE — the design's "no elision crosses a basic-block
boundary" invariant is documented in LazyTracedRef.hpp but NOT yet
enforced. Programs that re-assign a previously-Constant val inside a
branch (e.g. chainedIf100) currently produce traces missing the
required phi for that var, so several existing tests fail with the
option ON. The fix path (val-registry that materialize()s every live
Constant on traceBool) is sketched in the same comment.

Stage 2 (loop-aware widening via Snapshot stratification) is not
implemented; it requires restructuring SymbolicExecutionContext and
is documented as future work.

https://claude.ai/code/session_01H6BejBjwWYmoEXG6Vt6on4

@github-actions github-actions 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.

Tracing Benchmark

Details
Benchmark suite Current: ac7957e Previous: ac2c4ea Ratio
e2e_tiered_bc_to_mlir 49.6816 us (± 11.4293) 47.7032 us (± 8.68568) 1.04
e2e_single_mlir 8.23867 ms (± 294.546) 8.23818 ms (± 491.471) 1.00
ssa_add 177.991 ns (± 11.6883) 185.816 ns (± 10.3996) 0.96
ssa_ifThenElse 466.029 ns (± 29.5821) 455.998 ns (± 8.73188) 1.02
ssa_deeplyNestedIfElse 1.19914 us (± 103.988) 1.1929 us (± 84.0502) 1.01
ssa_loop 453.106 ns (± 26.3689) 495.525 ns (± 42.2521) 0.91
ssa_ifInsideLoop 838.535 ns (± 51.3168) 923.55 ns (± 58.5963) 0.91
ssa_loopDirectCall 507.629 ns (± 51.606) 497.983 ns (± 20.4573) 1.02
ssa_pointerLoop 596.269 ns (± 35.3296) 600.749 ns (± 36.2279) 0.99
ssa_staticLoop 451.68 ns (± 24.8408) 497.541 ns (± 60.4145) 0.91
ssa_fibonacci 516.015 ns (± 41.1861) 520.747 ns (± 31.8873) 0.99
ssa_gcd 453.194 ns (± 31.439) 451.525 ns (± 29.293) 1.00
exec_bc_addOne 35.9851 ns (± 6.12995) 36.2618 ns (± 5.56148) 0.99
exec_mlir_addOne 307.967 ns (± 9.30423) 276.222 ns (± 5.76067) 1.11
exec_cpp_addOne 4.08613 ns (± 1.0367) 3.88144 ns (± 0.331571) 1.05
exec_interpreted_addOne 38.0389 ns (± 1.81467) 38.0484 ns (± 1.8257) 1.00
ir_add 631.917 ns (± 33.7744) 618.115 ns (± 53.3797) 1.02
ir_ifThenElse 1.51633 us (± 113.587) 1.44905 us (± 86.8949) 1.05
ir_deeplyNestedIfElse 3.5321 us (± 459.519) 3.37592 us (± 239.133) 1.05
ir_loop 1.59076 us (± 94.4772) 1.53605 us (± 105.581) 1.04
ir_ifInsideLoop 2.85155 us (± 216.869) 2.77156 us (± 196.154) 1.03
ir_loopDirectCall 1.74458 us (± 187.481) 1.66853 us (± 129.354) 1.05
ir_pointerLoop 1.9764 us (± 196.735) 1.92704 us (± 132.013) 1.03
ir_staticLoop 1.31866 us (± 214.846) 1.2645 us (± 80.8019) 1.04
ir_fibonacci 1.74597 us (± 194.557) 1.65853 us (± 128.906) 1.05
ir_gcd 1.41674 us (± 99.0636) 1.37896 us (± 94.5931) 1.03
ir_nestedIf10 7.5986 us (± 487.31) 7.6512 us (± 799.841) 0.99
ir_nestedIf100 91.5981 us (± 4.86431) 93.3698 us (± 6.73228) 0.98
ir_chainedIf10 12.4957 us (± 942.577) 12.4575 us (± 863.742) 1.00
ir_chainedIf100 183.386 us (± 9.94714) 183.581 us (± 16.7128) 1.00
exec_mlir_add 10.9265 ns (± 1.22541) 10.822 ns (± 0.936004) 1.01
exec_mlir_fibonacci 15.8631 us (± 1.87754) 13.7916 us (± 1.74485) 1.15
exec_mlir_sum 538.244 us (± 27.0618) 515.967 us (± 16.084) 1.04
exec_cpp_add 4.81543 ns (± 0.996424) 4.6159 ns (± 0.528671) 1.04
exec_cpp_fibonacci 94.6739 us (± 7.14187) 97.6672 us (± 10.8249) 0.97
exec_cpp_sum 35.8817 ms (± 221.876) 35.9244 ms (± 434.181) 1.00
exec_bc_add 43.8306 ns (± 5.07487) 44.8834 ns (± 7.90089) 0.98
exec_bc_fibonacci 839.887 us (± 15.5265) 842.734 us (± 20.2036) 1.00
exec_bc_sum 178.513 ms (± 1.60754) 178.8 ms (± 3.10469) 1.00
exec_asmjit_add 3.50799 ns (± 0.465687) 3.49445 ns (± 0.375379) 1.00
exec_asmjit_fibonacci 21.368 us (± 1.88768) 21.6426 us (± 2.74605) 0.99
exec_asmjit_sum 4.65507 ms (± 95.0337) 4.71937 ms (± 21.7272) 0.99
exec_bc_add_noRegAlloc 43.5893 ns (± 4.34073) 43.9791 ns (± 4.89944) 0.99
exec_bc_add_regAlloc 43.8246 ns (± 4.82559) 43.5639 ns (± 2.86818) 1.01
exec_bc_fibonacci_noRegAlloc 841.07 us (± 14.1067) 861.571 us (± 98.4839) 0.98
exec_bc_fibonacci_regAlloc 845.345 us (± 15.2232) 839.407 us (± 13.4705) 1.01
exec_bc_sum_noRegAlloc 178.559 ms (± 1.05316) 179.223 ms (± 2.02788) 1.00
exec_bc_sum_regAlloc 178.727 ms (± 538.677) 178.601 ms (± 3.45719) 1.00
comp_mlir_add 8.09733 ms (± 195.508) 8.03653 ms (± 44.1051) 1.01
comp_mlir_ifThenElse 8.87835 ms (± 187.319) 8.61342 ms (± 54.5514) 1.03
comp_mlir_deeplyNestedIfElse 7.80659 ms (± 198.487) 7.5802 ms (± 40.4471) 1.03
comp_mlir_loop 9.98918 ms (± 357.061) 9.48877 ms (± 103.05) 1.05
comp_mlir_ifInsideLoop 31.5971 ms (± 471.105) 30.5007 ms (± 230.085) 1.04
comp_mlir_loopDirectCall 14.6247 ms (± 285.779) 14.0043 ms (± 46.9025) 1.04
comp_mlir_pointerLoop 31.0957 ms (± 876.226) 29.5874 ms (± 103.344) 1.05
comp_mlir_staticLoop 7.72811 ms (± 285.271) 7.47096 ms (± 38.3264) 1.03
comp_mlir_fibonacci 13.4716 ms (± 453.298) 12.6628 ms (± 38.156) 1.06
comp_mlir_gcd 12.3361 ms (± 370.663) 11.6741 ms (± 63.0358) 1.06
comp_mlir_nestedIf10 13.7389 ms (± 436.582) 12.8187 ms (± 55.0301) 1.07
comp_mlir_nestedIf100 27.2215 ms (± 426.761) 27.225 ms (± 87.2712) 1.00
comp_mlir_chainedIf10 12.307 ms (± 341.335) 11.8168 ms (± 116.022) 1.04
comp_mlir_chainedIf100 23.2382 ms (± 659.182) 22.1996 ms (± 240.353) 1.05
comp_cpp_add 25.0971 ms (± 719.14) 24.5321 ms (± 480.572) 1.02
comp_cpp_ifThenElse 25.479 ms (± 603.278) 25.2727 ms (± 558.226) 1.01
comp_cpp_deeplyNestedIfElse 26.3087 ms (± 688.859) 26.2665 ms (± 459.988) 1.00
comp_cpp_loop 25.8364 ms (± 508.337) 25.2988 ms (± 344.351) 1.02
comp_cpp_ifInsideLoop 27.0255 ms (± 592.473) 26.4559 ms (± 789.37) 1.02
comp_cpp_loopDirectCall 26.9702 ms (± 1.35278) 25.0943 ms (± 221.508) 1.07
comp_cpp_pointerLoop 26.397 ms (± 805.398) 25.222 ms (± 258.79) 1.05
comp_cpp_staticLoop 24.8856 ms (± 717.374) 24.5928 ms (± 309.914) 1.01
comp_cpp_fibonacci 25.85 ms (± 764.112) 24.9754 ms (± 293.062) 1.04
comp_cpp_gcd 25.8512 ms (± 612.924) 25.2159 ms (± 502.157) 1.03
comp_cpp_nestedIf10 30.6915 ms (± 704.766) 28.5753 ms (± 693.59) 1.07
comp_cpp_nestedIf100 62.1937 ms (± 1.59868) 61.7031 ms (± 527.471) 1.01
comp_cpp_chainedIf10 31.5669 ms (± 1.10673) 30.694 ms (± 425.766) 1.03
comp_cpp_chainedIf100 91.8308 ms (± 1.00526) 91.4516 ms (± 673.024) 1.00
comp_bc_add 14.855 us (± 2.21368) 14.3597 us (± 2.48149) 1.03
comp_bc_ifThenElse 18.7942 us (± 2.98858) 18.1495 us (± 2.61377) 1.04
comp_bc_deeplyNestedIfElse 22.997 us (± 3.22877) 21.8467 us (± 3.49218) 1.05
comp_bc_loop 19.3884 us (± 4.63735) 18.5722 us (± 4.77224) 1.04
comp_bc_ifInsideLoop 22.2572 us (± 3.72876) 21.1077 us (± 3.93291) 1.05
comp_bc_loopDirectCall 19.9262 us (± 3.87713) 18.8034 us (± 3.15769) 1.06
comp_bc_pointerLoop 20.5619 us (± 3.35869) 20.003 us (± 3.56989) 1.03
comp_bc_staticLoop 17.2778 us (± 3.03127) 17.0675 us (± 3.19641) 1.01
comp_bc_fibonacci 19.1415 us (± 3.14582) 18.8155 us (± 3.99054) 1.02
comp_bc_gcd 18.7145 us (± 3.72348) 18.1727 us (± 3.2952) 1.03
comp_bc_nestedIf10 36.2962 us (± 4.60828) 35.1955 us (± 4.58262) 1.03
comp_bc_nestedIf100 201.406 us (± 13.7971) 197.212 us (± 11.5333) 1.02
comp_bc_chainedIf10 52.1207 us (± 7.41229) 50.988 us (± 9.82885) 1.02
comp_bc_chainedIf100 303.043 us (± 13.7926) 306.036 us (± 11.3522) 0.99
comp_asmjit_add 19.814 us (± 3.60815) 20.6396 us (± 3.7317) 0.96
comp_asmjit_ifThenElse 32.548 us (± 5.01094) 32.008 us (± 5.75999) 1.02
comp_asmjit_deeplyNestedIfElse 54.6524 us (± 8.07573) 54.3531 us (± 8.14402) 1.01
comp_asmjit_loop 34.101 us (± 5.32475) 33.7759 us (± 4.23803) 1.01
comp_asmjit_ifInsideLoop 56.3058 us (± 11.5638) 53.9387 us (± 5.94154) 1.04
comp_asmjit_loopDirectCall 45.236 us (± 10.1102) 44.0242 us (± 8.85063) 1.03
comp_asmjit_pointerLoop 46.3312 us (± 7.93411) 46.0983 us (± 8.87218) 1.01
comp_asmjit_staticLoop 27.0939 us (± 4.20994) 27.1825 us (± 4.14008) 1.00
comp_asmjit_fibonacci 41.3349 us (± 8.10415) 41.5607 us (± 7.09007) 0.99
comp_asmjit_gcd 33.4159 us (± 4.89637) 34.0827 us (± 5.38372) 0.98
comp_asmjit_nestedIf10 100.642 us (± 10.9382) 100.924 us (± 9.12832) 1.00
comp_asmjit_nestedIf100 1.02162 ms (± 13.6663) 1.02018 ms (± 11.7866) 1.00
comp_asmjit_chainedIf10 151.903 us (± 14.2155) 152.283 us (± 13.5281) 1.00
comp_asmjit_chainedIf100 2.14853 ms (± 32.2963) 2.13238 ms (± 35.6257) 1.01
tiered_compile_addOne 54.1884 us (± 13.4109) 51.9377 us (± 13.0686) 1.04
single_compile_mlir_addOne 6.37705 ms (± 218.012) 6.10715 ms (± 63.2407) 1.04
single_compile_cpp_addOne 24.6656 ms (± 509.553) 24.4534 ms (± 271.946) 1.01
single_compile_bc_addOne 69.2658 us (± 21.9383) 51.9263 us (± 8.48295) 1.33
tiered_compile_sumLoop 75.0086 us (± 11.7772) 73.8566 us (± 13.3747) 1.02
single_compile_mlir_sumLoop 8.69136 ms (± 274.968) 8.15025 ms (± 122.033) 1.07
single_compile_cpp_sumLoop 26.0165 ms (± 872.992) 25.6265 ms (± 346.062) 1.02
single_compile_bc_sumLoop 77.0162 us (± 14.9975) 73.7859 us (± 9.66704) 1.04
trace_add 2.32013 us (± 213.105) 2.27443 us (± 166.248) 1.02
completing_trace_add 2.2852 us (± 199.618) 2.30772 us (± 203.032) 0.99
trace_ifThenElse 8.78943 us (± 1.19485) 8.79821 us (± 706.962) 1.00
completing_trace_ifThenElse 4.55249 us (± 455.198) 4.5873 us (± 359.51) 0.99
trace_deeplyNestedIfElse 26.29 us (± 3.12233) 25.9509 us (± 1.83273) 1.01
completing_trace_deeplyNestedIfElse 12.7999 us (± 1.55701) 12.719 us (± 1.13015) 1.01
trace_loop 8.72374 us (± 1.26144) 8.60986 us (± 668.278) 1.01
completing_trace_loop 4.73607 us (± 574.716) 4.69067 us (± 293.036) 1.01
trace_ifInsideLoop 17.4882 us (± 2.62388) 17.1019 us (± 1.72681) 1.02
completing_trace_ifInsideLoop 8.69817 us (± 1.03793) 8.49425 us (± 815.985) 1.02
trace_loopDirectCall 9.00565 us (± 818.836) 8.87258 us (± 695.472) 1.01
completing_trace_loopDirectCall 4.96096 us (± 533.35) 4.8027 us (± 315.653) 1.03
trace_pointerLoop 13.1579 us (± 1.46027) 14.3937 us (± 1.20265) 0.91
completing_trace_pointerLoop 9.95885 us (± 1.20702) 10.4807 us (± 1.59059) 0.95
trace_staticLoop 7.63257 us (± 873.921) 7.39065 us (± 849.79) 1.03
completing_trace_staticLoop 7.66787 us (± 783.017) 7.4703 us (± 715.621) 1.03
trace_fibonacci 10.3169 us (± 1.84159) 10.163 us (± 1.71855) 1.02
completing_trace_fibonacci 6.24658 us (± 843.983) 6.05346 us (± 710.97) 1.03
trace_gcd 8.13646 us (± 1.30721) 7.99856 us (± 1.09167) 1.02
completing_trace_gcd 4.0229 us (± 413.402) 3.98571 us (± 405.803) 1.01
trace_nestedIf10 39.2338 us (± 6.67466) 38.6445 us (± 6.35823) 1.02
completing_trace_nestedIf10 38.7864 us (± 6.15003) 39.1952 us (± 6.89562) 0.99
trace_nestedIf100 1.36722 ms (± 20.738) 1.36513 ms (± 19.5193) 1.00
completing_trace_nestedIf100 1.39942 ms (± 20.8884) 1.38142 ms (± 29.3291) 1.01
trace_chainedIf10 99.7868 us (± 9.12703) 100.633 us (± 10.9977) 0.99
completing_trace_chainedIf10 49.9673 us (± 7.11158) 49.6066 us (± 7.49433) 1.01
trace_chainedIf100 4.46633 ms (± 90.4112) 4.45201 ms (± 36.6404) 1.00
completing_trace_chainedIf100 2.23488 ms (± 63.0638) 2.27281 ms (± 21.1455) 0.98

This comment was automatically generated by workflow using github-action-benchmark.

@PhilippGrulich
PhilippGrulich force-pushed the claude/constant-value-tracer-BTcHn branch 9 times, most recently from af6d74e to 695f469 Compare April 18, 2026 09:58
PhilippGrulich and others added 2 commits April 19, 2026 18:12
Bundles the trace-time partial-evaluation plugin (ENABLE_CONSTANT_TRACER,
default off) and the TraceContextRegistry that swaps tracer selection
from a hard-coded if/else onto a registry lookup mirroring
CompilationBackendRegistry.

Core:
 - TraceContextRegistry (nautilus/tracing/): Meyer's-singleton that maps
   a trace-mode name to a TraceContextBase instance. Core registers
   "lazyTracing" and "exceptionBasedTracing" in the registry constructor;
   the PE plugin's static-init registers "partialEvaluation".
   LegacyCompiler::compileToIR picks the mode from engine.traceMode and
   dispatches via the instance's virtual Trace() — no core-side
   awareness of the PE subclass.
 - TraceContextBase grows a pure-virtual Trace(...). The existing
   LazyTraceContext::Trace and ExceptionBasedTraceContext::Trace move
   from static to virtual overrides; registry-owned instances are
   dormant factories whose Trace() forwards to a thread_local worker
   of the same concrete type.
 - TracingInterface grows a virtual isPartialEvaluationMode() — PE's
   PELazyTraceContext::onActivate/onDeactivate use it to flip the PE
   runtime flag on while PE is the active tracer, so mode selection is
   the sole source of truth for whether LazyTracedRef's fold fast paths
   and the Constant registry are live.

PE plugin (plugins/partial_evaluation/, ENABLE_CONSTANT_TRACER=ON):
 - PELazyTraceContext : public LazyTraceContext — single direct
   subclass (the earlier CRTP PETraceContextMixin over both
   LazyTraceContext and ExceptionBasedTraceContext is retired).
   Overrides the eight trace ops that can split or merge the trace
   with pe::materializeAllConstants() + base call; overrides
   onActivate/onDeactivate/beforeInnerFunction for counter reset,
   Constant-registry sweep, and PE-flag toggling.
 - LazyTracedRef<T>, Constant registry, Stage 2 stratified widening
   (per-site unroll_scope + blunt iteration cap), observability
   counters, assume_stable RAII, example/DemoConstantFolding.cpp.
 - ConstantTracerTest: fold correctness, Stage 2 widening behavior,
   exceptionBasedTracing-mode sanity.

Testing:
 - forEachBackend / forEachBackendWithTraceMode iterate trace-mode
   names from TraceContextRegistry. Under ENABLE_CONSTANT_TRACER=ON the
   default mode is "partialEvaluation" and TracingTest iterates only
   that mode so the committed golden-trace overrides (780 files under
   test/data/constant-tracer/) match. ReferenceDumpHelper now takes an
   explicit `usePartialEvaluationOverride` flag instead of sniffing
   ENABLE_CONSTANT_TRACER.
 - Plugin tests for specialization and inlining iterate
   constantTracerModes() unchanged (currently {false}) so those call
   sites compile without edits; a follow-up can switch them to mode
   iteration once they care.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tics

Add virtual TraceContextBase::collectStatistics(CompilationStatistics&)
no-op hook; PE overrides it to populate constantTracer.* keys.
LegacyCompiler::compileToIR now calls the virtual instead of the
#ifdef ENABLE_CONSTANT_TRACER block, removing the last PE-specific
ifdef from core.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@PhilippGrulich
PhilippGrulich force-pushed the claude/constant-value-tracer-BTcHn branch from 695f469 to ac7957e Compare April 19, 2026 16:30
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.

1 participant