summaryrefslogtreecommitdiff
path: root/chapter25/src
diff options
context:
space:
mode:
Diffstat (limited to 'chapter25/src')
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/IterPeeps.java37
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java16
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java4
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java21
-rw-r--r--chapter25/src/main/smp/sys.smp1
-rw-r--r--chapter25/src/main/smp/sys/adt.smp1
-rw-r--r--chapter25/src/main/smp/sys/adt/bitset.smp1
-rw-r--r--chapter25/src/main/smp/sys/ary.smp1
-rw-r--r--chapter25/src/main/smp/sys/aryi64.smp1
-rw-r--r--chapter25/src/main/smp/sys/aryu8.smp1
-rw-r--r--chapter25/src/main/smp/sys/char.smp1
-rw-r--r--chapter25/src/main/smp/sys/io.smp1
-rw-r--r--chapter25/src/main/smp/sys/libc.smp1
-rw-r--r--chapter25/src/main/smp/sys/scan.smp1
14 files changed, 47 insertions, 41 deletions
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/IterPeeps.java b/chapter25/src/main/java/com/seaofnodes/simple/IterPeeps.java
index 532f5c70..83616053 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/IterPeeps.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/IterPeeps.java
@@ -62,16 +62,10 @@ public class IterPeeps {
public void addAll( Ary<Node> ary ) { _work.addAll(ary); }
- public void deferInline( CodeGen code, CallEndNode cend ) {
- if( !code._midAssert )
- _workInline.push(cend);
- }
-
/**
* Iterate peepholes and inlining to a fixed point
*/
public void iterate( CodeGen code ) {
- CallEndNode cend = null;
boolean didInline = false;
Ary<Node> defer = new Ary<>(Node.class);
while( true ) {
@@ -79,18 +73,19 @@ public class IterPeeps {
iteratePeeps(code);
// Pick an inline candidate, no real heuristic, first come, first served
+ boolean inlined = false;
+ CallEndNode cend;
while( (cend=_workInline.pop()) != null) {
if( cend.isDead() ) continue;
- if( cend.inline() == -1 ) defer.add(cend);
- if( cend.inline() > 0 ) break;
- }
- // Found an inline candidate, so inline
- if( cend != null ) {
- // Inline, run peeps until clean again
- cend.doInline();
- didInline = true;
- continue;
+ byte inline = cend.maybeInline();
+ if( inline == -1 ) defer.add(cend);
+ if( inline > 0 ) {
+ inlined = true;
+ break;
+ }
}
+ // Inlined, run peeps until clean again
+ if( inlined ) { didInline = true; continue; }
// No more candidates, check the defer list
if( !didInline ) break; // No more progress, so all the "maybe inline after cleanup" do not progress
// Some inlining happened, retry all the "try again after cleanup" calls
@@ -102,7 +97,7 @@ public class IterPeeps {
// Run all the code-reduction and type-lifting peeps as possible
private void iteratePeeps( CodeGen code ) {
- assert progressOnList(code, _work, true);
+ assert !CodeGen.expensiveAssert(1) || progressOnList(code, _work, true);
int cnt=0;
Node n;
@@ -110,6 +105,8 @@ public class IterPeeps {
if( n.isDead() ) continue;
cnt++; // Useful for debugging, searching which peephole broke things
Node x = n.peepholeOpt();
+ if( n instanceof CallEndNode cend )
+ _workInline.push(cend);
if( x != null ) {
if( x.isDead() ) continue;
// peepholeOpt can return brand-new nodes, needing an initial type set
@@ -136,7 +133,8 @@ public class IterPeeps {
// If there are distant neighbors, move to worklist
n.moveDepsToWorklist();
JSViewer.show(); // Show again
- assert progressOnList(code, _work, true); // Very expensive assert
+ // Very expensive assert.
+ assert !CodeGen.expensiveAssert(cnt) || progressOnList(code, _work, true);
}
if( n.isUnused() && !(n instanceof StopNode) )
n.kill(); // Just plain dead
@@ -174,6 +172,11 @@ public class IterPeeps {
assert !checkType || monotonic : "Non-monotonic peep: "+n+"#"+n._nid+" old="+n._type+" new="+nval+" inputs="+inputTypes(n)+" peep="+m;
if( list.on(n) )
return null;
+ if( n instanceof CallEndNode cend ) {
+ if( code._iter._workInline.on(cend) )
+ return null;
+ assert cend.maybeInline() <= 0 : "Inline fired and not on worklist, CallEndNode#"+cend._nid;
+ }
assert n.nOuts() > 0 : "Unused live node: "+n;
m = n.peepholeOpt();
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
index 50f5c33b..bcefe996 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
@@ -45,6 +45,19 @@ public class CodeGen {
/** True when tests deliberately randomize Iter worklist order. */
public static boolean iterSeedOverridden() { return System.getProperty("simple.iter.seed") != null; }
+ // Expensive assert sampling:
+ // -Dsimple.assert.expensive=0 disables these checks
+ // -Dsimple.assert.expensive=1 checks every step
+ // -Dsimple.assert.expensive=N checks once every 1<<N steps
+ private static final int EXPENSIVE_ASSERT_LOG = Integer.getInteger("simple.assert.expensive",8);
+ public static boolean expensiveAssert() { return EXPENSIVE_ASSERT_LOG > 0; }
+ public static boolean expensiveAssert( int trip ) {
+ if( EXPENSIVE_ASSERT_LOG <= 0 ) return false;
+ if( EXPENSIVE_ASSERT_LOG == 1 ) return true;
+ int shift = Math.min(EXPENSIVE_ASSERT_LOG,30);
+ return (trip & ((1<<shift)-1)) == 0;
+ }
+
// ---------------------------
// Module Source Root
public final String _modDir;
@@ -458,7 +471,8 @@ public class CodeGen {
return null;
});
_iter.iterate(this);
- assert Opto.fixedPointCheck(this);
+ // Expensive assert.
+ assert !expensiveAssert() || Opto.fixedPointCheck(this);
_times[Phase.Iter.ordinal()] = System.currentTimeMillis() - t0;
return this;
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java b/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java
index 5d4c151d..e8062c90 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java
@@ -246,8 +246,8 @@ abstract public class Opto {
// Since n._type changed, visit all output neighbors
code._iter.addAll(n._outputs);
n.moveDepsToWorklist(code._iter);
- // Quadratic (expensive) small-step assert
- assert worklistCheck(code);
+ // Quadratic (expensive) small-step assert.
+ assert !CodeGen.expensiveAssert(count) || worklistCheck(code);
}
}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java
index 061232c7..c9029049 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java
@@ -133,19 +133,18 @@ public class CallEndNode extends CFGNode implements MultiNode {
@Override
public Node idealize() {
+ return null;
+ }
- _inline = inlineCandidate();
- if( _inline == 1 ) {
- ReturnNode ret = (ReturnNode)in(1);
- FunNode fun = ret.fun();
- doTrivialInlining(fun);
- return this;
- }
- // Delay for cleanup, before cloning
- if( _inline >= 2 )
- CodeGen.CODE._iter.deferInline(CodeGen.CODE,this);
+ public byte maybeInline() {
+ byte inline = inlineCandidate();
+ if( CodeGen.CODE._midAssert )
+ return inline;
+ _inline = inline;
+ if( _inline > 0 )
+ doInline();
- return null;
+ return _inline;
}
// Check if candidate right now, sets no flags
diff --git a/chapter25/src/main/smp/sys.smp b/chapter25/src/main/smp/sys.smp
index 8aef5b68..7705a187 100644
--- a/chapter25/src/main/smp/sys.smp
+++ b/chapter25/src/main/smp/sys.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
// top-level default standard library import
diff --git a/chapter25/src/main/smp/sys/adt.smp b/chapter25/src/main/smp/sys/adt.smp
index efdad395..a4fe40bf 100644
--- a/chapter25/src/main/smp/sys/adt.smp
+++ b/chapter25/src/main/smp/sys/adt.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
// Abstract data types.
val bitset = bitset;
diff --git a/chapter25/src/main/smp/sys/adt/bitset.smp b/chapter25/src/main/smp/sys/adt/bitset.smp
index f56f1cce..d02cd2fe 100644
--- a/chapter25/src/main/smp/sys/adt/bitset.smp
+++ b/chapter25/src/main/smp/sys/adt/bitset.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
// A set of non-negative integers, represented one bit per value.
struct bitset {
diff --git a/chapter25/src/main/smp/sys/ary.smp b/chapter25/src/main/smp/sys/ary.smp
index feade0f5..8312e94c 100644
--- a/chapter25/src/main/smp/sys/ary.smp
+++ b/chapter25/src/main/smp/sys/ary.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
// Array utilities
diff --git a/chapter25/src/main/smp/sys/aryi64.smp b/chapter25/src/main/smp/sys/aryi64.smp
index e4c39ac3..22ee082e 100644
--- a/chapter25/src/main/smp/sys/aryi64.smp
+++ b/chapter25/src/main/smp/sys/aryi64.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
// Ary/Vector of i64s
struct aryi64 {
diff --git a/chapter25/src/main/smp/sys/aryu8.smp b/chapter25/src/main/smp/sys/aryu8.smp
index 186a45a3..21cf920b 100644
--- a/chapter25/src/main/smp/sys/aryu8.smp
+++ b/chapter25/src/main/smp/sys/aryu8.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
// Ary/Vector of u8s - a resizable array of bytes.
struct aryu8 {
diff --git a/chapter25/src/main/smp/sys/char.smp b/chapter25/src/main/smp/sys/char.smp
index de37968e..22ca4213 100644
--- a/chapter25/src/main/smp/sys/char.smp
+++ b/chapter25/src/main/smp/sys/char.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
val toupper = { u8 c ->
return c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c;
diff --git a/chapter25/src/main/smp/sys/io.smp b/chapter25/src/main/smp/sys/io.smp
index 3d6be512..33fbdb5e 100644
--- a/chapter25/src/main/smp/sys/io.smp
+++ b/chapter25/src/main/smp/sys/io.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
// Simple I/O Library
diff --git a/chapter25/src/main/smp/sys/libc.smp b/chapter25/src/main/smp/sys/libc.smp
index 6d750f7b..133b5bf7 100644
--- a/chapter25/src/main/smp/sys/libc.smp
+++ b/chapter25/src/main/smp/sys/libc.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
// libc bindings:
// https://www.man7.org/linux/man-pages/man2/<libc call>.2.html
diff --git a/chapter25/src/main/smp/sys/scan.smp b/chapter25/src/main/smp/sys/scan.smp
index ba91003e..44bedaaa 100644
--- a/chapter25/src/main/smp/sys/scan.smp
+++ b/chapter25/src/main/smp/sys/scan.smp
@@ -1,4 +1,3 @@
-// -*- mode: java; -*-
// Scanner; a simple string parser.
struct scan {