summaryrefslogtreecommitdiff
path: root/chapter25
diff options
context:
space:
mode:
Diffstat (limited to 'chapter25')
-rw-r--r--chapter25/README.md26
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java4
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java3
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetIRISC.java6
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java24
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21AllocTest-testString.smp13
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testAntiDeps1.smp8
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testInfinite.smp2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testStringExport.smp3
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23AllocTest-testString.smp13
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testAndPtr.smp4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFRefFields.smp6
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFuncCall.smp4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testMethod.smp6
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopLocal.smp6
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopMemory.smp8
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24AllocTest-testBubbleSort.smp40
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack3.smp4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack5.smp4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/spill/README.md13
22 files changed, 115 insertions, 86 deletions
diff --git a/chapter25/README.md b/chapter25/README.md
index ec8a8ea8..6d2a376b 100644
--- a/chapter25/README.md
+++ b/chapter25/README.md
@@ -183,21 +183,23 @@ calculation next to the use adds no instruction and avoids preserving a
callee-save register merely to hold the constant. Adjacent uses and multi-use
addresses retain the area/cost ranking.
-Rows are fixed test cohorts; columns are the compiler/allocator chapters. Each
-cell is the sum of `_spillScaled`: retained split moves, including register
-copies, weighted by loopDepth. Lower is better. **# tests counts
-compilations** (program/CPU/ABI cases), including zero-spill cases, rather than
-JUnit methods. The count and membership of each row stay fixed across columns.
+Rows are fixed test cohorts; columns are compiler chapters. Each cell gives
+**Ops / RA / X**: executed ARM+RISC-V instructions, the subset emitted for
+allocator copies/rematerializations, and x86's loop-weighted split-move estimate.
+**Cases D / X** counts measured dynamic program/target cases and x86 compilations;
+membership and inputs stay fixed across columns. Native-library work is excluded.
+Chapter 20 has no encoder, hence no dynamic counts. Lower is better within each
+metric; see the [measurement details](../docs/regalloc-spills.md) for coverage.
<!-- spill-matrix:start -->
-| Test cohort | # tests | Ch 20 | Ch 21 | Ch 22 | Ch 23 | Ch 24 | Ch 25 |
+| Test cohort | Cases D / X | Ch 20: Ops / RA / X | Ch 21: Ops / RA / X | Ch 22: Ops / RA / X | Ch 23: Ops / RA / X | Ch 24: Ops / RA / X | Ch 25: Ops / RA / X |
|---|---:|---:|---:|---:|---:|---:|---:|
-| Ch 20 | 39 | 360 | 576 | 430 | 442 | 441 | 491 |
-| Ch 21 | 52 | | 1,072 | 960 | 961 | 948 | 1,077 |
-| Ch 22 | 26 | | | 63 | 63 | 63 | 71 |
-| Ch 23 | 24 | | | | 103 | 103 | 152 |
-| Ch 24 | 58 | | | | | 1,387 | 1,503 |
-| Ch 25 | 14 | | | | | | 1,862 |
+| Ch 20 | 22 / 13 | — / — / 161 | 55,173 / 5,407 / 174 | 58,751 / 9,099 / 175 | 58,736 / 9,084 / 184 | 58,720 / 9,068 / 183 | 59,043 / 9,094 / 209 |
+| Ch 21 | 20 / 18 | | 6,207 / 261 / 461 | 6,324 / 379 / 475 | 6,326 / 381 / 475 | 6,325 / 380 / 470 | 6,233 / 219 / 533 |
+| Ch 22 | 14 / 8 | | | 198 / 60 / 7 | 194 / 56 / 7 | 194 / 56 / 7 | 332 / 136 / 11 |
+| Ch 23 | 14 / 8 | | | | 630 / 160 / 36 | 630 / 160 / 36 | 1,106 / 442 / 36 |
+| Ch 24 | 36 / 20 | | | | | 4,923 / 1,341 / 790 | 5,044 / 1,470 / 609 |
+| Ch 25 | 2 / 12 | | | | | | 20 / 0 / 1,862 |
<!-- spill-matrix:end -->
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
index 4fbd6840..53494092 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
@@ -17,7 +17,7 @@ public class LoadARM extends MemOpARM {
super(ld, base, idx, off, 0);
}
@Override public String op() { return "ld"+_sz; }
- @Override public RegMask outregmap() { return size() >= 4 ? arm.MEM_MASK : arm.RMASK; }
+ @Override public RegMask outregmap() { return size() >= 4 ? arm.MEM_MASK : arm.WMASK; }
private static final int[] OP_LOADS = new int[]{ Arm64.OP_LOAD_IMM_8, Arm64.OP_LOAD_IMM_16, Arm64.OP_LOAD_IMM_32, Arm64.OP_LOAD_IMM_64, };
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java
index ac21c706..f8e450f6 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java
@@ -18,9 +18,9 @@ public class NotARM extends MachConcreteNode implements MachNode{
// subtracting zero from rs will just yield rs, it sets the zero flag and then it's used in cset
short self = enc.reg(this );
short reg1 = enc.reg(in(1));
- int subs = Arm64.imm_inst(Arm64.OP_SUBS, 0, reg1, self);
+ int subs = Arm64.imm_inst(Arm64.OP_SUBS, 0, reg1, 31);
enc.add4(subs);
- int cset = Arm64.cond_set(Arm64.OP_CSET, 31, Arm64.COND.EQ, 31, reg1);
+ int cset = Arm64.cset(Arm64.OP_CSET, 31, Arm64.COND.EQ, 31, self);
enc.add4(cset);
}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java
index dbe9ceb0..6f499db1 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java
@@ -15,7 +15,8 @@ public class NotRISC extends MachConcreteNode implements MachNode {
@Override public void encoding( Encoding enc ) {
short dst = enc.reg(this );
short src = enc.reg(in(1));
- enc.add4(RiscV.i_type(RiscV.OP_IMM, dst, 2, src, 1));
+ // SEQZ is unsigned: negative nonzero inputs must also produce false.
+ enc.add4(RiscV.i_type(RiscV.OP_IMM, dst, 3, src, 1));
}
@Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)); }
}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetIRISC.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetIRISC.java
index 690e2102..9bc86565 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetIRISC.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetIRISC.java
@@ -7,7 +7,11 @@ import com.seaofnodes.simple.node.Node;
public class SetIRISC extends ImmRISC {
final boolean _unsigned; // slti vs sltiu
public SetIRISC( Node src, int imm12, boolean unsigned ) {
- super(src,imm12);
+ this(src,imm12,unsigned,true);
+ }
+ public SetIRISC( Node src, int imm12, boolean unsigned, boolean pop ) {
+ super(src,imm12,pop);
+ if( !pop ) _inputs.setLen(2);
_unsigned = unsigned;
}
@Override public String op() { return "slt" + (_unsigned ? "u":"") + "i"; }
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
index ae69b439..19b91866 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
@@ -317,7 +317,7 @@ public class riscv extends Machine {
// x <= y - flip and negate; !(y < x); `slt tmp=y,x; xori dst=tmp,#1`
case "<=" -> new XorIRISC(new SetRISC(bool.swap12(), false),1,false);
// x == y - sub and vs0 == `sub tmp=x-y; sltu dst=tmp,#1`
- case "==" -> new SetIRISC(new SubRISC(bool),1,true);
+ case "==" -> new SetIRISC(new SubRISC(bool),1,true,false);
default -> throw Utils.TODO();
};
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java
index ef65c6d9..3e21c73e 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java
@@ -226,19 +226,21 @@ return (10 < something_specific < 20)
String src2 = "return 0 == arg == 1;";
TestC.runC(src, "stacked_r_13x", "1",0);
- // Evaluate on RISC5 emulator
+ // Compile once per target, then check false, true and negative inputs.
EvalRisc5 R5 = TestRisc5.build( src2, "stacked_r_13", 1, 0, false);
- R5.regs[riscv.A1] = 1; // Arg in A1, Test.class in A0
- int trap = R5.step(100);
- assertEquals(0,trap);
- assertEquals(1,R5.regs[riscv.A0]);
-
- // Evaluate on ARM emulator
+ for( int arg : new int[]{-1,0,1} ) {
+ R5._pc = 0;
+ R5.regs[riscv.A1] = arg;
+ assertEquals(0,R5.step(100));
+ assertEquals(arg==0 ? 1 : 0,R5.regs[riscv.A0]);
+ }
EvalArm64 arm = TestArm64.build("stacked_r_13", src2, 1, 0, false);
- arm.regs[1] = 1; // Arg in r1, Test.class in r0
- trap = arm.step(100);
- assertEquals(0,trap);
- assertEquals(1,arm.regs[0]);
+ for( int arg : new int[]{-1,0,1} ) {
+ arm._pc = 0;
+ arm.regs[1] = arg;
+ assertEquals(0,arm.step(100));
+ assertEquals(arg==0 ? 1 : 0,arm.regs[0]);
+ }
}
@Test
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21AllocTest-testString.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21AllocTest-testString.smp
index 586ccb85..a18a5b88 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21AllocTest-testString.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21AllocTest-testString.smp
@@ -1,12 +1,12 @@
// -*- mode: java; -*-
-struct String {
+struct _String {
u8[] cs;
int _hashCode;
- new String = { u8[] data -> cs=data; };
+ new _String = { u8[] data -> cs=data; };
};
// Compare two Strings
-val equals = { !String !self, !String s ->
+val equals = { !_String !self, !_String s ->
if( self == s ) return true;
if( self.cs# != s.cs# ) return false;
for( int i=0; i< self.cs#; i++ )
@@ -16,13 +16,13 @@ val equals = { !String !self, !String s ->
};
// Return the String hashCode (cached, and never 0)
-val hashCode = { !String self ->
+val hashCode = { !_String self ->
self._hashCode
? self._hashCode
: (self._hashCode = _hashCodeString(self));
};
-val _hashCodeString = { !String self ->
+val _hashCodeString = { !_String self ->
int hash=0;
if( self.cs )
for( int i=0; i< self.cs#; i++ )
@@ -30,3 +30,6 @@ val _hashCodeString = { !String self ->
if( !hash ) hash = 123456789;
return hash;
};
+
+// This fixture exports its API, not the last declaration as a result.
+return 0;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testAntiDeps1.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testAntiDeps1.smp
index 950e282d..315cc5b6 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testAntiDeps1.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testAntiDeps1.smp
@@ -1,7 +1,7 @@
-struct S { int f; };
-var v0 = new S;
-!S? !v1;
-if (arg) v1 = new S;
+struct _S { int f; };
+var v0 = new _S;
+!_S? !v1;
+if (arg) v1 = new _S;
if (v1) {
v0.f = v1.f;
} else {
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testInfinite.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testInfinite.smp
index 5e517b61..1804ad59 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testInfinite.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testInfinite.smp
@@ -1 +1 @@
-struct S { int i; }; !S !s = new S; while(1) s.i++;
+struct _S { int i; }; !_S !s = new _S; while(1) s.i++;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testStringExport.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testStringExport.smp
index f3d34b0a..ee5a0560 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testStringExport.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter21Test-testStringExport.smp
@@ -28,3 +28,6 @@ val _hashCodeString = { !String self ->
if( !hash ) hash = 123456789;
return hash;
};
+
+// This fixture exports its API, not the last declaration as a result.
+return 0;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23AllocTest-testString.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23AllocTest-testString.smp
index 4ef375e9..49c80a99 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23AllocTest-testString.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23AllocTest-testString.smp
@@ -1,12 +1,12 @@
// -*- mode: java; -*-
-struct String {
+struct _String {
u8[] cs;
int _hashCode;
- new String = { u8[] data -> cs=data; };
+ new _String = { u8[] data -> cs=data; };
};
// Compare two Strings
-val equals = { !String !self, !String s ->
+val equals = { !_String !self, !_String s ->
if( self == s ) return true;
if( self.cs# != s.cs# ) return false;
for( int i=0; i< self.cs#; i++ )
@@ -16,16 +16,19 @@ val equals = { !String !self, !String s ->
};
// Return the String hashCode (cached, and never 0)
-val hashCode = { !String self ->
+val hashCode = { !_String self ->
self._hashCode
? self._hashCode
: (self._hashCode = _hashCodeString(self));
};
-val _hashCodeString = { !String self ->
+val _hashCodeString = { !_String self ->
int hash=0;
for( int i=0; i< self.cs#; i++ )
hash = hash*31 + self.cs[i];
if( !hash ) hash = 123456789;
return hash;
};
+
+// This fixture exports its API, not the last declaration as a result.
+return 0;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testAndPtr.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testAndPtr.smp
index 556a1375..a1e4e9ab 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testAndPtr.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testAndPtr.smp
@@ -1,8 +1,8 @@
{i32 i64 u32 -> u32} write="C";
val _p={u8[~] str -> i64 ptr=str; return write(1,ptr,str#);};
-struct S { !S? !fld; new S={ !S? f -> fld=f; }; };
+struct _S { !_S? !fld; new _S={ !_S? f -> fld=f; }; };
-val ptr = arg == 1 ? null : new S(arg==1 ? null : new S(null));
+val ptr = arg == 1 ? null : new _S(arg==1 ? null : new _S(null));
if( ptr && ptr.fld ) {
_p("true");
} else {
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFRefFields.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFRefFields.smp
index 00fcb589..eac0a542 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFRefFields.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFRefFields.smp
@@ -1,8 +1,8 @@
// A hypothetical scanner class
-struct Scan {
+struct _Scan {
int !x;
u8[~] buf;
- new Scan={ u8[~] b -> buf=b; };
+ new _Scan={ u8[~] b -> buf=b; };
// Skip whitespace
val skip = { ->
while( buf[x] <= ' ' )
@@ -16,5 +16,5 @@ struct Scan {
return true;
};
};
-!Scan !s = new Scan(" q");
+!_Scan !s = new _Scan(" q");
return s.peek('q');
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFuncCall.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFuncCall.smp
index b522a811..8a7b90d9 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFuncCall.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testFuncCall.smp
@@ -4,11 +4,11 @@ val _p={u8[~] str -> i64 ptr=str; return write(1,ptr,str#);};
int a = 1;
int b = 1;
-var sq = { int x ->
+var _sq = { int x ->
x*x;
};
-if(a && sq(0)) {
+if(a && _sq(0)) {
_p("And");
} else {
_p("Or");
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testMethod.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testMethod.smp
index 27a19988..ced649e3 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testMethod.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testMethod.smp
@@ -1,8 +1,8 @@
// A hypothetical scanner class
-struct Scan {
+struct _Scan {
int !x;
u8[~] buf;
- new Scan={ u8[~] b -> buf=b; };
+ new _Scan={ u8[~] b -> buf=b; };
// Skip whitespace
val skip = { ->
while( buf[x] <= ' ' )
@@ -13,5 +13,5 @@ struct Scan {
buf[x++]==ch;
};
};
-!Scan !s = new Scan(" [1,2]");
+!_Scan !s = new _Scan(" [1,2]");
return s.require('[');
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopLocal.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopLocal.smp
index cf6d93ab..c4e4f9b5 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopLocal.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopLocal.smp
@@ -1,10 +1,10 @@
-struct S { int f; };
+struct _S { int f; };
int x=0;
int result=arg&1;
if(!result) {
- !S !s=new S;
+ !_S !s=new _S;
while(x<3) x++;
s.f=++x;
- result=!!s.f;
+ result=s.f;
}
return x*10+result;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopMemory.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopMemory.smp
index 370bfb8d..79478408 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopMemory.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter23Test-testOrRhsLoopMemory.smp
@@ -1,11 +1,11 @@
-struct S { int f; };
-!S !s=new S;
+struct _S { int f; };
+!_S !s=new _S;
int result=arg&1;
if(!result) {
- !S !t=new S;
+ !_S !t=new _S;
while(s.f<3) s.f++;
s.f++;
t.f=s.f;
- result=!!t.f;
+ result=t.f;
}
return s.f*10+result;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24AllocTest-testBubbleSort.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24AllocTest-testBubbleSort.smp
index 7aeeaa35..f292254e 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24AllocTest-testBubbleSort.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24AllocTest-testBubbleSort.smp
@@ -16,22 +16,22 @@
i32 MAP_PRIVATE = 2;
i32 MAP_ANON = 32;
- val copy = { u8[] dst, int doff, u8[~] src, int soff, int len ->
+ val _copy = { u8[] dst, int doff, u8[~] src, int soff, int len ->
for( int i=0; i<len; i++ )
dst[i+doff] = src[i+soff];
return dst;
};
- struct aryu8 {
+ struct _aryu8 {
u32 !len = 0;
u8[] !buf;
- new aryu8={ u8[] b -> buf=b; };
+ new _aryu8={ u8[] b -> buf=b; };
// Grow as needed
val _grow = { int len2 ->
if( len+len2 < buf# ) return self;
int newlen = buf# * 2;
while( len+len2 >= newlen ) newlen *= 2;
u8[] !buf2 = new u8[newlen];
- copy(buf2,0,buf,0,buf#);
+ _copy(buf2,0,buf,0,buf#);
buf = buf2;
self;
};
@@ -45,7 +45,7 @@
// Add a plain array to the aryu8
val addAry = { u8[~] ary ->
_grow(ary#);
- copy(buf,len,ary,0,ary#);
+ _copy(buf,len,ary,0,ary#);
len += ary#;
self;
};
@@ -75,10 +75,10 @@
// Write to fd, returns the number of bytes written (len).
val write = { i32 fd -> i64 ptr = buf; write(fd,ptr,len); };
};
-struct Scan {
+struct _Scan {
int !x;
u8[~] buf;
- new Scan={ u8[~] b -> buf=b; };
+ new _Scan={ u8[~] b -> buf=b; };
// Skip whitespace
val skip = { ->
@@ -105,10 +105,10 @@ struct Scan {
return neg ? -n : n;
};
};
-struct aryi64 {
+struct _aryi64 {
u32 !len = 0;
i64[] !buf;
- new aryi64={ i64[] b -> buf=b; };
+ new _aryi64={ i64[] b -> buf=b; };
// Grow as needed
val _grow = { int len2 ->
if( len+len2 < buf# ) return self;
@@ -130,17 +130,17 @@ struct aryi64 {
// Write to aryu8
val str = { ->
// TODO: clunky default constructor syntax
- var str = new aryu8(new u8[1]).add('[');
+ var str = new _aryu8(new u8[1]).add('[');
for( int i=0; i<len; i++ )
str.num(buf[i]).add(',').add(' ');
str.undo(2).add(']');
};
};
- val parseAryI64 = { u8[~] str ->
- !Scan !s = new Scan(str);
+ val _parseAryI64 = { u8[~] str ->
+ !_Scan !s = new _Scan(str);
if( !s.match('[') ) return null;
// Array of parsed results
- var nums = new aryi64(new i64[1]);
+ var nums = new _aryi64(new i64[1]);
// Parse a list of numbers
if( !s.match(']') ) { // Handle the empty list
// Parse "123, " until a something else
@@ -156,13 +156,13 @@ struct aryi64 {
// Print string to stdout
- val p = { u8[~] str ->
+ val _p = { u8[~] str ->
i64 ptr = str; // cast array base to i64
return write(1,ptr,str#);
};
// Return stdin as a u8[]
- val stdin = { ->
+ val _stdin = { ->
var buf = new u8[8*1024];
i64 ptr = buf;
int len = 0;
@@ -176,7 +176,7 @@ struct aryi64 {
}
// Compress
var dst = new u8[len];
- return copy(dst,0,buf,0,len);
+ return _copy(dst,0,buf,0,len);
};
// -*- mode: java; -*-
@@ -185,7 +185,7 @@ struct aryi64 {
//
// Bubble sort, with reading (parsing) and writing (formatting) the data.
-val sort = { !aryi64 nums ->
+val _sort = { !_aryi64 nums ->
var done = false;
while( !done ) {
done = true;
@@ -202,14 +202,14 @@ val sort = { !aryi64 nums ->
// Read from stdin a line of the form "[ 4, 3, 2, 1]" and print it sorted.
val main = { ->
// Parse array of numbers from stdin
- var nums = parseAryI64( stdin() );
+ var nums = _parseAryI64( _stdin() );
if( !nums ) {
- p("stdin must look like [4, 3, 2, 1]");
+ _p("stdin must look like [4, 3, 2, 1]");
return 1;
}
// Bubble sort array of integers
- sort(nums);
+ _sort(nums);
// Print a list of numbers to stdout
nums.str().write(1);
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack3.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack3.smp
index 6a3db406..4700f8ce 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack3.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack3.smp
@@ -1,11 +1,11 @@
{i32 i64 u32 -> u32} write="C";
val _p={u8[~] str -> i64 ptr=str; return write(1,ptr,str#);};
-var sq = { int x ->
+var _sq = { int x ->
x*x;
};
int score = 5;
-val str = (sq(2) <= score < sq(3)) ? "In Range" : "Out of range";
+val str = (_sq(2) <= score < _sq(3)) ? "In Range" : "Out of range";
_p(str);
return 0;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack5.smp b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack5.smp
index e4660752..3c2c4208 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack5.smp
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/Chapter24Test-testStack5.smp
@@ -1,12 +1,12 @@
{i32 i64 u32 -> u32} write="C";
val _p={u8[~] str -> i64 ptr=str; return write(1,ptr,str#);};
-var sq = { int x ->
+var _sq = { int x ->
x*x;
};
int score = 5;
-if (sq(2) <= score < sq(3)) {
+if (_sq(2) <= score < _sq(3)) {
_p("In Range");
} else {
_p("Out of range");
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/spill/README.md b/chapter25/src/test/java/com/seaofnodes/simple/spill/README.md
index 08371ae9..b5ab9d80 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/spill/README.md
+++ b/chapter25/src/test/java/com/seaofnodes/simple/spill/README.md
@@ -35,7 +35,10 @@ Chapter 25 cannot parse all earlier sources unchanged. Adaptations are explicit:
sources are a new comparison baseline; their totals cannot be compared as
identical inputs with the earlier constructor-free fixtures.
- The two short-circuit RHS initializer loops become equivalent guarded blocks,
- preserving allocation, side effects, and the final result.
+ preserving allocation, side effects, and the final result. Their RHS assigns
+ the field value directly: Simple's `||` returns an operand, not a normalized
+ boolean. The 2026-10-07 cleanup removes an erroneous `!!` in those adaptations;
+ both fixtures return 44 for even arguments and 1 for odd arguments.
- Simple I/O cases include the old `write` binding and print helper directly.
Bubble Sort includes the old library bodies, with namespace prefixes flattened,
explicit constructors, and mutable replacement buffers. This retains the old
@@ -50,6 +53,14 @@ Chapter 25 cannot parse all earlier sources unchanged. Adaptations are explicit:
StringExport, Person and the C-return wrappers, retain their public names.
These visibility adaptations change the generated workload and are recorded
separately from the allocator improvement in the cross-chapter comparison.
+- The remaining visibility cleanup makes local classes/functions private in
+ AntiDeps1, Infinite, the Chapter 21/23 allocation String cases, the Chapter 23
+ scanner/pointer/short-circuit/function cases, and Stack3/Stack5. Bubble Sort's
+ copied library implementation is private; its `main` stays public. The three
+ adapted String API fixtures end in `return 0;`, avoiding an accidental return
+ of the last declared function. Their equality/hash APIs stay public, and the
+ named StringExport fixture also keeps its public String factory. No cohort
+ entries, workload operations, or intentional export APIs are removed.
- Other source texts are retained.
All entries replay **through RegAlloc**, checking scheduled register constraints.