summaryrefslogtreecommitdiff
path: root/chapter22/src/main
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-05-11 11:43:10 -0700
committerCliff Click <cliffc@acm.org>2025-05-11 11:43:10 -0700
commitef7577136b942819d4cff2f8c63605744e854f75 (patch)
tree5f75d92e208a1a8f696c0c175af135d8532d7c8b /chapter22/src/main
parentaeb86e64bdc72232b0cc7edd28e81344a7e1a3b4 (diff)
downloadSimple-ef7577136b942819d4cff2f8c63605744e854f75.tar.gz
Simple-ef7577136b942819d4cff2f8c63605744e854f75.zip
Clean up stacked mergemem
Diffstat (limited to 'chapter22/src/main')
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java32
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java7
2 files changed, 30 insertions, 9 deletions
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java
index e936ee58..9f2fdd16 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java
@@ -65,24 +65,38 @@ public class MemMergeNode extends Node {
@Override public Node idealize() {
if( inProgress() ) return null;
+ // Fold defaults into the default
+ boolean progress=false, allDefault=true;
+ for( int i=2; i<nIns(); i++ )
+ if( in(1) == in(i) ) { setDef(i,null); progress=true; }
+ else { allDefault=false; }
+
// If not merging any memory (all memory is just the default)
- if( allDefault() )
+ if( allDefault )
return in(1); // Become default memory
- return null;
- }
- private boolean allDefault() {
- for( int i=2; i<nIns(); i++ )
- if( in(1) != in(i) )
- return false;
- return true;
+ // Collapse stacked all-mem
+ if( in(1) instanceof MemMergeNode mem ) {
+ // Goal is to swap my default mem with mem's default mem
+ for( int i=2; i<mem.nIns(); i++ ) {
+ if( mem.in(i) != null ) {
+ // deeper default mem has a non-default
+ if( i>=nIns() || in(i)==null )
+ setDefX(i,mem.in(i));
+ }
+ }
+ setDef(1,mem.in(1));
+ return this;
+ }
+
+ return progress ? this : null;
}
public Node in( Var v ) { return in(v._idx); }
public Node alias( int alias ) {
- return in(alias<nIns() && in(alias)!=null ? alias : 1);
+ return alias < nIns() && in(alias)!=null ? in(alias) : in(1);
}
Node alias( int alias, Node st ) {
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java
index 2e9e38d5..9b561bed 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java
@@ -71,6 +71,12 @@ public class StoreNode extends MemOpNode {
return this;
}
+ // Simple store-after-MemMerge to a known alias can bypass. Happens when inlining.
+ if( mem() instanceof MemMergeNode mem ) {
+ setDef(1,mem.alias(_alias));
+ return this;
+ }
+
// Value is automatically truncated by narrow store
if( val() instanceof AndNode and && and.in(2)._type.isConstant() ) {
int log = _declaredType.log_size();
@@ -84,6 +90,7 @@ public class StoreNode extends MemOpNode {
}
}
+ // Store will chop high order bits off; math to change those bits can be dropped.
if( val() instanceof SarNode shr &&
shr.in(1) instanceof ShlNode shl &&
shr.in(2)._type.isConstant() &&