From dc77490c735104497851ed8c12ae5c713ab05b04 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Sun, 30 Jun 2024 01:58:08 +0100 Subject: Chapter 11: Global Code Motion Co-authored-by: Dibyendu Majumdar Co-authored-by: Thalia Archibald Co-authored-by: Robert Obkircher --- src/main/java/com/seaofnodes/simple/Parser.java | 50 +++++++++++++++++-------- 1 file changed, 35 insertions(+), 15 deletions(-) (limited to 'src/main/java/com/seaofnodes/simple/Parser.java') diff --git a/src/main/java/com/seaofnodes/simple/Parser.java b/src/main/java/com/seaofnodes/simple/Parser.java index fc84c9d9..e367f499 100644 --- a/src/main/java/com/seaofnodes/simple/Parser.java +++ b/src/main/java/com/seaofnodes/simple/Parser.java @@ -23,8 +23,14 @@ public class Parser { */ public static StartNode START; + public static ConstantNode ZERO; + public static XCtrlNode XCTRL; + public StopNode STOP; + // Debugger Printing. + public static boolean SCHEDULED; // True if debug printer can use schedule info + // The Lexer. Thin wrapper over a byte[] buffer with a cursor. private final Lexer _lexer; @@ -77,11 +83,14 @@ public class Parser { Node.reset(); IterPeeps.reset(); OBJS.clear(); + SCHEDULED = false; _lexer = new Lexer(source); _scope = new ScopeNode(); _continueScope = _breakScope = null; START = new StartNode(new Type[]{ Type.CONTROL, arg }); STOP = new StopNode(source); + ZERO = new ConstantNode(TypeInteger.constant(0)).peephole().keep(); + XCTRL= new XCtrlNode().peephole().keep(); } public Parser(String source) { @@ -105,9 +114,11 @@ public class Parser { _xScopes.push(_scope); // Enter a new scope for the initial control and arguments _scope.push(); - _scope.define(ScopeNode.CTRL, Type.CONTROL , new ProjNode(START, 0, ScopeNode.CTRL).peephole()); - _scope.define(ScopeNode.ARG0, TypeInteger.BOT, new ProjNode(START, 1, ScopeNode.ARG0).peephole()); + _scope.define(ScopeNode.CTRL, Type.CONTROL , new CProjNode(START, 0, ScopeNode.CTRL).peephole()); + _scope.define(ScopeNode.ARG0, TypeInteger.BOT, new ProjNode(START, 1, ScopeNode.ARG0).peephole()); parseBlock(); + if( ctrl()._type==Type.CONTROL ) + STOP.addReturn(new ReturnNode(ctrl(), new ConstantNode(TypeInteger.constant(0)).peephole(), _scope).peephole()); _scope.pop(); _xScopes.pop(); if (!_lexer.isEOF()) throw error("Syntax error, unexpected " + _lexer.getAnyNextToken()); @@ -236,8 +247,8 @@ public class Parser { // IfNode takes current control and predicate Node ifNode = new IfNode(ctrl(), pred).peephole(); // Setup projection nodes - Node ifT = new ProjNode(ifNode. keep(), 0, "True" ).peephole().keep(); - Node ifF = new ProjNode(ifNode.unkeep(), 1, "False").peephole(); + Node ifT = new CProjNode(ifNode. keep(), 0, "True" ).peephole().keep(); + Node ifF = new CProjNode(ifNode.unkeep(), 1, "False").peephole(); // Clone the body Scope to create the break/exit Scope which accounts for any // side effects in the predicate. The break/exit Scope will be the final @@ -283,7 +294,7 @@ public class Parser { private ScopeNode jumpTo(ScopeNode toScope) { ScopeNode cur = _scope.dup(); - ctrl(new ConstantNode(Type.XCONTROL).peephole()); // Kill current scope + ctrl(XCTRL); // Kill current scope // Prune nested lexical scopes that have depth > than the loop head // We use _breakScope as a proxy for the loop head scope to obtain the depth while( cur._scopes.size() > _breakScope._scopes.size() ) @@ -319,8 +330,8 @@ public class Parser { // IfNode takes current control and predicate Node ifNode = new IfNode(ctrl(), pred).peephole(); // Setup projection nodes - Node ifT = new ProjNode(ifNode. keep(), 0, "True" ).peephole().keep(); - Node ifF = new ProjNode(ifNode.unkeep(), 1, "False").peephole().keep(); + Node ifT = new CProjNode(ifNode. keep(), 0, "True" ).peephole().keep(); + Node ifF = new CProjNode(ifNode.unkeep(), 1, "False").peephole().keep(); // In if true branch, the ifT proj node becomes the ctrl // But first clone the scope and set it as current int ndefs = _scope.nIns(); @@ -366,7 +377,7 @@ public class Parser { private Node parseReturn() { var expr = require(parseExpression(), ";"); Node ret = STOP.addReturn(new ReturnNode(ctrl(), expr, _scope).peephole()); - ctrl(new ConstantNode(Type.XCONTROL).peephole()); // Kill control + ctrl(XCTRL); // Kill control return ret; } @@ -568,7 +579,7 @@ public class Parser { if( _lexer.isNumber() ) return parseIntegerLiteral(); if( match("(") ) return require(parseExpression(), ")"); if( matchx("true" ) ) return new ConstantNode(TypeInteger.constant(1)).peephole(); - if( matchx("false") ) return new ConstantNode(TypeInteger.constant(0)).peephole(); + if( matchx("false") ) return ZERO; if( matchx("null" ) ) return new ConstantNode(TypeMemPtr.NULLPTR).peephole(); if( matchx("new") ) { String structName = requireId(); @@ -586,12 +597,11 @@ public class Parser { /** * Return a NewNode but also generate instructions to initialize it. */ - private Node newStruct( TypeStruct obj ) { + private Node newStruct(TypeStruct obj) { Node n = new NewNode(TypeMemPtr.make(obj), ctrl()).peephole().keep(); - Node initValue = new ConstantNode(TypeInteger.constant(0)).peephole(); int alias = START._aliasStarts.get(obj._name); for( Field field : obj._fields ) { - memAlias(alias, new StoreNode(field._fname, alias, memAlias(alias), n, initValue).peephole()); + memAlias(alias, new StoreNode(field._fname, alias, ctrl(), memAlias(alias), n, ZERO).peephole()); alias++; } return n.unkeep(); @@ -629,7 +639,7 @@ public class Parser { if( peek('=') ) _lexer._position--; else { Node val = parseExpression(); - memAlias(alias, new StoreNode(name, alias, memAlias(alias), expr, val).peephole()); + memAlias(alias, new StoreNode(name, alias, ctrl(), memAlias(alias), expr, val).peephole()); return expr; // "obj.a = expr" returns the expression while updating memory } } @@ -740,7 +750,16 @@ public class Parser { * Return the next non-white-space character */ private void skipWhiteSpace() { - while (isWhiteSpace()) _position++; + while( true ) { + if( isWhiteSpace() ) _position++; + // Skip // to end of line + else if( _position+2 < _input.length && + _input[_position ] == '/' && + _input[_position+1] == '/') { + _position += 2; + while( !isEOF() && _input[_position] != '\n' ) _position++; + } else break; + } } @@ -822,8 +841,9 @@ public class Parser { return new String(_input, start, --_position - start); } + // private boolean isPunctuation(char ch) { - return "=;[]<>(){}+-/*!".indexOf(ch) != -1; + return "=;[]<>()+-/*".indexOf(ch) != -1; } private String parsePunctuation() { -- cgit v1.2.3