From d32f97238c903765dec4e9a9f3cbfa5fd12cded6 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Mon, 10 Aug 2026 11:11:18 -0700 Subject: Chapter 25: Modules, Separate Compilation, and SSA Construction Co-authored-by: Hsiang-Ying Fu <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: fuhsnn <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: Symious <14933944+symious@users.noreply.github.com> Co-authored-by: Jun Kawasaki Co-authored-by: Claude Opus 5 --- .../java/com/seaofnodes/simple/SpillStats.java | 83 +++++++++++++--------- 1 file changed, 51 insertions(+), 32 deletions(-) (limited to 'src/test/java/com/seaofnodes/simple/SpillStats.java') diff --git a/src/test/java/com/seaofnodes/simple/SpillStats.java b/src/test/java/com/seaofnodes/simple/SpillStats.java index ad044a52..d43f1a36 100644 --- a/src/test/java/com/seaofnodes/simple/SpillStats.java +++ b/src/test/java/com/seaofnodes/simple/SpillStats.java @@ -1,13 +1,15 @@ package com.seaofnodes.simple; import com.seaofnodes.simple.codegen.CodeGen; +import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen; +import com.seaofnodes.simple.type.TypeInteger; +import java.nio.file.*; import java.util.Map; import java.util.TreeMap; import org.junit.runner.*; import org.junit.runner.notification.*; -// Run existing tests and sum actual allocations, including ones without goldens. -// Helpers call record after allocation; ordinary JUnit runs collect nothing. +// Earlier cohorts freeze source/target membership; Chapter 25 retains native checks. public class SpillStats extends RunListener { private static SpillStats ACTIVE; private Description _test; @@ -15,30 +17,25 @@ public class SpillStats extends RunListener { private final Map _totals = new TreeMap<>(); @Override public void testStarted(Description test) { _test = test; } - public static void record(CodeGen code, String cohort, String cpu, String abi) { - if( ACTIVE==null ) return; - String test = ACTIVE._test.getTestClass().getSimpleName()+"."+ACTIVE._test.getMethodName(); + @Override public void testFinished(Description test) { _test = null; } + + public static void record25(CodeGen code) { + if( ACTIVE==null || ACTIVE._test==null || ACTIVE._test.getTestClass()!=Chapter25Test.class ) return; + ACTIVE.record(code,"Chapter25",ACTIVE._test.getMethodName(),code._mach.getClass().getSimpleName(),code._callingConv); + } + + private void record(CodeGen code, String cohort, String test, String cpu, String abi) { for( String key : new String[]{cohort+","+cpu+","+abi,cohort+",ALL,ALL"} ) { - long[] sum = ACTIVE._totals.computeIfAbsent(key,k -> new long[3]); + long[] sum = _totals.computeIfAbsent(key,k -> new long[3]); sum[0]++; sum[1] += code._regAlloc._spills; sum[2] += code._regAlloc._spillScaled; } System.out.println("allocation,"+cohort+","+test+","+cpu+","+abi+","+ code._regAlloc._spills+","+code._regAlloc._spillScaled); } - // The same native helpers serve old and new program cohorts. - public static void recordNative(CodeGen code, String cpu, String abi) { - String cohort = ACTIVE!=null && (ACTIVE._test.getTestClass()==Chapter24Test.class || ACTIVE._test.getTestClass()==Chapter24AllocTest.class) - ? "Chapter24" : ACTIVE!=null && ACTIVE._test.getTestClass()==Chapter23Test.class - ? "Chapter23" : ACTIVE!=null && ACTIVE._test.getTestClass()==Chapter22Test.class - ? "Chapter22" : "Chapter21"; - record(code,cohort,cpu,abi); - } - - // Keep running every CPU and native result check when measuring quality. - // A changed golden still makes spill-stats fail at the end. + // Keep native result checks running during a quality comparison. public static void checkSpills(int expected, int actual) { - if( expected==-1 ) return; + if( expected==-1 || CodeGen.iterSeedOverridden() ) return; try { org.junit.Assert.assertEquals("Expect spills:",expected,actual,Math.max(1,expected>>3)); } catch( AssertionError error ) { if( ACTIVE==null ) throw error; @@ -47,27 +44,49 @@ public class SpillStats extends RunListener { } } - public static void main(String[] args) throws ClassNotFoundException { - if( args.length==0 ) args = new String[]{"Chapter20Test","Chapter21Test","Chapter21AllocTest","Chapter22Test","Chapter23Test","Chapter23AllocTest","Chapter24Test","Chapter24AllocTest","BrainFuckTest","MergeSortTest"}; - Class[] tests = new Class[args.length]; - for( int i=0; i