summaryrefslogtreecommitdiff
path: root/chapter15/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'chapter15/src/main')
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/Parser.java2
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java17
2 files changed, 13 insertions, 6 deletions
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
index b3b1f3c5..2b09e943 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
@@ -813,7 +813,7 @@ public class Parser {
return (ConstantNode) new ConstantNode(_lexer.parseNumber()).peephole();
}
- private Node con( long con ) {
+ public static Node con( long con ) {
return new ConstantNode(TypeInteger.constant(con)).peephole();
}
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java
index 097a899c..28e6dd14 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/node/ShlNode.java
@@ -1,8 +1,8 @@
package com.seaofnodes.simple.node;
+import com.seaofnodes.simple.Parser;
import com.seaofnodes.simple.type.Type;
import com.seaofnodes.simple.type.TypeInteger;
-
import java.util.BitSet;
public class ShlNode extends Node {
@@ -33,11 +33,18 @@ public class ShlNode extends Node {
public Node idealize() {
Node lhs = in(1);
Node rhs = in(2);
- Type t2 = rhs._type;
- // Shl of 0.
- if( t2.isConstant() && t2 instanceof TypeInteger i && (i.value()&63)==0 )
- return lhs;
+ if( rhs._type instanceof TypeInteger shl && shl.isConstant() ) {
+ // Shl of 0.
+ if( (shl.value()&63)==0 )
+ return lhs;
+ // (x + c) << i => (x << i) + (c << i)
+ if( lhs instanceof AddNode add && add.in(2)._type instanceof TypeInteger c && c.isConstant() ) {
+ long sum = c.value() << shl.value();
+ if( Integer.MIN_VALUE <= sum && sum <= Integer.MAX_VALUE )
+ return new AddNode( new ShlNode(add.in(1),rhs).peephole(), Parser.con(sum) );
+ }
+ }
// TODO: x << 3 << (y ? 1 : 2) ==> x << (y ? 4 : 5)