From 89dd0a79da85b2c7102b7c8918a1466e6238fe94 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Fri, 13 Jun 2025 15:42:08 -0700 Subject: Chapter 24a: SCCP Within a Function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tamás Hadházy <85063808+Hels15@users.noreply.github.com> Co-authored-by: Hsiang-Ying Fu <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: fuhsnn <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: Symious <14933944+symious@users.noreply.github.com> Co-authored-by: Jun Kawasaki Co-authored-by: Hadházy Tamás Co-authored-by: Claude Opus 5 --- src/main/java/com/seaofnodes/simple/Parser.java | 38 +++++++++++++++++-------- 1 file changed, 26 insertions(+), 12 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 1bd1a74d..81c7be32 100644 --- a/src/main/java/com/seaofnodes/simple/Parser.java +++ b/src/main/java/com/seaofnodes/simple/Parser.java @@ -133,7 +133,7 @@ public class Parser { public void parse() { // Graph callbacks during scope setup need a source position. - _lexer = new Lexer(com.seaofnodes.simple.sys.SYS); + _lexer = new Lexer(sys.SYS); _scope.define(ScopeNode.CTRL, Type.CONTROL , false, null, _lexer); _scope.define(ScopeNode.MEM0, TypeMem.BOT , false, null, _lexer); @@ -160,18 +160,26 @@ public class Parser { // default main). FunNode main = _code.link(_code._main); StopNode stop = _code._stop; + // Gather an explicit main + FunNode xmain = null; + for( Node n : stop._inputs ) + if( n instanceof ReturnNode ret && "main".equals(ret.fun()._name) ) + if( xmain != null ) throw Utils.TODO(); + else xmain = ret.fun(); + if( main.ret().expr()._type==Type.TOP && main.uctrl()==null ) { // 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())); + if( xmain != null ) + _code.setMain(xmain); + } else { // We have a non-empty default main. - // Check for an explicit main - for( Node n : stop._inputs ) - if( n instanceof FunNode fun && fun._name.equals("main") ) - // Found an explicit "main" AND we have a default "main" - throw error("Cannot define both an explicit main and a default main"); + if( xmain != null ) + // Found an explicit "main" AND we have a default "main" + throw error("Cannot define both an explicit main and a default main"); main._name = "main"; } @@ -540,9 +548,8 @@ public class Parser { // Parse a conditional expression, merging results. private Node parseTrinary( Node pred, String fside ) { - pred.keep(); - // IfNode takes current control and predicate + pred.keep(); Node ifNode = new IfNode(ctrl(), pred).peephole(); // Setup projection nodes Node ifT = new CProjNode(ifNode. keep(), 0, "True" ).peephole().keep(); @@ -708,7 +715,7 @@ public class Parser { // Type is sane if( et!=Type.BOTTOM && (!et.shallowISA(t) || !et.accessISA(t)) ) - expr = peep(new CastNode(t,null,expr)); + expr = peep(new CastNode(t.isConstant() ? t : t.widen(),null,expr)); return expr; } @@ -822,7 +829,7 @@ public class Parser { // Lift type to the declaration. This will report as an error later if // we cannot lift the type. if( !lift._type.isa(t) ) - lift = peep(new CastNode(t,null,lift)); + lift = peep(new CastNode(t.widen(),null,lift)); // Define a new name if( !_scope.define(name,t,xfinal || fld_final,lift, loc) ) throw error("Redefining name '" + name + "'", loc); @@ -1063,6 +1070,11 @@ public class Parser { return lhs; } + + + /** + * Parse an eq/ne expression + */ private Node parseEquality() { Node lhs = parseComparison(); while( true ) { @@ -1081,7 +1093,8 @@ public class Parser { * Parse an expression of the form: * *
-     *     expr : additiveExpr op additiveExpr
+     *     expr : shiftExpr < shiftExpr <= shiftExpr...
+     *     expr : shiftExpr > shiftExpr >= shiftExpr...
      * 
* @return an comparator expression {@link Node}, never {@code null} */ @@ -1584,6 +1597,8 @@ public class Parser { Type tf = f._t; if( tf instanceof TypeMemPtr ftmp && ftmp.isFRef() ) tf = ftmp.makeFrom(((TypeMemPtr)(TYPES.get(ftmp._obj._name)))._obj); + if( base.isAry() && tf instanceof TypeConAry con ) + tf = con.elem(); expr.keep(); // Field offset; fixed for structs, computed for arrays @@ -1746,7 +1761,6 @@ public class Parser { // Into the call CallNode call = (CallNode)new CallNode(loc(), args.asAry()).peephole(); - // Post-call setup CallEndNode cend = (CallEndNode)new CallEndNode(call).peephole(); call.peephole(); // Rerun peeps after CallEnd, allows early inlining -- cgit v1.2.3