summaryrefslogtreecommitdiff
path: root/chapter22/src/main/java/com/seaofnodes
diff options
context:
space:
mode:
Diffstat (limited to 'chapter22/src/main/java/com/seaofnodes')
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/Parser.java53
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java5
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java6
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/ShlNode.java11
5 files changed, 41 insertions, 36 deletions
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
index bbf841c8..5b9a3820 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
@@ -132,34 +132,17 @@ public class Parser {
private <N extends Node> N ctrl(N n) { return _scope.ctrl(n); }
public void parse() {
- _scope.define(ScopeNode.CTRL, Type.CONTROL , false, null, null);
- _scope.define(ScopeNode.MEM0, TypeMem.BOT , false, null, null);
- _scope.define(ScopeNode.ARG0, TypeInteger.BOT, false, null, null);
+ _lexer = new Lexer(_code._src);
+ _xScopes.push(_scope);
+ _scope.define(ScopeNode.CTRL, Type.CONTROL , false, null, _lexer);
+ _scope.define(ScopeNode.MEM0, TypeMem.BOT , false, null, _lexer);
+ _scope.define(ScopeNode.ARG0, TypeInteger.BOT, false, null, _lexer);
ctrl(XCTRL);
_scope.mem(new MemMergeNode(false));
- // Parse the "sys" import
- //_parse(com.seaofnodes.simple.sys.sys.SYS);
-
- _code._stop.popUntil(0); // Delete return from parsing sys import
-
- // Parse program text
- _parse(_code._src);
-
- // Clean up and reset
- _scope.kill();
- for( StructNode init : INITS.values() )
- init.unkeep().kill();
- INITS.clear();
- _code._stop.peephole();
- }
-
- private void _parse(String src) {
- _lexer = new Lexer(src);
- _xScopes.push(_scope);
-
// Parse whole program, as-if function header "{ int arg -> body }"
+
parseFunctionBody(_code._main,loc(),"arg");
// Kill an empty default main. Keep only if it was explicitly defined
@@ -167,9 +150,10 @@ public class Parser {
// default main).
FunNode main = _code.link(_code._main);
StopNode stop = _code._stop;
- if( main.ret().expr() instanceof ConstantNode && main.ret().mem().in(0)==main && stop.nIns() > 1 ) {
+ if( main.ret().expr()._type==Type.TOP ) {
// Kill an empty default main; so it does not attempt to put a
// "main" in any final ELF file
+ main.setDef(1,XCTRL); // Delete default start input
stop.delDef(stop._inputs.find(main.ret()));
} else {
// We have a non-empty default main.
@@ -185,6 +169,11 @@ public class Parser {
// Clean up and reset
_xScopes.pop();
+ _scope.kill();
+ for( StructNode init : INITS.values() )
+ init.unkeep().kill();
+ INITS.clear();
+ stop.peephole();
}
/**
@@ -233,13 +222,22 @@ public class Parser {
_scope.define(ids[i], t, false, new ParmNode(ids[i],i+2,t,fun,con(t)).peephole(), loc);
}
+ //// If top-level parser, parse the sys import
+ //if( fun.sig()==_code._main ) {
+ // Lexer old = _lexer;
+ // _lexer = new Lexer(com.seaofnodes.simple.sys.sys.SYS);
+ // while(!_lexer.isEOF() )
+ // parseStatement();
+ // _lexer = old;
+ //}
+
// Parse the body
Node last=ZERO;
while (!peek('}') && !_lexer.isEOF())
last = parseStatement();
- // Last expression is the return
- if( ctrl()._type==Type.CONTROL )
+ // Last expression is the return except for the top-level main
+ if( ctrl()._type==Type.CONTROL && fun.sig() != _code._main )
fun.addReturn(ctrl(), _scope.mem().merge(), last);
// Pop off the inProgress node on the multi-exit Region merge
@@ -1286,9 +1284,8 @@ public class Parser {
throw error("Accessing unknown field '" + name + "' from 'null'");
// Sanity check expr for being a reference
- if( !(expr._type instanceof TypeMemPtr ptr) ) {
+ if( !(expr._type instanceof TypeMemPtr ptr) )
throw error( "Expected "+(name=="#" || name=="[]" ? "array" : "reference")+" but found " + expr._type.str() );
- }
// Find the field from the Type. Lookup in the base object field names.
TypeStruct base = ptr._obj;
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
index bf6d67b0..26f2e522 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
@@ -111,7 +111,7 @@ public class CodeGen {
return TypeFunPtr.make((byte)2,sig,ret, 1L<<fidx );
}
// Signature for MAIN
- public TypeFunPtr _main = makeFun(TypeTuple.MAIN,Type.BOTTOM);
+ public final TypeFunPtr _main = makeFun(TypeTuple.MAIN,Type.BOTTOM);
// Reverse from a constant function pointer to the IR function being called
public FunNode link( TypeFunPtr tfp ) {
assert tfp.isConstant();
@@ -269,7 +269,8 @@ public class CodeGen {
var map = new IdentityHashMap<Node,Node>();
_instSelect( _stop, map );
_stop = ( StopNode)map.get(_stop );
- _start = (StartNode)map.get(_start);
+ StartNode start = (StartNode)map.get(_start);
+ _start = start==null ? new StartNode(_start) : start;
_instOuts(_stop,visit());
_visit.clear();
_tInsSel = (int)(System.currentTimeMillis() - t0);
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
index d7057839..bc7de99a 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
@@ -185,12 +185,10 @@ public class Encoding {
Ary<CFGNode> rpo = new Ary<>(CFGNode.class);
rpos.put(_code._start.loop(),rpo);
BitSet visit = _code.visit();
- //IdentityHashMap<CFGNode,LoopNode> looptail = new IdentityHashMap<>();
rpo.add(_code._stop);
for( Node n : _code._start._outputs )
if( n instanceof FunNode fun ) {
int x = rpo._len;
- //_rpo_cfg2(fun, visit, rpo, looptail);
_rpo_cfg(fun, visit, rpos );
assert rpo.at(x) instanceof ReturnNode;
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java
index c477e125..5a356185 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java
@@ -72,7 +72,9 @@ public class FunNode extends RegionNode {
@Override
public Type compute() {
// Only dead if no callers after SCCP
- return Type.CONTROL;
+ if( unknownCallers() )
+ return Type.CONTROL;
+ return super.compute();
}
@Override
@@ -118,7 +120,7 @@ public class FunNode extends RegionNode {
@Override public CFGNode idom(Node dep) { return cfg(1); }
// Always in-progress until we run out of unknown callers
- public boolean unknownCallers() { return in(1) instanceof StartNode; }
+ public boolean unknownCallers() { return nIns()<2 || in(1) instanceof StartNode; }
@Override public boolean inProgress() { return unknownCallers(); }
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/ShlNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/ShlNode.java
index 82e01841..39a2698a 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/ShlNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/ShlNode.java
@@ -22,8 +22,15 @@ public class ShlNode extends LogicalNode {
t2 instanceof TypeInteger i1 ) {
if( i0 == TypeInteger.ZERO )
return TypeInteger.ZERO;
- if( i0.isConstant() && i1.isConstant() )
- return TypeInteger.constant(i0.value()<<i1.value());
+ if( i1.isConstant() ) {
+ int shf = (int)i1.value();
+ if( i0.isConstant() )
+ return TypeInteger.constant(i0.value()<<shf);
+ // If no overflow, shift endpoints
+ if( !(((i0._min<<shf)>>shf) != i0._min ||
+ ((i0._max<<shf)>>shf) != i0._max ) )
+ return TypeInteger.make(i0._min<<shf,i0._max<<shf);
+ }
}
return TypeInteger.BOT;
}