diff options
Diffstat (limited to 'chapter23/src/main/java/com')
8 files changed, 63 insertions, 21 deletions
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/Parser.java b/chapter23/src/main/java/com/seaofnodes/simple/Parser.java index 1db873e0..ffd4bfe9 100644 --- a/chapter23/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter23/src/main/java/com/seaofnodes/simple/Parser.java @@ -530,11 +530,11 @@ public class Parser { // Parse predicate require("("); var pred = require(parseAsgn(), ")"); - return parseTrinary(pred,true,"else"); + return parseTrinary(pred,"else"); } // Parse a conditional expression, merging results. - private Node parseTrinary( Node pred, boolean stmt, String fside ) { + private Node parseTrinary( Node pred, String fside ) { pred.keep(); // IfNode takes current control and predicate @@ -550,7 +550,15 @@ public class Parser { // Parse the true side ctrl(ifT.unkeep()); // set ctrl token to ifTrue projection _scope.addGuards(ifT,pred,false); // Up-cast predicate - Node lhs = (stmt ? parseStatement() : parseAsgn()).keep(); // Parse true-side + // Parse true-side flavor + Node lhs = switch( fside ) { + case "else" -> parseStatement(); // if( pred ) stmts; + case ":" -> parseAsgn(); // pred ? asgn; + case "&&" -> parseLogical(); // pred && expr + case "||" -> pred; // pred || expr_is_ignored + default -> throw Utils.TODO(); + }; + lhs.keep(); _scope.removeGuards(ifT); // See if a one-sided def was made: "if(pred) int x = 1;" and throw. @@ -566,17 +574,23 @@ public class Parser { // Up-cast predicate, even if not else clause, because predicate can // remain true if the true clause exits: `if( !ptr ) return 0; return ptr.fld;` _scope.addGuards(ifF,pred,true); - boolean doRHS = match(fside); - Node rhs = (doRHS - ? (stmt ? parseStatement() : parseAsgn()) - : con(lhs._type.makeZero())).keep(); + // Parse false-side flavor + boolean doRHS = false; // RHS is optional for if/else and trinary + Node rhs = switch( fside ) { + case "else" -> (doRHS=match(fside)) ? parseStatement() : con(lhs._type.makeZero()); + case ":" -> (doRHS=match(fside)) ? parseAsgn() : con(lhs._type.makeZero()); + case "&&" -> rhs = pred; + case "||" -> rhs = parseLogical(); + default -> throw Utils.TODO(); + }; + rhs.keep(); _scope.removeGuards(ifF); if( doRHS ) fScope = _scope; pred.unkeep(); // Check the trinary widening int/flt - if( !stmt ) { + if( !fside.equals("else") ) { rhs = widenInt( rhs.unkeep(), lhs._type ).keep(); lhs = widenInt( lhs.unkeep(), rhs._type ).keep(); } @@ -593,7 +607,7 @@ public class Parser { Node ret = peep(new PhiNode("",lhs._type.meet(rhs._type).glb(false),r,lhs.unkeep(),rhs.unkeep())); // Immediately fail e.g. `arg ? 7 : ptr` ParseException err; - if( !stmt && (err=ret.err()) !=null ) throw err; + if( !fside.equals("else") && (err=ret.err()) !=null ) throw err; r.peephole(); return ret; } @@ -993,8 +1007,8 @@ public class Parser { * @return an expression {@link Node}, never {@code null} */ private Node parseExpression() { - Node expr = parseBitwise(); - return match("?") ? parseTrinary(expr,false,":") : expr; + Node expr = parseLogical(); + return match("?") ? parseTrinary(expr,":") : expr; } /** @@ -1005,13 +1019,25 @@ public class Parser { * </pre> * @return a bitwise expression {@link Node}, never {@code null} */ + + private Node parseLogical() { + Node lhs = parseBitwise(); + while (true) { + if( false ) ; + else if( match("&&") ) lhs = parseTrinary(lhs, "&&"); + else if( match("||") ) lhs = parseTrinary(lhs, "||"); + else break; + } + return lhs; + } + private Node parseBitwise() { Node lhs = parseComparison(); while( true ) { if( false ) ; - else if( match("&") ) lhs = new AndNode(loc(),lhs,null); - else if( match("|") ) lhs = new OrNode(loc(),lhs,null); - else if( match("^") ) lhs = new XorNode(loc(),lhs,null); + else if( matchOp('&') ) lhs = new AndNode(loc(),lhs,null); + else if( matchOp('|') ) lhs = new OrNode(loc(),lhs,null); + else if( match ("^") ) lhs = new XorNode(loc(),lhs,null); else break; lhs.setDef(2,parseComparison()); lhs = peep(lhs); @@ -1701,6 +1727,7 @@ public class Parser { private boolean match (String syntax) { return _lexer.match (syntax); } // Match must be "exact", not be followed by more id letters private boolean matchx(String syntax) { return _lexer.matchx(syntax); } + private boolean matchOp(char c0 ) { return _lexer.matchOp(c0); } private boolean matchOpx(char c0, char c1) { return _lexer.matchOpx(c0,c1); } // Return true and do NOT skip if 'ch' is next private boolean peek(char ch) { return _lexer.peek(ch); } @@ -1876,6 +1903,15 @@ public class Parser { _position -= syntax.length(); return false; } + // Match this char, and the next char must be different. + // Handles '&&' vs '&' + boolean matchOp( char c0 ) { + skipWhiteSpace(); + if( _position+1 >= _input.length || _input[_position]!=c0 || _input[_position+1]==c0 ) + return false; + inc(); + return true; + } // Match these two characters in a row boolean matchOpx(char c0, char c1) { skipWhiteSpace(); diff --git a/chapter23/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter23/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java index caa7ff44..6c958f32 100644 --- a/chapter23/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java +++ b/chapter23/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java @@ -39,6 +39,8 @@ public class CodeGen { // --------------------------- public CodeGen( String src ) { this(src, TypeInteger.BOT, 123L, true ); } + public CodeGen( String src, TypeInteger arg) { this(src, arg==null ? TypeInteger.BOT : arg, 123L, true ); } + public CodeGen( String src, TypeInteger arg, long workListSeed, boolean reset ) { CODE = this; if( reset ) Type.reset(); diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/CallEndNode.java b/chapter23/src/main/java/com/seaofnodes/simple/node/CallEndNode.java index b75852a4..d95af697 100644 --- a/chapter23/src/main/java/com/seaofnodes/simple/node/CallEndNode.java +++ b/chapter23/src/main/java/com/seaofnodes/simple/node/CallEndNode.java @@ -86,6 +86,11 @@ public class CallEndNode extends CFGNode implements MultiNode { fun.setDef(2,call.ctrl()); // Bypass the Call; fun.ret().setDef(3,null); // Return is folding also CodeGen.CODE.addAll(fun._outputs); + // Repeat defs 1 layer down, for users of Parm (Phis) + for( Node parm : fun._outputs ) + if( parm instanceof ParmNode ) + CodeGen.CODE.addAll(parm._outputs); + // Inlining immediately blows all cache idepth fields past the inline point. // Bump the global version number invalidating them en-masse. CodeGen.CODE.invalidateIDepthCaches(); diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java index a2cb9bba..427cf2e2 100644 --- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java +++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java @@ -42,9 +42,9 @@ public class CallARM extends CallNode implements MachNode, RIPRelSize { } @Override public void asm(CodeGen code, SB sb) { - sb.p(_name); + sb.p(_name).p(" "); for( int i=0; i<nargs(); i++ ) - sb.p(code.reg(arg(i+2))).p(" "); + sb.p(code.reg(arg(i+2))).p(", "); sb.unchar(2); } } diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java index a3e1cf19..c84aa9e5 100644 --- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java +++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java @@ -25,7 +25,7 @@ public class CallRRARM extends CallNode implements MachNode { @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(fptr())).p(" "); for( int i=0; i<nargs(); i++ ) - sb.p(code.reg(arg(i))).p(" "); + sb.p(code.reg(arg(i))).p(", "); sb.unchar(2); } diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java index a676ba60..bd5dabe5 100644 --- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java +++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java @@ -57,7 +57,6 @@ public class CallRISC extends CallNode implements MachNode, RIPRelSize { sb.p(_name).p(" "); for( int i=0; i<nargs(); i++ ) sb.p(code.reg(arg(i+2))).p(", "); - sb.unchar(2).p(" ").p(code.reg(fptr())); - + sb.unchar(2); } } diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java index ac36ed12..298789e8 100644 --- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java +++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java @@ -25,7 +25,7 @@ public class CallRRISC extends CallNode implements MachNode { @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(fptr())).p(" "); for( int i=0; i<nargs(); i++ ) - sb.p(code.reg(arg(i))).p(" "); + sb.p(code.reg(arg(i))).p(", "); sb.unchar(2); } } diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java index ffdce7df..d74e3833 100644 --- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java +++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java @@ -42,7 +42,7 @@ public class CallX86 extends CallNode implements MachNode, RIPRelSize { @Override public void asm(CodeGen code, SB sb) { sb.p(_name).p(" "); for( int i=0; i<nargs(); i++ ) - sb.p(code.reg(in(i+2))).p(" "); + sb.p(code.reg(in(i+2))).p(", "); sb.unchar(2); } } |
