diff options
Diffstat (limited to 'chapter22/src/main/java')
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; } |
