diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/BuildLRG.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/BuildLRG.java index 003d26e..1b4f17b 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/BuildLRG.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/BuildLRG.java @@ -64,7 +64,7 @@ public static boolean run(int round, RegAlloc alloc) { } // MultiNodes have projections which set registers - if( n instanceof MultiNode ) + if( n instanceof MultiNode && !(n instanceof CFGNode) ) for( Node proj : n.outs() ) if( proj instanceof MachNode ) defLRG(alloc,proj); diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/CodeGen.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/CodeGen.java index d7eaa3a..fa890bd 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/CodeGen.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/CodeGen.java @@ -90,6 +90,24 @@ public int getUID() { public int getALIAS() { return _alias++; } + // idepths are cached and valid until *inserting* CFG edges (deleting is + // OK). This happens with inlining, which bumps the version to bulk + // invalidate the idepth caches. + private int _iDepthVersion = 0; + public void invalidateIDepthCaches() { _iDepthVersion++; } + public boolean validIDepth(int idepth) { + if( idepth==0 ) return false; + if( _iDepthVersion==0 ) return true; + return (idepth%100)==_iDepthVersion; + } + public int iDepthAt(int idepth) { + return 100*idepth+_iDepthVersion; + } + public int iDepthFrom(int idepth) { + assert idepth==0 || validIDepth(idepth); + return idepth+100; + } + // Popular visit bitset, declared here, so it gets reused all over public final BitSet _visit = new BitSet(); public BitSet visit() { assert _visit.isEmpty(); return _visit; } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/Encoding.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/Encoding.java index 53f20ed..1fc124e 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/Encoding.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/Encoding.java @@ -323,7 +323,6 @@ private void writeEncodings() { if( !(bb instanceof MachNode mach0) ) _opStart[bb._nid] = _bits.size(); else if( bb instanceof FunNode fun ) { - padN(16,_bits); _fun = fun; // Currently encoding function _opStart[bb._nid] = _bits.size(); mach0.encoding( this ); @@ -337,7 +336,6 @@ else if( bb instanceof FunNode fun ) { } } } - padN(16,_bits); } // -------------------------------------------------- diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/GlobalCodeMotion.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/GlobalCodeMotion.java index deba31f..627e7e0 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/GlobalCodeMotion.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/GlobalCodeMotion.java @@ -167,6 +167,8 @@ private static void breadth(Node stop, Node[] ns, CFGNode[] late) { !(memuse instanceof NewNode) && // Load-use directly defines memory (memuse._type instanceof SONTypeMem || + // Load-use directly defines memory + memuse instanceof CallNode || // Load-use indirectly defines memory (memuse._type instanceof SONTypeTuple tt && tt._types[ld._alias] instanceof SONTypeMem)) ) continue outer; @@ -200,6 +202,33 @@ private static void _doSchedLate(Node n, Node[] ns, CFGNode[] late) { if( n instanceof MemOpNode load && load._isLoad ) lca = find_anti_dep(lca,load,early,late); + + // Nodes setting a single register and getting killed will stay close + // to the uses, since they will be forced to spill anyway. The kill + // check is very weak, and some may be hoisted only to spill in the RA. + if( n instanceof MachNode mach ) { + RegMask out = mach.outregmap(); + if( out!=null && out.size1() ) { + int reg = mach.outregmap().firstReg(); + // Look for kills + outer: + for( CFGNode lca2=lca; lca2 != early; lca2 = lca2.idom() ) { + if( lca2 instanceof MachNode mach2 ) { + for( int i=1; i best.idepth() || best instanceof IfNode); + lca instanceof NeverNode || + lca.idepth() > best.idepth() || + best instanceof IfNode; } private static CFGNode find_anti_dep(CFGNode lca, MemOpNode load, CFGNode early, CFGNode[] late) { @@ -249,9 +279,9 @@ private static CFGNode find_anti_dep(CFGNode lca, MemOpNode load, CFGNode early, lca = anti_dep( load, late[mem._nid], mem.cfg0(), lca, st ); } break; // Loads do not cause anti-deps on other loads - case CallNode st: - assert late[st._nid]!=null; - lca = anti_dep(load,late[st._nid],st.cfg0(),lca,st); + case CallNode call: + assert late[call._nid]!=null; + lca = anti_dep(load,late[call._nid],call.cfg0(),lca,call); break; case PhiNode phi: // Repeat anti-dep for matching Phi inputs. diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/IFG.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/IFG.java index 37005a7..4868c13 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/IFG.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/IFG.java @@ -241,14 +241,12 @@ private static void selfConflict(RegAlloc alloc, Node n, LRG lrg, Node prior) { private static void mergeLiveOut( RegAlloc alloc, CFGNode priorbb, int i ) { CFGNode bb = priorbb.cfg(i); if( bb == null ) return; // Start has no prior - if( !bb.blockHead() ) bb = bb.cfg0(); - //if( i==0 && !(bb instanceof StartNode) ) bb = bb.cfg0(); - assert bb.blockHead(); + while( !bb.blockHead() ) bb = bb.cfg0(); // Lazy get live-out set for bb - IdentityHashMap lrgs = BBOUTS.computeIfAbsent( bb, k -> new IdentityHashMap<>() ); + IdentityHashMap lrgs = BBOUTS.computeIfAbsent( bb, k -> new IdentityHashMap<>() ); - for( LRG lrg : TMP.keySet() ) { + for( LRG lrg : TMP.keySet() ) { Node def = TMP.get(lrg); // Effective def comes from phi input from prior block if( def instanceof PhiNode phi && phi.cfg0()==priorbb ) { diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/Machine.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/Machine.java index b04ddbe..4115e57 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/Machine.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/Machine.java @@ -16,8 +16,12 @@ abstract public class Machine { public abstract long callerSave(); // List of never-save registers, e.g. RSP or a ZERO register if you have one public abstract long neverSave(); - // Call Argument Mask - public abstract RegMask callArgMask(SONTypeFunPtr tfp, int arg); + // Call Argument Mask. Passed in the function signature and argument + // number (2-based; 0 is for control and 1 for memory). Also passed in a 0 + // for the function itself, or for *outgoing* calls, the maximum stack slot + // given to the incoming function arguments (stack slots reserved for + // incoming arguments). + public abstract RegMask callArgMask(SONTypeFunPtr tfp, int arg, int maxArgSlot); // Return register mask, based on signature (GPR vs FPR) public abstract RegMask retMask(SONTypeFunPtr tfp); // Return PC register diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RegAlloc.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RegAlloc.java index 5c01edf..0c778d5 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RegAlloc.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RegAlloc.java @@ -261,7 +261,7 @@ boolean splitEmptyMaskSimple( byte round, LRG lrg ) { } // Single-def live range with an empty mask. There are many single-reg - // uses. Theory is there's many repeats if the same reg amongst the uses. + // uses. Theory is there's many repeats of the same reg amongst the uses. // In of splitting once per use, start by splitting into groups based on // required input register. boolean splitEmptyMaskByUse( byte round, LRG lrg ) { @@ -270,35 +270,45 @@ boolean splitEmptyMaskByUse( byte round, LRG lrg ) { // Look at each use, and break into non-overlapping register classes. Ary rclass = new Ary<>(RegMask.class); boolean done=false; + int ncalls=0; while( !done ) { done = true; for( Node use : def._outputs ) - if( use instanceof MachNode mach ) + if( use instanceof MachNode mach ) { + if( mach instanceof CallNode ) ncalls++; for( int i=1; i 1 ) return false; - // Split by class + // Split by classh + Ary ns = new Ary<>(Node.class); for( RegMask rmask : rclass ) { + ns.addAll(def._outputs); Node split = makeSplit(def,"popular",round,lrg); split.insertAfter( def ); if( split.nIns()>1 ) split.setDef(1,def); // all uses by class to split - for( int j=0; j < def._outputs._len; j++ ) { - Node use = def._outputs.at(j); + for( Node use : ns ) { if( use instanceof MachNode mach && use!=split ) { // Check all use inputs for n, in case there's several for( int i = 1; i < use.nIns(); i++ ) // Find a def input, and check register class - if( use.in( i ) == def && mach.regmap( i ).overlap( rmask ) ) - // Modify use to use the split version specialized to this rclass - { use.setDef( i, split ); j--; break; } + if( use.in( i ) == def ) { + RegMask m = mach.regmap( i ); + if( m!=null && mach.regmap( i ).overlap( rmask ) ) + // Modify use to use the split version specialized to this rclass + use.setDefOrdered( i, split ); + } } } + ns.clear(); } return true; } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RegMask.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RegMask.java index 1e7faff..d38e002 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RegMask.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RegMask.java @@ -4,11 +4,11 @@ import com.compilerprogramming.ezlang.compiler.SB; /** RegMask - * A "register mask" - 1 bit set for each allowed register. In addition + * A "register mask" - 1 bit set for each allowed register. In addition, * "stack slot" registers may be allowed, effectively making the set infinite. *

* For smaller and simpler machines it suffices to make such masks an i64 or - * i128 (64 or 128 bit integers), and this presentation is by far the better + * i128 (64- or 128-bit integers), and this presentation is by far the better * way to go... if all register allocations can fit in this bit limitation. * The allocator will need bits for stack-based parameters and for splits * which cannot get a register. For a 32-register machine like the X86, add 1 @@ -28,7 +28,7 @@ public class RegMask { public RegMask(int bit) { if( bit < 64 ) _bits0 = 1L<...} */ public int _idepth; - public int idepth() { return _idepth==0 ? (_idepth=idom().idepth()+1) : _idepth; } + public int idepth() { + return CodeGen.CODE.validIDepth(_idepth) ? _idepth : (_idepth=CodeGen.CODE.iDepthFrom(idom().idepth())); + } // Return the immediate dominator of this Node and compute dom tree depth. public CFGNode idom(Node dep) { return cfg(0); } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/CallEndNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/CallEndNode.java index 07c2aa8..f2db2a9 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/CallEndNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/CallEndNode.java @@ -59,7 +59,7 @@ public Node idealize() { // Trivial inlining: call site calls a single function; single function // is only called by this call site. - if( !_folding && nIns()==2 && in(0) instanceof CallNode call ) { + if( false && !_folding && nIns()==2 && in(0) instanceof CallNode call ) { Node fptr = call.fptr(); if( fptr.nOuts() == 1 && // Only user is this call fptr instanceof ConstantNode && // We have an immediate call @@ -74,8 +74,9 @@ public Node idealize() { assert fun.in(1) instanceof StartNode && fun.in(2)==call; // Disallow self-recursive inlining (loop unrolling by another name) CFGNode idom = call; - while( !(idom instanceof FunNode fun2) ) + while( !(idom instanceof FunNode) ) idom = idom.idom(); + // Inline? if( idom != fun ) { // Trivial inline: rewrite _folding = true; @@ -85,6 +86,9 @@ public Node idealize() { fun.setDef(2,call.ctrl()); // Bypass the Call; fun.ret().setDef(3,null); // Return is folding also CodeGen.CODE.addAll(fun._outputs); + // Inlining immediately blows all cache idepth fields past the inline point. + // Bump the global version number invalidating them en-masse. + CodeGen.CODE.invalidateIDepthCaches(); return this; } } else { diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/CallNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/CallNode.java index 56902cf..5f88fd4 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/CallNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/CallNode.java @@ -138,7 +138,7 @@ public void unlink_all() { assert linked(fun); int idx = fun._inputs.find(this); for( Node use : fun._outputs ) - if( use instanceof ParmNode parm ) + if( use instanceof ParmNode ) use.delDef(idx); fun.delDef(idx); cend().delDef(cend()._inputs.find(fun.ret())); diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/FunNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/FunNode.java index 9992008..7e12aaf 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/FunNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/FunNode.java @@ -88,6 +88,7 @@ public Node idealize() { // Upgrade inferred or user-written return type to actual if( _ret!=null && _ret._type instanceof SONTypeTuple tt && tt.ret() != _sig.ret() ) + // FIXME Dibyendu //throw Utils.TODO(); return null; @@ -113,8 +114,11 @@ public Node idealize() { return null; } - // Bypass Region idom, always assume depth == 1, one more than Start - @Override public int idepth() { return (_idepth=1); } + // Bypass Region idom, always assume depth == 1, one more than Start, + // unless folding then just a ID on input#1 + @Override public int idepth() { + return _folding ? super.idepth() : CodeGen.CODE.iDepthAt(1); + } // Bypass Region idom, always assume idom is Start @Override public CFGNode idom(Node dep) { return cfg(1); } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/LoopNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/LoopNode.java index 4ff533c..a912ba8 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/LoopNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/LoopNode.java @@ -21,7 +21,9 @@ public SONType compute() { } // Bypass Region idom, same as the default idom() using use in(1) instead of in(0) - @Override public int idepth() { return _idepth==0 ? (_idepth=idom().idepth()+1) : _idepth; } + public int idepth() { + return CodeGen.CODE.validIDepth(_idepth) ? _idepth : (_idepth=CodeGen.CODE.iDepthFrom(idom().idepth())); + } // Bypass Region idom, same as the default idom() using use in(1) instead of in(0) @Override public CFGNode idom(Node dep) { return entry(); } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/NewNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/NewNode.java index 8048e02..1d7ca33 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/NewNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/NewNode.java @@ -92,8 +92,8 @@ public SONTypeTuple compute() { private RegMask _retMask; private RegMask _kills; public void cacheRegs(CodeGen code) { - _arg2Reg = code._mach.callArgMask(SONTypeFunPtr.CALLOC,2).firstReg(); - _arg3Mask = code._mach.callArgMask(SONTypeFunPtr.CALLOC,3); + _arg2Reg = code._mach.callArgMask(SONTypeFunPtr.CALLOC,2,0).firstReg(); + _arg3Mask = code._mach.callArgMask(SONTypeFunPtr.CALLOC,3,0); // Return mask depends on TFP (either GPR or FPR) _retMask = code._mach.retMask(SONTypeFunPtr.CALLOC); // Kill mask is all caller-saves, and any mirror stack slots for args diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/PhiNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/PhiNode.java index 903f792..9ac7bb8 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/PhiNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/PhiNode.java @@ -14,7 +14,7 @@ public class PhiNode extends Node { final SONType _declaredType; public PhiNode(String label, SONType declaredType, Node... inputs) { super(inputs); _label = label; assert declaredType!=null; _declaredType = declaredType; } - public PhiNode(PhiNode phi, String label, SONType declaredType) { super(phi); _label = label; _declaredType = declaredType; } + public PhiNode(PhiNode phi, String label, SONType declaredType) { super(phi); _label = label; _type = _declaredType = declaredType; } public PhiNode(PhiNode phi) { super(phi); _label = phi._label; _declaredType = phi._declaredType; } public PhiNode(RegionNode r, Node sample) { diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/RegionNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/RegionNode.java index 34fa3cd..f193b2c 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/RegionNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/RegionNode.java @@ -137,12 +137,13 @@ boolean hasMidUser(RegionNode r) { // Immediate dominator of Region is a little more complicated. @Override public int idepth() { - if( _idepth!=0 ) return _idepth; + if( CodeGen.CODE.validIDepth(_idepth) ) + return _idepth; int d=0; for( Node n : _inputs ) if( n!=null ) - d = Math.max(d,((CFGNode)n).idepth()+1); - return _idepth=d; + d = Math.max(d,CodeGen.CODE.iDepthFrom(((CFGNode)n).idepth())); + return _idepth = d; } @Override public CFGNode idom(Node dep) { diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/ReturnNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/ReturnNode.java index 065bdcb..b63280a 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/ReturnNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/ReturnNode.java @@ -61,7 +61,9 @@ public SONType compute() { if( inProgress () ) return null; if( _fun.isDead() ) return null; -// // Upgrade signature based on return type + // Upgrade signature based on return type + // FIXME Dibyendu - EZ lang does not support modifying function signature + // but we should probably do the checking? // SONType ret = expr()._type; // SONTypeFunPtr fcn = _fun.sig(); // assert ret.isa(fcn.ret()); diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/StartNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/StartNode.java index ac9053f..5908301 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/StartNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/StartNode.java @@ -51,7 +51,7 @@ public StringBuilder _print1(StringBuilder sb, BitSet visited) { @Override public Node idealize() { return null; } // No immediate dominator, and idepth==0 - @Override public int idepth() { return 0; } + @Override public int idepth() { return CodeGen.CODE.iDepthAt(0); } @Override public CFGNode idom(Node dep) { return null; } } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/StoreNode.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/StoreNode.java index 8d2c679..a37af4f 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/StoreNode.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/StoreNode.java @@ -86,6 +86,11 @@ public Node idealize() { } } + // Store of zero after alloc + if( mem() instanceof ProjNode prj && prj.in(0) instanceof NewNode && + prj.in(0)==ptr().in(0) && // Same NewNode memory & pointer + (val()._type==SONTypeInteger.ZERO || val()._type==SONType.NIL ) ) + return mem(); return null; } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/CallARM.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/CallARM.java index 94722aa..f85e62d 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/CallARM.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/CallARM.java @@ -21,7 +21,7 @@ public class CallARM extends CallNode implements MachNode, RIPRelSize { @Override public String label() { return op(); } @Override public String name() { return _name; } @Override public SONTypeFunPtr tfp() { return _tfp; } - @Override public RegMask regmap(int i) { return arm.callInMask(_tfp,i); } + @Override public RegMask regmap(int i) { return arm.callInMask(_tfp,i,fun()._maxArgSlot); } @Override public RegMask outregmap() { return null; } @Override public void encoding( Encoding enc ) { diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/CallRRARM.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/CallRRARM.java index 71f9382..7b32cbf 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/CallRRARM.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/CallRRARM.java @@ -11,7 +11,7 @@ public class CallRRARM extends CallNode implements MachNode { @Override public RegMask regmap(int i) { return i==_inputs._len ? arm.RMASK // Function call target - : arm.callInMask(tfp(),i); // Normal argument + : arm.callInMask(tfp(),i,fun()._maxArgSlot); // Normal argument } @Override public RegMask outregmap() { return null; } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/ParmARM.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/ParmARM.java index 2761799..acba277 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/ParmARM.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/ParmARM.java @@ -9,7 +9,7 @@ public class ParmARM extends ParmNode implements MachNode { final RegMask _rmask; ParmARM(ParmNode parm) { super(parm); - _rmask = arm.callInMask(fun().sig(),_idx); + _rmask = arm.callInMask(fun().sig(),_idx,0); } @Override public RegMask regmap(int i) { return null; } @Override public RegMask outregmap() { return _rmask; } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/arm.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/arm.java index 928d2e6..e9b6644 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/arm.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/arm/arm.java @@ -563,8 +563,8 @@ public static int b_calloc(int opcode, int delta) { return (opcode << 26) | delta; } - @Override public RegMask callArgMask(SONTypeFunPtr tfp, int idx ) { return callInMask(tfp,idx); } - static RegMask callInMask(SONTypeFunPtr tfp, int idx ) { + @Override public RegMask callArgMask(SONTypeFunPtr tfp, int idx, int maxArgSlot ) { return callInMask(tfp,idx,maxArgSlot); } + static RegMask callInMask(SONTypeFunPtr tfp, int idx, int maxArgSlot ) { if( idx==0 ) return CodeGen.CODE._rpcMask; if( idx==1 ) return null; // Count floats in signature up to index @@ -788,8 +788,7 @@ private Node lsr(ShrNode lsr) { private static int off; private static Node idx; private Node st(StoreNode st) { - Node xval = st.val() instanceof ConstantNode con && con._con == SONTypeInteger.ZERO ? null : st.val(); - return new StoreARM(address(st),st.ptr(),idx,off,xval); + return new StoreARM(address(st),st.ptr(),idx,off,st.val()); } // Gather addressing mode bits prior to constructing. This is a builder diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/CallRISC.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/CallRISC.java index 292cf6a..457ca77 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/CallRISC.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/CallRISC.java @@ -19,9 +19,9 @@ public class CallRISC extends CallNode implements MachNode, RIPRelSize { @Override public String op() { return "call"; } @Override public String label() { return op(); } @Override public RegMask regmap(int i) { - return riscv.callInMask(_tfp,i); + return riscv.callInMask(_tfp,i,fun()._maxArgSlot); } - @Override public RegMask outregmap() { return riscv.RPC_MASK; } + @Override public RegMask outregmap() { return null; } @Override public String name() { return _name; } @Override public SONTypeFunPtr tfp() { return _tfp; } @@ -29,8 +29,7 @@ public class CallRISC extends CallNode implements MachNode, RIPRelSize { // Short form +/-4K: beq r0,r0,imm12 // Long form: auipc rX,imm20/32; jal r0,[rX+imm12/32] enc.relo(this); - short rpc = enc.reg(this); - enc.add4(riscv.j_type(riscv.OP_JAL, rpc, 0)); + enc.add4(riscv.j_type(riscv.OP_JAL, riscv.RPC, 0)); } // Delta is from opcode start @@ -42,9 +41,8 @@ public class CallRISC extends CallNode implements MachNode, RIPRelSize { // Delta is from opcode start @Override public void patch( Encoding enc, int opStart, int opLen, int delta ) { - short rpc = enc.reg(this); if( opLen==4 ) { - enc.patch4(opStart,riscv.j_type(riscv.OP_JAL, rpc, delta)); + enc.patch4(opStart,riscv.j_type(riscv.OP_JAL, riscv.RPC, delta)); } else { throw Utils.TODO(); } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/CallRRISC.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/CallRRISC.java index 22d08d6..d44d55f 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/CallRRISC.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/CallRRISC.java @@ -11,7 +11,7 @@ public class CallRRISC extends CallNode implements MachNode { @Override public RegMask regmap(int i) { return i==_inputs._len-1 ? riscv.RMASK // Function call target - : riscv.callInMask(tfp(),i); // Normal argument + : riscv.callInMask(tfp(),i,fun()._maxArgSlot); // Normal argument } @Override public RegMask outregmap() { return null; } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/ParmRISC.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/ParmRISC.java index 07b6884..7bfc5fd 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/ParmRISC.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/ParmRISC.java @@ -9,7 +9,7 @@ public class ParmRISC extends ParmNode implements MachNode { final RegMask _rmask; ParmRISC(ParmNode parm) { super(parm); - _rmask = riscv.callInMask(fun().sig(),_idx); + _rmask = riscv.callInMask(fun().sig(),_idx,0); } @Override public RegMask regmap(int i) { return null; } @Override public RegMask outregmap() { return _rmask; } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/StoreRISC.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/StoreRISC.java index d732933..177aecf 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/StoreRISC.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/StoreRISC.java @@ -36,7 +36,7 @@ public class StoreRISC extends MemOpRISC { short ptr = enc.reg(ptr()); int op = val >= riscv.F_OFFSET ? riscv.OP_STOREFP : riscv.OP_STORE; if( val >= riscv.F_OFFSET ) val -= riscv.F_OFFSET; - enc.add4(riscv.s_type(op, func3()&7, ptr, val, _off)); + enc.add4(riscv.s_type(op, func3()&7, ptr, val == -1 ? riscv.ZERO : val, _off)); } @Override public void asm(CodeGen code, SB sb) { diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/riscv.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/riscv.java index eb10fab..b051fef 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/riscv.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/riscv/riscv.java @@ -253,8 +253,8 @@ static public int fsetop(String op) { }; } - @Override public RegMask callArgMask( SONTypeFunPtr tfp, int idx ) { return callInMask(tfp,idx); } - static RegMask callInMask( SONTypeFunPtr tfp, int idx ) { + @Override public RegMask callArgMask( SONTypeFunPtr tfp, int idx, int maxArgSlot ) { return callInMask(tfp,idx,maxArgSlot); } + static RegMask callInMask( SONTypeFunPtr tfp, int idx, int maxArgSlot ) { if( idx==0 ) return RPC_MASK; if( idx==1 ) return null; // Count floats in signature up to index @@ -272,6 +272,7 @@ static RegMask callInMask( SONTypeFunPtr tfp, int idx ) { return cargs[idx-2-fcnt]; } // Pass on stack slot(8 and higher) + if( maxArgSlot>0 ) throw Utils.TODO(); return new RegMask(MAX_REG + 1 + (idx - 2)); } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/CallRX86.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/CallRX86.java index 82a9999..3940630 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/CallRX86.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/CallRX86.java @@ -12,7 +12,7 @@ public class CallRX86 extends CallNode implements MachNode { @Override public RegMask regmap(int i) { return i==_inputs._len ? x86_64_v2.WMASK // Function call target - : x86_64_v2.callInMask(tfp(),i); // Normal argument + : x86_64_v2.callInMask(tfp(),i,fun()._maxArgSlot); // Normal argument } @Override public RegMask outregmap() { return null; } @Override public void encoding( Encoding enc ) { diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/CallX86.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/CallX86.java index 362f54e..ec9b60d 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/CallX86.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/CallX86.java @@ -20,7 +20,7 @@ public class CallX86 extends CallNode implements MachNode, RIPRelSize { @Override public String label() { return op(); } @Override public String name() { return _name; } @Override public SONTypeFunPtr tfp() { return _tfp; } - @Override public RegMask regmap(int i) { return x86_64_v2.callInMask(_tfp,i); } + @Override public RegMask regmap(int i) { return x86_64_v2.callInMask(_tfp,i,fun()._maxArgSlot); } @Override public RegMask outregmap() { return null; } @Override public int nargs() { return nIns()-2; } // Minus control, memory, fptr diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/ParmX86.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/ParmX86.java index 33995f1..d7ee657 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/ParmX86.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/ParmX86.java @@ -9,7 +9,7 @@ public class ParmX86 extends ParmNode implements MachNode { final RegMask _rmask; ParmX86( ParmNode parm ) { super(parm); - _rmask = x86_64_v2.callInMask(fun().sig(),_idx); + _rmask = x86_64_v2.callInMask(fun().sig(),_idx,1/*RPC*/); } @Override public RegMask regmap(int i) { return null; } @Override public RegMask outregmap() { return _rmask; } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/SplitX86.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/SplitX86.java index 058df1e..545d0f1 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/SplitX86.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/SplitX86.java @@ -49,9 +49,16 @@ public class SplitX86 extends SplitNode { // Stack spills if( dst >= x86_64_v2.MAX_REG ) { - if( src >= x86_64_v2.MAX_REG ) - throw Utils.TODO(); // Very rare stack-stack move int off = enc._fun.computeStackOffset(enc._code,dst); + if( src >= x86_64_v2.MAX_REG ) { + // Rare stack-stack move. push [RSP+soff]; pop [RSP+doff] + int soff = enc._fun.computeStackOffset(enc._code,src); + enc.add1(0xFF); + x86_64_v2.indirectAdr(0, (short)-1/*index*/, (short)x86_64_v2.RSP, soff, 6, enc); + enc.add1(0x8F); + x86_64_v2.indirectAdr(0, (short)-1/*index*/, (short)x86_64_v2.RSP, off, 0, enc); + return; + } StoreX86.encVal(enc, srcX ? SONTypeFloat.F64 : SONTypeInteger.BOT, (short)x86_64_v2.RSP, (short)-1/*index*/, src, off, 0); return; } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/StoreX86.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/StoreX86.java index 49ec2bb..243f48b 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/StoreX86.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/StoreX86.java @@ -44,7 +44,7 @@ public class StoreX86 extends MemOpX86 { case 0: enc.add1(_imm); break; case 1: enc.add2(_imm); break; case 2: enc.add4(_imm); break; - case 3: enc.add8(_imm); break; + case 3: enc.add4(_imm); break; // Limit of a 4 byte immediate } } else { encVal(enc,_declaredType,ptr,idx,src,_off,_scale); diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/x86_64_v2.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/x86_64_v2.java index bee5d2e..547abda 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/x86_64_v2.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/nodes/cpus/x86_64_v2/x86_64_v2.java @@ -185,13 +185,13 @@ public static void indirectAdr( int scale, short index, short base, int offset, // Map from function signature and argument index to register. // Used to set input registers to CallNodes, and ParmNode outputs. - @Override public RegMask callArgMask( SONTypeFunPtr tfp, int idx ) { return callInMask(tfp,idx); } - static RegMask callInMask( SONTypeFunPtr tfp, int idx ) { + @Override public RegMask callArgMask( SONTypeFunPtr tfp, int idx, int maxArgSlot ) { return callInMask(tfp,idx,maxArgSlot); } + static RegMask callInMask( SONTypeFunPtr tfp, int idx, int maxArgSlot ) { if( idx==0 ) return RPC_MASK; if( idx==1 ) return null; return switch( CodeGen.CODE._callingConv ) { - case "SystemV" -> callSys5 (tfp,idx); - case "Win64" -> callWin64(tfp,idx); + case "SystemV" -> callSys5 (tfp,idx,maxArgSlot); + case "Win64" -> callWin64(tfp,idx,maxArgSlot); default -> throw Utils.TODO(); }; } @@ -230,11 +230,11 @@ static RegMask callInMask( SONTypeFunPtr tfp, int idx ) { R09_MASK, }; - static RegMask callWin64(SONTypeFunPtr tfp, int idx ) { + static RegMask callWin64(SONTypeFunPtr tfp, int idx, int maxArgSlot ) { // idx 2,3,4,5 passed in registers, with stack slot mirrors. // idx >= 6 passed on stack, starting at slot#1 (#0 reserved for RPC). if( idx >= 6 ) - return new RegMask(MAX_REG+1/*RPC*/+(idx-2)); + return new RegMask(MAX_REG+maxArgSlot+(idx-2)); return tfp.arg(idx-2) instanceof SONTypeFloat ? XMMS8 [idx-2] : WIN64_CALL[idx-2]; @@ -271,7 +271,7 @@ static short maxArgSlotWin64(SONTypeFunPtr tfp) { R09_MASK, }; - static RegMask callSys5(SONTypeFunPtr tfp, int idx ) { + static RegMask callSys5(SONTypeFunPtr tfp, int idx, int maxArgSlot ) { // First 6 integers passed in registers: rdi,rsi,rdx,rcx,r08,r09 // First 8 floats passed in registers: xmm0-xmm7 int icnt=0, fcnt=0; // Count of ints, floats @@ -281,8 +281,8 @@ static RegMask callSys5(SONTypeFunPtr tfp, int idx ) { } int nstk = Math.max(icnt-6,0)+Math.max(fcnt-8,0); return tfp.arg(idx-2) instanceof SONTypeFloat - ? fcnt<8 ? XMMS8 [fcnt] : new RegMask(MAX_REG+1/*RPC*/+nstk) - : icnt<6 ? SYS5_CALL[icnt] : new RegMask(MAX_REG+1/*RPC*/+nstk); + ? fcnt<8 ? XMMS8 [fcnt] : new RegMask(MAX_REG+maxArgSlot+nstk) + : icnt<6 ? SYS5_CALL[icnt] : new RegMask(MAX_REG+maxArgSlot+nstk); } static short maxArgSlotSys5(SONTypeFunPtr tfp) { int icnt=0, fcnt=0; // Count of ints, floats diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeMemPtr.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeMemPtr.java index 1d74de0..e3b197f 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeMemPtr.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeMemPtr.java @@ -43,9 +43,9 @@ public SONTypeMemPtr(byte nil, SONTypeStruct obj) { // An abstract pointer, pointing to either a Struct or an Array. // Can also be null or not, so 4 choices {TOP,BOT} x {nil,not} - public static SONTypeMemPtr BOT = make((byte)3, SONTypeStruct.BOT); - public static SONTypeMemPtr TOP = BOT.dual(); - public static SONTypeMemPtr NOTBOT = make((byte)2, SONTypeStruct.BOT); + public static final SONTypeMemPtr BOT = make((byte)3, SONTypeStruct.BOT); + public static final SONTypeMemPtr TOP = BOT.dual(); + public static final SONTypeMemPtr NOTBOT = make((byte)2, SONTypeStruct.BOT); //public static SONTypeMemPtr TEST= make((byte)2, SONTypeStruct.TEST); public static void gather(ArrayList ts) { ts.add(NOTBOT); ts.add(BOT); /* ts.add(TEST); */ } @@ -79,7 +79,7 @@ public SONTypeNil xmeet(SONType t) { // Is forward-reference @Override public boolean isFRef() { return _obj.isFRef(); } - @Override public int log_size() { return 2; } // (1<<2)==4-byte pointers + @Override public int log_size() { return 3; } // (1<<3)==8-byte pointers @Override int hash() { return _obj.hashCode() ^ super.hash(); } diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeStruct.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeStruct.java index 256ddfa..cd69999 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeStruct.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeStruct.java @@ -192,9 +192,12 @@ int hash() { @Override public SB print(SB sb) { + if( _fields == null ) return sb.p(_name); // Forward reference struct, just print the name + if( isAry() ) { + if( !isFinal() ) sb.p("!"); + return sb.p(_name); // Skip printing generic array fields + } sb.p(_name); - if( _fields == null ) return sb; // Forward reference struct, just print the name - if( isAry() ) return sb; // Skip printing generic array fields sb.p(" {"); for( Field f : _fields ) f._type.print(sb).p(f._final ? " " : " !").p(f._fname).p("; "); diff --git a/seaofnodes/src/test/cases/mergsort/sort_ez.out b/seaofnodes/src/test/cases/mergsort/sort_ez.out new file mode 100644 index 0000000..946e758 --- /dev/null +++ b/seaofnodes/src/test/cases/mergsort/sort_ez.out @@ -0,0 +1,716 @@ +START: [[ ]] + 10 Start ____ ____ ____ [[ 15 52 55 61 158 12 67 9 102 179 ]] [ Ctrl, #TOP, int] + +L9: [[ START ]] + 9 merge_s ____ 10 [[ 50 51 54 56 60 321 320 319 318 317 316 315 314 313 312 311 310 309 308 307 306 305 304 401 398 362 364 400 403 405 8 ]] Ctrl + 50 $mem 9 15 [[ 8 ]] #BOT + 51 a 9 52 [[ 398 ]] *[int] + 54 n 9 55 [[ 401 ]] int + 56 b 9 52 [[ 362 ]] *[int] + 60 $rpc 9 61 [[ 2 ]] $[ALL] + 405 #0 9 [[ 8 ]] 0 + 403 mov 9 401 [[ 8 ]] + 400 mov 9 398 [[ 8 ]] + 364 mov 9 362 [[ 8 ]] + 8 call 9 50 400 405 403 364 [[ 7 ]] Ctrl + 362 mov 9 56 [[ 363 364 ]] + 398 mov 9 51 [[ 399 400 ]] + 401 mov 9 54 [[ 402 403 ]] + 305 rbp 9 [[ 2 ]] + 309 r13 9 [[ 2 ]] + 310 r14 9 [[ 2 ]] + 311 r15 9 [[ 2 ]] + 312 xmm6 9 [[ 2 ]] + 313 xmm7 9 [[ 2 ]] + 314 xmm8 9 [[ 2 ]] + 315 xmm9 9 [[ 2 ]] + 316 xmm10 9 [[ 2 ]] + 317 xmm11 9 [[ 2 ]] + 318 xmm12 9 [[ 2 ]] + 319 xmm13 9 [[ 2 ]] + 320 xmm14 9 [[ 2 ]] + 321 xmm15 9 [[ 2 ]] + 304 rbx 9 [[ 2 ]] + 308 r12 9 [[ 2 ]] + 307 rdi 9 [[ 2 ]] + 306 rsi 9 [[ 2 ]] + +L12: [[ START ]] + 12 main ____ 10 [[ 14 208 303 302 301 300 299 298 297 296 295 294 293 292 291 290 289 288 287 286 409 394 22 345 347 32 348 31 349 30 350 29 351 28 352 27 353 26 354 25 355 24 356 23 393 20 397 392 17 360 45 44 43 42 41 40 39 38 37 36 13 357 359 396 11 ]] Ctrl + 14 $mem 12 15 [[ 13 22 22 ]] #BOT + 208 $rpc 12 61 [[ 203 ]] $[ALL] + 347 mov 12 345 [[ 32 ]] + 32 st8 12 33 347 ____ ____ [[ 31 ]] #3:int + 348 mov 12 345 [[ 31 ]] + 31 st8 12 32 348 ____ ____ [[ 30 ]] #3:int + 349 mov 12 345 [[ 30 ]] + 30 st8 12 31 349 ____ ____ [[ 29 ]] #3:int + 350 mov 12 345 [[ 29 ]] + 45 st8 12 46 360 ____ ____ [[ 44 ]] #3:int + 29 st8 12 30 350 ____ ____ [[ 28 ]] #3:int + 351 mov 12 345 [[ 28 ]] + 44 st8 12 45 360 ____ ____ [[ 43 ]] #3:int + 28 st8 12 29 351 ____ ____ [[ 27 ]] #3:int + 43 st8 12 44 360 ____ ____ [[ 42 ]] #3:int + 352 mov 12 345 [[ 27 ]] + 42 st8 12 43 360 ____ ____ [[ 41 ]] #3:int + 27 st8 12 28 352 ____ ____ [[ 26 ]] #3:int + 353 mov 12 345 [[ 26 ]] + 41 st8 12 42 360 ____ ____ [[ 40 ]] #3:int + 26 st8 12 27 353 ____ ____ [[ 25 ]] #3:int + 354 mov 12 345 [[ 25 ]] + 40 st8 12 41 360 ____ ____ [[ 39 ]] #3:int + 25 st8 12 26 354 ____ ____ [[ 24 ]] #3:int + 355 mov 12 345 [[ 24 ]] + 39 st8 12 40 360 ____ ____ [[ 38 ]] #3:int + 24 st8 12 25 355 ____ ____ [[ 23 ]] #3:int + 356 mov 12 345 [[ 23 ]] + 38 st8 12 39 360 ____ ____ [[ 37 ]] #3:int + 23 st8 12 24 356 ____ ____ [[ 20 ]] #3:int + 393 #88 12 [[ 20 ]] 88 + 37 st8 12 38 360 ____ ____ [[ 36 ]] #3:int + 20 new_ary 12 393 21 23 [[ 19 35 48 ]] [ Ctrl, *![int], #2:u32, #3:int] + 19 $2 20 [[ 17 ]] #2:u32 + 35 $3 20 [[ 17 ]] #3:int + 48 [int] 20 [[ 397 ]] *[int] + 394 #88 12 [[ 22 ]] 88 + 36 st8 12 37 360 ____ ____ [[ 13 ]] #3:int + 392 #88 12 [[ 17 ]] 88 + 397 mov 12 48 [[ 359 ]] + 396 #10 12 [[ 11 ]] 10 + 17 new_ary 12 392 19 35 [[ 16 46 47 ]] [ Ctrl, *![int], #2:u32, #3:int] + 16 $2 17 [[ 13 ]] #2:u32 + 46 $3 17 [[ 45 ]] #3:int + 47 [int] 17 [[ 360 ]] *[int] + 13 ALLMEM 12 14 16 36 [[ 11 ]] #BOT + 357 mov 12 345 [[ 11 ]] + 359 mov 12 397 [[ 11 ]] + 22 new_ary 12 394 14 14 [[ 21 33 34 ]] [ Ctrl, *![int], #2:u32, #3:int] + 21 $2 22 [[ 20 ]] #2:u32 + 33 $3 22 [[ 32 ]] #3:int + 34 [int] 22 [[ 345 ]] *[int] + 11 call 12 13 357 359 396 [[ 182 ]] Ctrl + 345 mov 12 34 [[ 346 357 356 355 354 353 352 351 350 349 348 347 ]] + 360 mov 12 47 [[ 361 36 37 38 39 40 41 42 43 44 45 ]] + 286 rbx 12 [[ 409 ]] + 409 mov 12 286 [[ 410 ]] + 288 rsi 12 [[ 203 ]] + 289 rdi 12 [[ 203 ]] + 290 r12 12 [[ 203 ]] + 291 r13 12 [[ 203 ]] + 292 r14 12 [[ 203 ]] + 293 r15 12 [[ 203 ]] + 294 xmm6 12 [[ 203 ]] + 295 xmm7 12 [[ 203 ]] + 296 xmm8 12 [[ 203 ]] + 297 xmm9 12 [[ 203 ]] + 298 xmm10 12 [[ 203 ]] + 299 xmm11 12 [[ 203 ]] + 300 xmm12 12 [[ 203 ]] + 301 xmm13 12 [[ 203 ]] + 302 xmm14 12 [[ 203 ]] + 303 xmm15 12 [[ 203 ]] + 287 rbp 12 [[ 203 ]] + +L179: [[ START ]] + 179 eq ____ 10 [[ 189 190 194 197 201 285 284 283 282 281 280 279 278 277 276 275 274 273 272 271 270 269 268 390 178 ]] Ctrl + 189 $mem 179 15 [[ 187 193 199 199 ]] #BOT + 190 a 179 52 [[ 187 ]] *[int] + 194 b 179 52 [[ 193 ]] *[int] + 197 n 179 55 [[ 195 ]] int + 201 $rpc 179 61 [[ 174 ]] $[ALL] + 390 #0 179 [[ 191 ]] 0 + 272 r12 179 [[ 174 ]] + 273 r13 179 [[ 174 ]] + 274 r14 179 [[ 174 ]] + 275 r15 179 [[ 174 ]] + 276 xmm6 179 [[ 174 ]] + 277 xmm7 179 [[ 174 ]] + 278 xmm8 179 [[ 174 ]] + 279 xmm9 179 [[ 174 ]] + 280 xmm10 179 [[ 174 ]] + 281 xmm11 179 [[ 174 ]] + 282 xmm12 179 [[ 174 ]] + 283 xmm13 179 [[ 174 ]] + 284 xmm14 179 [[ 174 ]] + 285 xmm15 179 [[ 174 ]] + 271 rdi 179 [[ 174 ]] + 270 rsi 179 [[ 174 ]] + 269 rbp 179 [[ 174 ]] + 268 rbx 179 [[ 174 ]] + +L158: [[ START ]] + 158 copy_ar ____ 10 [[ 163 165 167 170 172 173 249 248 247 246 245 244 243 242 241 240 239 238 237 236 235 234 233 232 157 ]] Ctrl + 163 begin 158 55 [[ 162 ]] int + 165 end 158 55 [[ 160 ]] int + 167 $mem 158 15 [[ 166 168 ]] #BOT + 170 b 158 52 [[ 169 ]] *[int] + 172 a 158 52 [[ 171 ]] *[int] + 173 $rpc 158 61 [[ 154 ]] $[ALL] + 232 rbx 158 [[ 154 ]] + 238 r14 158 [[ 154 ]] + 239 r15 158 [[ 154 ]] + 240 xmm6 158 [[ 154 ]] + 241 xmm7 158 [[ 154 ]] + 242 xmm8 158 [[ 154 ]] + 243 xmm9 158 [[ 154 ]] + 244 xmm10 158 [[ 154 ]] + 245 xmm11 158 [[ 154 ]] + 246 xmm12 158 [[ 154 ]] + 247 xmm13 158 [[ 154 ]] + 248 xmm14 158 [[ 154 ]] + 249 xmm15 158 [[ 154 ]] + 237 r13 158 [[ 154 ]] + 236 r12 158 [[ 154 ]] + 235 rdi 158 [[ 154 ]] + 234 rsi 158 [[ 154 ]] + 233 rbp 158 [[ 154 ]] + +L67: [[ START ]] + 67 split_m ____ 10 [[ 70 73 74 75 78 95 267 266 265 264 263 262 261 260 259 258 257 256 255 254 253 252 251 250 383 332 328 324 338 387 84 82 66 ]] Ctrl + 70 $mem 67 15 [[ 68 91 ]] #BOT + 73 a 67 52 [[ 324 ]] *[int] + 74 b 67 52 [[ 328 ]] *[int] + 75 begin 67 55 [[ 383 ]] int + 78 end 67 55 [[ 332 ]] int + 95 $rpc 67 61 [[ 63 ]] $[ALL] + 387 mov 67 383 [[ 84 ]] + 328 mov 67 74 [[ 331 330 329 ]] + 332 mov 67 78 [[ 338 336 333 335 ]] + 383 mov 67 75 [[ 387 386 384 385 ]] + 338 mov 67 332 [[ 84 ]] + 324 mov 67 73 [[ 327 325 326 ]] + 84 sub 67 338 387 [[ 82 ]] int + 82 cmp 67 84 [[ 66 ]] bool + 66 j<= 67 82 [[ 65 69 ]] [ Ctrl, Ctrl] + 255 r13 67 [[ 63 ]] + 256 r14 67 [[ 63 ]] + 257 r15 67 [[ 63 ]] + 258 xmm6 67 [[ 63 ]] + 259 xmm7 67 [[ 63 ]] + 260 xmm8 67 [[ 63 ]] + 261 xmm9 67 [[ 63 ]] + 262 xmm10 67 [[ 63 ]] + 263 xmm11 67 [[ 63 ]] + 264 xmm12 67 [[ 63 ]] + 265 xmm13 67 [[ 63 ]] + 266 xmm14 67 [[ 63 ]] + 267 xmm15 67 [[ 63 ]] + 252 rsi 67 [[ 63 ]] + 251 rbp 67 [[ 63 ]] + 250 rbx 67 [[ 63 ]] + 253 rdi 67 [[ 63 ]] + 254 r12 67 [[ 63 ]] + +L102: [[ START ]] + 102 merge ____ 10 [[ 119 122 125 132 134 139 153 231 230 229 228 227 226 225 224 223 222 221 220 219 218 217 216 215 214 406 322 368 373 101 ]] Ctrl + 119 begin 102 55 [[ 368 135 ]] int + 122 middle 102 55 [[ 116 373 ]] int + 125 end 102 55 [[ 123 150 ]] int + 132 $mem 102 15 [[ 131 152 ]] #BOT + 134 b 102 52 [[ 133 ]] *[int] + 139 a 102 52 [[ 322 ]] *[int] + 153 $rpc 102 61 [[ 98 ]] $[ALL] + 373 mov 102 122 [[ 126 ]] + 368 mov 102 119 [[ 118 ]] + 322 mov 102 139 [[ 323 129 140 138 ]] + 214 rbx 102 [[ 406 ]] + 406 mov 102 214 [[ 407 ]] + 217 rdi 102 [[ 98 ]] + 222 xmm6 102 [[ 98 ]] + 223 xmm7 102 [[ 98 ]] + 224 xmm8 102 [[ 98 ]] + 225 xmm9 102 [[ 98 ]] + 226 xmm10 102 [[ 98 ]] + 227 xmm11 102 [[ 98 ]] + 228 xmm12 102 [[ 98 ]] + 229 xmm13 102 [[ 98 ]] + 230 xmm14 102 [[ 98 ]] + 231 xmm15 102 [[ 98 ]] + 216 rsi 102 [[ 98 ]] + 215 rbp 102 [[ 98 ]] + 220 r14 102 [[ 98 ]] + 221 r15 102 [[ 98 ]] + 219 r13 102 [[ 98 ]] + 218 r12 102 [[ 98 ]] + +LOOP178: [[ L179 L184 ]] + 178 Loop ____ 179 419 [[ 191 195 177 ]] Ctrl + 191 Phi_i 178 390 192 [[ 195 187 192 193 ]] int + 195 cmp 178 191 197 [[ 177 ]] bool + 177 j>= 178 195 [[ 176 186 ]] [ Ctrl, Ctrl] + +LOOP157: [[ L158 L159 ]] + 157 Loop ____ 158 411 [[ 162 168 160 156 ]] Ctrl + 162 Phi_k 157 163 164 [[ 160 164 169 171 ]] int + 168 Phi_$3 157 167 169 [[ 166 169 171 ]] #BOT + 160 cmp 157 162 165 [[ 156 ]] bool + 156 j>= 157 160 [[ 155 159 ]] [ Ctrl, Ctrl] + +LOOP101: [[ L102 L103 ]] + 101 Loop ____ 102 413 [[ 118 126 131 135 150 100 ]] Ctrl + 118 Phi_i 101 368 120 [[ 129 116 121 120 138 ]] int + 126 Phi_j 101 373 127 [[ 142 123 127 128 140 ]] int + 131 Phi_$3 101 132 133 [[ 129 133 138 140 142 152 ]] #BOT + 135 Phi_k 101 119 136 [[ 150 133 136 ]] int + 150 cmp 101 135 125 [[ 100 ]] bool + 100 j>= 101 150 [[ 99 115 ]] [ Ctrl, Ctrl] + +L7: [[ L9 ]] + 7 CallEnd 8 [[ 6 57 ]] [ Ctrl, #BOT, int] + 57 $mem 7 [[ 5 ]] #BOT + +L182: [[ L12 ]] + 182 CallEnd 11 [[ 181 183 ]] [ Ctrl, #BOT, int] + 183 $mem 182 [[ 180 ]] #BOT + +L65: [[ L67 ]] + 65 True 66 [[ 53 64 ]] Ctrl + 53 #0 65 [[ 93 ]] 0 + +L69: [[ L67 ]] + 69 False 66 [[ 335 386 77 79 76 341 326 331 344 385 68 ]] Ctrl + 326 mov 69 324 [[ 68 ]] + 331 mov 69 328 [[ 68 ]] + 385 mov 69 383 [[ 68 ]] + 344 mov 69 341 [[ 68 ]] + 68 call 69 70 326 385 344 331 [[ 72 ]] Ctrl + 335 mov 69 332 [[ 77 ]] + 386 mov 69 383 [[ 77 ]] + 77 add 69 335 386 [[ 76 ]] int + 79 #2 69 [[ 76 ]] 2 + 76 div 69 77 79 [[ 341 ]] int + 341 mov 69 76 [[ 344 342 343 ]] + +L6: [[ L7 ]] + 6 $ctrl 7 [[ 363 399 402 404 5 ]] Ctrl + 363 mov 6 362 [[ 5 ]] + 399 mov 6 398 [[ 5 ]] + 404 #0 6 [[ 5 ]] 0 + 402 mov 6 401 [[ 5 ]] + 5 call 6 57 399 404 402 363 [[ 4 ]] Ctrl + +L186: [[ LOOP178 ]] + 186 False 177 [[ 193 187 185 ]] Ctrl + 193 ld8 186 189 194 191 [[ 187 ]] int + 187 cmp8 186 189 190 191 193 [[ 185 ]] bool + 185 j!= 186 187 [[ 184 198 ]] [ Ctrl, Ctrl] + +L176: [[ LOOP178 ]] + 176 True 177 [[ 149 175 ]] Ctrl + 149 #1 176 [[ 200 ]] 1 + +L181: [[ L182 ]] + 181 $ctrl 182 [[ 346 361 395 180 ]] Ctrl + 346 mov 181 345 [[ 180 ]] + 361 mov 181 360 [[ 180 ]] + 395 #10 181 [[ 180 ]] 10 + 180 call 181 183 346 361 395 [[ 205 ]] Ctrl + +L159: [[ LOOP157 ]] + 159 False 156 [[ 171 169 164 411 ]] Ctrl + 164 inc 159 162 [[ 162 ]] int + 171 ld8 159 168 172 162 [[ 169 ]] int + 169 st8 159 168 170 162 171 [[ 168 ]] #3:Bot + +L115: [[ LOOP101 ]] + 115 False 100 [[ 116 114 ]] Ctrl + 116 cmp 115 118 122 [[ 114 ]] bool + 114 j< 115 116 [[ 113 143 ]] [ Ctrl, Ctrl] + +L99: [[ LOOP101 ]] + 99 True 100 [[ 152 407 408 98 ]] Ctrl + 152 ALLMEM 99 132 ____ 131 [[ 98 ]] #BOT + 407 mov 99 406 [[ 98 ]] + 408 #0 99 [[ 98 ]] 0 + 98 Return 99 152 408 153 407 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 [[ 1 ]] [ Ctrl, #BOT, 0] + +L155: [[ LOOP157 ]] + 155 True 156 [[ 166 212 154 ]] Ctrl + 166 ALLMEM 155 167 ____ 168 [[ 154 ]] #BOT + 212 #0 155 [[ 154 ]] 0 + 154 Return 155 166 212 173 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 [[ 1 ]] [ Ctrl, #BOT, 0] + +L4: [[ L6 ]] + 4 CallEnd 5 [[ 3 58 59 ]] [ Ctrl, #BOT, int] + 58 $mem 4 [[ 2 ]] #BOT + 59 #2 4 [[ 2 ]] int + +L198: [[ L186 ]] + 198 True 185 [[ 391 418 ]] Ctrl + 391 #0 198 [[ 200 ]] 0 + 418 jmp 198 [[ 175 ]] + +L184: [[ L186 ]] + 184 False 185 [[ 192 419 ]] Ctrl + 192 inc 184 191 [[ 191 ]] int + +L143: [[ L115 ]] + 143 False 114 [[ 381 417 ]] Ctrl + 381 #0 143 [[ 148 ]] 0 + 417 jmp 143 [[ 108 ]] + +L205: [[ L181 ]] + 205 CallEnd 180 [[ 204 206 207 ]] [ Ctrl, #BOT, bool] + 206 $mem 205 [[ 203 ]] #BOT + 207 #2 205 [[ 203 ]] bool + +L113: [[ L115 ]] + 113 True 114 [[ 123 112 ]] Ctrl + 123 cmp 113 125 126 [[ 112 ]] bool + 112 j<= 113 123 [[ 111 144 ]] [ Ctrl, Ctrl] + +L72: [[ L69 ]] + 72 CallEnd 68 [[ 71 81 ]] [ Ctrl, #BOT, int] + 71 $mem 72 [[ 80 ]] #BOT + +L3: [[ L4 ]] + 3 $ctrl 4 [[ 2 ]] Ctrl + 2 Return 3 58 59 60 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 [[ 1 ]] [ Ctrl, #BOT, int] + +L81: [[ L72 ]] + 81 $ctrl 72 [[ 327 330 336 343 80 ]] Ctrl + 327 mov 81 324 [[ 80 ]] + 330 mov 81 328 [[ 80 ]] + 343 mov 81 341 [[ 80 ]] + 336 mov 81 332 [[ 80 ]] + 80 call 81 71 327 343 336 330 [[ 89 ]] Ctrl + +L204: [[ L205 ]] + 204 $ctrl 205 [[ 410 203 ]] Ctrl + 410 mov 204 409 [[ 203 ]] + 203 Return 204 206 207 208 410 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 [[ 1 ]] [ Ctrl, #BOT, bool] + +L175: [[ L176 L198 ]] + 175 Region ____ 176 418 [[ 200 199 174 ]] Ctrl + 200 Phi_res 175 149 391 [[ 174 ]] bool + 199 ALLMEM 175 189 ____ 189 [[ 174 ]] #BOT + 174 Return 175 199 200 201 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 [[ 1 ]] [ Ctrl, #BOT, bool] + +L111: [[ L113 ]] + 111 False 112 [[ 323 142 129 110 ]] Ctrl + 323 mov 111 322 [[ 142 ]] + 142 ld8 111 131 323 126 [[ 129 ]] int + 129 cmp8 111 131 322 118 142 [[ 110 ]] bool + 110 j<= 111 129 [[ 109 145 ]] [ Ctrl, Ctrl] + +L144: [[ L113 ]] + 144 True 112 [[ 380 108 ]] Ctrl + 380 #1 144 [[ 148 ]] 1 + +L89: [[ L81 ]] + 89 CallEnd 80 [[ 88 90 ]] [ Ctrl, #BOT, int] + 90 $mem 89 [[ 87 ]] #BOT + +L88: [[ L89 ]] + 88 $ctrl 89 [[ 325 329 333 342 384 87 ]] Ctrl + 325 mov 88 324 [[ 87 ]] + 329 mov 88 328 [[ 87 ]] + 384 mov 88 383 [[ 87 ]] + 342 mov 88 341 [[ 87 ]] + 333 mov 88 332 [[ 87 ]] + 87 call 88 90 329 384 342 333 325 [[ 86 ]] Ctrl + +L109: [[ L111 ]] + 109 True 110 [[ 379 415 ]] Ctrl + 379 #1 109 [[ 148 ]] 1 + 415 jmp 109 [[ 108 ]] + +L145: [[ L111 ]] + 145 False 110 [[ 382 416 ]] Ctrl + 382 #0 145 [[ 148 ]] 0 + 416 jmp 145 [[ 108 ]] + +L108: [[ L109 L143 L144 L145 ]] + 108 Region ____ 415 417 144 416 [[ 148 146 107 ]] Ctrl + 148 Phi_con 108 379 381 380 382 [[ 146 ]] bool + 146 test 108 148 [[ 107 ]] + 107 j!= 108 146 [[ 104 141 ]] [ Ctrl, Ctrl] + +L86: [[ L88 ]] + 86 CallEnd 87 [[ 85 92 94 ]] [ Ctrl, #BOT, int] + 92 $mem 86 [[ 91 ]] #BOT + 94 #2 86 [[ 93 ]] int + +L141: [[ L108 ]] + 141 False 107 [[ 140 128 414 ]] Ctrl + 128 inc 141 126 [[ 127 ]] int + 140 ld8 141 131 322 126 [[ 137 ]] int + 414 jmp 141 [[ 103 ]] + +L104: [[ L108 ]] + 104 True 107 [[ 138 121 103 ]] Ctrl + 121 inc 104 118 [[ 120 ]] int + 138 ld8 104 131 322 118 [[ 137 ]] int + +L85: [[ L86 ]] + 85 $ctrl 86 [[ 412 ]] Ctrl + 412 jmp 85 [[ 64 ]] + +L103: [[ L104 L141 ]] + 103 Region ____ 104 414 [[ 120 127 137 133 136 413 ]] Ctrl + 120 Phi_i 103 121 118 [[ 118 ]] int + 127 Phi_j 103 126 128 [[ 126 ]] int + 137 Phi_$3 103 138 140 [[ 133 ]] int + 136 inc 103 135 [[ 135 ]] int + 133 st8 103 131 134 135 137 [[ 131 ]] #3:Bot + +L64: [[ L65 L85 ]] + 64 Region ____ 65 412 [[ 91 93 63 ]] Ctrl + 91 Phi_$me 64 70 92 [[ 63 ]] #BOT + 93 Phi_arg 64 53 94 [[ 63 ]] int + 63 Return 64 91 93 95 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 [[ 1 ]] [ Ctrl, #BOT, int] + +L1: [[ L155 L175 L204 ]] + 1 Stop 2 63 98 154 174 203 [[ ]] Bot + + + +---eq { *![int] *![int] int -> int #1}--------------------------- + a:rcx,b:rdx,n:r8 +0000 ?? xor rax,rax +0001 ?? JMP L178 +LOOP178: + i:rax +0002 ?? cmp rax, r8 +0003 ?? j>= L176 // L186 +L186: +0004 ?? ld8 r9,[rdx+rax*8+8] +0005 ?? cmp8 r9, [rcx+rax*8+8] +0006 ?? j!= L198 // L184 +L184: +0007 ?? inc rax += #1 +0008 ?? jmp LOOP178 +L419: +0009 ?? JMP L178 +L198: +000A ?? xor rax,rax +000B ?? jmp L175 +L418: +000C ?? JMP L175 +L176: +000D ?? ldi rax = #1 +000E ?? JMP L175 +L175: + result:rax +000F ?? ALLME +0010 ?? ret +---{ *![int] *![int] int -> int #1}--------------------------- + +---merge { *![int] int int int *![int] -> int #0}--------------------------- + begin:rdx,middle:r8,end:r9,b:rcx,a:[stk#38] +0011 ?? mov xmm0 = rbx // def/loop #2 +0012 ?? mov rbx = [rsp+0] // def/empty1 #0 +0013 ?? mov r11 = rdx // use/self/phi #1 +0014 ?? mov r10 = r8 // use/self/use #1 +0015 ?? JMP L101 +LOOP101: + i:r11,j:r10,k:rdx +0016 ?? cmp rdx, r9 +0017 ?? j>= L99 // L115 +L115: +0018 ?? cmp r11, r8 +0019 ?? j< L113 // L143 +L143: +001A ?? xor rax,rax +001B ?? jmp L108 +L417: +001C ?? JMP L108 +L113: +001D ?? cmp r9, r10 +001E ?? j<= L144 // L111 +L111: +001F ?? mov rax = rbx // use/empty1 #0 +0020 ?? ld8 rax,[rax+r10*8+8] +0021 ?? cmp8 rax, [rbx+r11*8+8] +0022 ?? j<= L109 // L145 +L145: +0023 ?? xor rax,rax +0024 ?? jmp L108 +L416: +0025 ?? JMP L108 +L109: +0026 ?? ldi rax = #1 +0027 ?? jmp L108 +L415: +0028 ?? JMP L108 +L144: +0029 ?? ldi rax = #1 +002A ?? JMP L108 +L108: + cond:rax +002B ?? test rax +002C ?? j!= L104 // L141 +L141: +002D ?? ld8 rax,[rbx+r10*8+8] +002E ?? inc r10 += #1 +002F ?? jmp L103 +L414: +0030 ?? JMP L103 +L104: +0031 ?? ld8 rax,[rbx+r11*8+8] +0032 ?? inc r11 += #1 +0033 ?? JMP L103 +L103: + i:r11,j:r10,$3:rax +0034 ?? st8 [rcx+rdx*8+8],rax +0035 ?? inc rdx += #1 +0036 ?? jmp LOOP101 +L413: +0037 ?? JMP L101 +L99: +0038 ?? ALLME +0039 ?? mov rbx = xmm0 // use/loop/use #2 +003A ?? xor rax,rax +003B ?? ret +---{ *![int] int int int *![int] -> int #0}--------------------------- + +---merge_sort { *![int] *![int] int -> int #0}--------------------------- + a:rcx,n:r8,b:rdx +003C ?? mov [rsp+24] = r8 // def/loop #1 +003D ?? mov [rsp+16] = rcx // def/loop #1 +003E ?? mov [rsp+8] = rdx // def/loop #0 +003F ?? mov r9 = [rsp+8] // use/loop/use #0 +0040 ?? mov rcx = [rsp+16] // use/loop/use #1 +0041 ?? mov r8 = [rsp+24] // use/loop/use #1 +0042 ?? xor rdx,rdx +0043 ?? call copy_array rcx rdx r8 r9 +0044 ?? mov r9 = [rsp+8] // use/loop/use #0 +0045 ?? mov rcx = [rsp+16] // use/loop/use #1 +0046 ?? mov r8 = [rsp+24] // use/loop/use #1 +0047 ?? xor rdx,rdx +0048 ?? call split_merge rcx rdx r8 r9 + #2 rax +0049 ?? addi rsp += #40 +ret +---{ *![int] *![int] int -> int #0}--------------------------- + +---split_merge { *![int] int int *![int] -> int #0}--------------------------- + a:r9,b:rcx,begin:rdx,end:r8 +004A ?? mov [rsp+40] = rdx // def/loop #1 +004B ?? mov [rsp+32] = r8 // def/loop #0 +004C ?? mov [rsp+24] = rcx // def/loop #0 +004D ?? mov [rsp+16] = r9 // def/loop #0 +004E ?? mov r8 = [rsp+32] // use/loop/use #0 +004F ?? mov r10 = [rsp+40] // use/loop/use #1 +0050 ?? sub r8 -= r10 +0051 ?? cmp r8, #1 +0052 ?? j<= L65 // L69 +L69: +0053 ?? mov rax = [rsp+32] // use/loop/use #0 +0054 ?? mov rdx = [rsp+40] // use/loop/use #1 +0055 ?? add rax += rdx +0056 ?? ldi rcx = #2 +0057 ?? div rax = rax / rcx // kill rdx +0058 ?? mov [rsp+8] = rax // def/loop #0 +0059 ?? mov rcx = [rsp+16] // use/loop/use #0 +005A ?? mov r9 = [rsp+24] // use/loop/use #0 +005B ?? mov r8 = [rsp+8] // use/loop/use #0 +005C ?? mov rdx = [rsp+40] // use/loop/use #1 +005D ?? call split_merge rcx rdx r8 r9 +005E ?? mov rcx = [rsp+16] // use/loop/use #0 +005F ?? mov r9 = [rsp+24] // use/loop/use #0 +0060 ?? mov r8 = [rsp+32] // use/loop/use #0 +0061 ?? mov rdx = [rsp+8] // use/loop/use #0 +0062 ?? call split_merge rcx rdx r8 r9 +0063 ?? mov [rsp+32] = [rsp+16] // use/loop/use #0 +0064 ?? mov rcx = [rsp+24] // use/loop/use #0 +0065 ?? mov r9 = [rsp+32] // use/loop/use #0 +0066 ?? mov r8 = [rsp+8] // use/loop/use #0 +0067 ?? mov rdx = [rsp+40] // use/loop/use #1 +0068 ?? call merge rcx rdx r8 r9 [stk#42] + #2 rax +0069 ?? jmp L64 +L412: +006A ?? JMP L64 +L65: +006B ?? xor rax,rax +006C ?? JMP L64 +L64: + arg:rax +006D ?? addi rsp += #56 +ret +---{ *![int] int int *![int] -> int #0}--------------------------- + +---main { -> int #0}--------------------------- + +006E ?? mov [rsp+0] = rbx // def/loop #2 +006F ?? ldi rdx = #88 +0070 ?? alloc ldi rcx = #1 +call #calloc + [int] rax +0071 ?? mov [rsp+32] = rax // def/loop #0 +0072 ?? mov rdx = [rsp+32] // use/loop/use #0 +0073 ?? st8 [rdx+8],#10 +0074 ?? mov rcx = [rsp+32] // use/loop/use #0 +0075 ?? st8 [rcx+16],#9 +0076 ?? mov rax = [rsp+32] // use/loop/use #0 +0077 ?? st8 [rax+24],#8 +0078 ?? mov r11 = [rsp+32] // use/loop/use #0 +0079 ?? st8 [r11+32],#7 +007A ?? mov r10 = [rsp+32] // use/loop/use #0 +007B ?? st8 [r10+40],#6 +007C ?? mov r9 = [rsp+32] // use/loop/use #0 +007D ?? st8 [r9+48],#5 +007E ?? mov r8 = [rsp+32] // use/loop/use #0 +007F ?? st8 [r8+56],#4 +0080 ?? mov rdx = [rsp+32] // use/loop/use #0 +0081 ?? st8 [rdx+64],#3 +0082 ?? mov rcx = [rsp+32] // use/loop/use #0 +0083 ?? st8 [rcx+72],#2 +0084 ?? mov rax = [rsp+32] // use/loop/use #0 +0085 ?? st8 [rax+80],#1 +0086 ?? ldi rdx = #88 +0087 ?? alloc ldi rcx = #1 +call #calloc + [int] rax +0088 ?? mov [rsp+24] = rax // def/empty1 #1 +0089 ?? ldi rdx = #88 +008A ?? alloc ldi rcx = #1 +call #calloc + [int] rax +008B ?? mov rbx = rax // def/empty1 #0 +008C ?? st8 [rbx+8],#1 +008D ?? st8 [rbx+16],#2 +008E ?? st8 [rbx+24],#3 +008F ?? st8 [rbx+32],#4 +0090 ?? st8 [rbx+40],#5 +0091 ?? st8 [rbx+48],#6 +0092 ?? st8 [rbx+56],#7 +0093 ?? st8 [rbx+64],#8 +0094 ?? st8 [rbx+72],#9 +0095 ?? st8 [rbx+80],#10 +0096 ?? ALLME +0097 ?? mov rcx = [rsp+32] // use/loop/use #0 +0098 ?? mov rdx = [rsp+24] // use/empty1 #0 +0099 ?? ldi r8 = #10 +009A ?? call merge_sort rcx rdx r8 +009B ?? mov rcx = [rsp+32] // use/loop/use #0 +009C ?? mov rdx = rbx // use/empty1 #0 +009D ?? ldi r8 = #10 +009E ?? call eq rcx rdx r8 + #2 rax +009F ?? mov rbx = [rsp+0] // use/loop/use #2 +00A0 ?? addi rsp += #40 +ret +---{ -> int #0}--------------------------- + +---copy_array { *![int] int int *![int] -> int #1}--------------------------- + begin:rdx,end:r8,b:r9,a:rcx +00A1 ?? JMP L157 +LOOP157: + k:rdx +00A2 ?? cmp rdx, r8 +00A3 ?? j>= L155 // L159 +L159: +00A4 ?? ld8 rax,[rcx+rdx*8+8] +00A5 ?? st8 [r9+rdx*8+8],rax +00A6 ?? inc rdx += #1 +00A7 ?? jmp LOOP157 +L411: +00A8 ?? JMP L157 +L155: +00A9 ?? ALLME +00AA ?? xor rax,rax +00AB ?? ret +---{ *![int] int int *![int] -> int #1}--------------------------- diff --git a/seaofnodes/src/test/cases/mergsort/sort_smp.out b/seaofnodes/src/test/cases/mergsort/sort_smp.out new file mode 100644 index 0000000..e5edda1 --- /dev/null +++ b/seaofnodes/src/test/cases/mergsort/sort_smp.out @@ -0,0 +1,723 @@ +START: [[ ]] + 10 Start ____ ____ ____ [[ 13 61 64 86 58 9 190 121 70 93 ]] [ Ctrl, #TOP, int] + +L9: [[ START ]] + 9 main ____ 10 [[ 12 212 325 324 323 322 321 320 319 318 317 316 315 314 313 312 311 310 309 308 416 408 23 355 358 34 359 33 360 32 361 31 362 30 363 29 364 28 365 27 366 26 357 21 367 25 407 20 411 18 406 16 371 48 47 46 45 44 43 42 41 40 14 39 11 368 370 410 8 ]] Ctrl + 12 $mem 9 13 [[ 11 23 23 ]] #BOT + 212 $rpc 9 86 [[ 2 ]] $[ALL] + 358 mov 9 355 [[ 34 ]] + 34 st8 9 35 358 ____ ____ [[ 33 ]] #3:int + 359 mov 9 355 [[ 33 ]] + 33 st8 9 34 359 ____ ____ [[ 32 ]] #3:int + 360 mov 9 355 [[ 32 ]] + 32 st8 9 33 360 ____ ____ [[ 31 ]] #3:int + 361 mov 9 355 [[ 31 ]] + 48 st8 9 49 371 ____ ____ [[ 47 ]] #3:int + 31 st8 9 32 361 ____ ____ [[ 30 ]] #3:int + 362 mov 9 355 [[ 30 ]] + 47 st8 9 48 371 ____ ____ [[ 46 ]] #3:int + 30 st8 9 31 362 ____ ____ [[ 29 ]] #3:int + 46 st8 9 47 371 ____ ____ [[ 45 ]] #3:int + 363 mov 9 355 [[ 29 ]] + 45 st8 9 46 371 ____ ____ [[ 44 ]] #3:int + 29 st8 9 30 363 ____ ____ [[ 28 ]] #3:int + 364 mov 9 355 [[ 28 ]] + 44 st8 9 45 371 ____ ____ [[ 43 ]] #3:int + 28 st8 9 29 364 ____ ____ [[ 27 ]] #3:int + 365 mov 9 355 [[ 27 ]] + 43 st8 9 44 371 ____ ____ [[ 42 ]] #3:int + 27 st8 9 28 365 ____ ____ [[ 26 ]] #3:int + 366 mov 9 355 [[ 26 ]] + 42 st8 9 43 371 ____ ____ [[ 41 ]] #3:int + 367 mov 9 355 [[ 25 ]] + 357 mov 9 355 [[ 21 ]] + 26 st8 9 27 366 ____ ____ [[ 25 ]] #3:int + 41 st8 9 42 371 ____ ____ [[ 40 ]] #3:int + 25 st8 9 26 367 ____ ____ [[ 20 ]] #3:int + 407 #88 9 [[ 20 ]] 88 + 21 st4 9 22 357 ____ ____ [[ 20 ]] #2:u32 + 40 st8 9 41 371 ____ ____ [[ 39 ]] #3:int + 20 new_ary 9 407 21 25 [[ 19 36 37 ]] [ Ctrl, *![int], #2:u32, #3:int] + 19 $2 20 [[ 18 ]] #2:u32 + 36 [int] 20 [[ 411 18 ]] *[int] + 37 $3 20 [[ 16 ]] #3:int + 408 #88 9 [[ 23 ]] 88 + 39 st8 9 40 371 ____ ____ [[ 11 ]] #3:int + 18 st4 9 19 36 ____ ____ [[ 16 ]] #2:u32 + 411 mov 9 36 [[ 370 ]] + 406 #88 9 [[ 16 ]] 88 + 14 st4 9 15 371 ____ ____ [[ 11 ]] #2:u32 + 410 #10 9 [[ 8 ]] 10 + 16 new_ary 9 406 18 37 [[ 15 38 49 ]] [ Ctrl, *![int], #2:u32, #3:int] + 15 $2 16 [[ 14 ]] #2:u32 + 38 [int] 16 [[ 371 ]] *[int] + 49 $3 16 [[ 48 ]] #3:int + 11 ALLMEM 9 12 14 39 [[ 8 ]] #BOT + 368 mov 9 355 [[ 8 ]] + 370 mov 9 411 [[ 8 ]] + 23 new_ary 9 408 12 12 [[ 22 24 35 ]] [ Ctrl, *![int], #2:u32, #3:int] + 22 $2 23 [[ 21 ]] #2:u32 + 24 [int] 23 [[ 355 ]] *[int] + 35 $3 23 [[ 34 ]] #3:int + 8 call 9 11 368 370 410 [[ 7 ]] Ctrl + 371 mov 9 38 [[ 372 39 40 41 42 43 44 45 46 47 48 14 ]] + 355 mov 9 24 [[ 356 368 367 366 365 364 363 362 361 360 359 358 357 ]] + 308 rbx 9 [[ 416 ]] + 416 mov 9 308 [[ 417 ]] + 310 rsi 9 [[ 2 ]] + 311 rdi 9 [[ 2 ]] + 312 r12 9 [[ 2 ]] + 313 r13 9 [[ 2 ]] + 314 r14 9 [[ 2 ]] + 315 r15 9 [[ 2 ]] + 316 xmm6 9 [[ 2 ]] + 317 xmm7 9 [[ 2 ]] + 318 xmm8 9 [[ 2 ]] + 319 xmm9 9 [[ 2 ]] + 320 xmm10 9 [[ 2 ]] + 321 xmm11 9 [[ 2 ]] + 322 xmm12 9 [[ 2 ]] + 323 xmm13 9 [[ 2 ]] + 324 xmm14 9 [[ 2 ]] + 325 xmm15 9 [[ 2 ]] + 309 rbp 9 [[ 2 ]] + +L70: [[ START ]] + 70 copy_ar ____ 10 [[ 75 77 79 82 84 85 289 288 287 286 285 284 283 282 281 280 279 278 277 276 275 274 273 272 69 ]] Ctrl + 75 begin 70 64 [[ 74 ]] int + 77 end 70 64 [[ 72 ]] int + 79 $mem 70 13 [[ 78 80 ]] #BOT + 82 b 70 61 [[ 81 ]] *[int] + 84 a 70 61 [[ 83 ]] *[int] + 85 $rpc 70 86 [[ 66 ]] $[ALL] + 272 rbx 70 [[ 66 ]] + 278 r14 70 [[ 66 ]] + 279 r15 70 [[ 66 ]] + 280 xmm6 70 [[ 66 ]] + 281 xmm7 70 [[ 66 ]] + 282 xmm8 70 [[ 66 ]] + 283 xmm9 70 [[ 66 ]] + 284 xmm10 70 [[ 66 ]] + 285 xmm11 70 [[ 66 ]] + 286 xmm12 70 [[ 66 ]] + 287 xmm13 70 [[ 66 ]] + 288 xmm14 70 [[ 66 ]] + 289 xmm15 70 [[ 66 ]] + 277 r13 70 [[ 66 ]] + 276 r12 70 [[ 66 ]] + 275 rdi 70 [[ 66 ]] + 274 rsi 70 [[ 66 ]] + 273 rbp 70 [[ 66 ]] + +L121: [[ START ]] + 121 merge ____ 10 [[ 138 141 144 151 154 158 173 235 234 233 232 231 230 229 228 227 226 225 224 223 222 221 220 219 218 413 326 376 381 120 ]] Ctrl + 138 begin 121 64 [[ 376 155 ]] int + 141 middle 121 64 [[ 135 381 ]] int + 144 end 121 64 [[ 142 170 ]] int + 151 $mem 121 13 [[ 150 172 ]] #BOT + 154 b 121 61 [[ 153 159 ]] *[int] + 158 a 121 61 [[ 326 ]] *[int] + 173 $rpc 121 86 [[ 117 ]] $[ALL] + 381 mov 121 141 [[ 145 ]] + 376 mov 121 138 [[ 137 ]] + 326 mov 121 158 [[ 327 148 161 157 ]] + 218 rbx 121 [[ 413 ]] + 413 mov 121 218 [[ 414 ]] + 221 rdi 121 [[ 117 ]] + 226 xmm6 121 [[ 117 ]] + 227 xmm7 121 [[ 117 ]] + 228 xmm8 121 [[ 117 ]] + 229 xmm9 121 [[ 117 ]] + 230 xmm10 121 [[ 117 ]] + 231 xmm11 121 [[ 117 ]] + 232 xmm12 121 [[ 117 ]] + 233 xmm13 121 [[ 117 ]] + 234 xmm14 121 [[ 117 ]] + 235 xmm15 121 [[ 117 ]] + 220 rsi 121 [[ 117 ]] + 219 rbp 121 [[ 117 ]] + 224 r14 121 [[ 117 ]] + 225 r15 121 [[ 117 ]] + 223 r13 121 [[ 117 ]] + 222 r12 121 [[ 117 ]] + +L190: [[ START ]] + 190 eq ____ 10 [[ 196 197 201 204 208 271 270 269 268 267 266 265 264 263 262 261 260 259 258 257 256 255 254 398 189 ]] Ctrl + 196 $mem 190 13 [[ 194 200 206 206 ]] #BOT + 197 a 190 61 [[ 194 ]] *[int] + 201 b 190 61 [[ 200 ]] *[int] + 204 n 190 64 [[ 202 ]] int + 208 $rpc 190 86 [[ 185 ]] $[ALL] + 398 #0 190 [[ 198 ]] 0 + 258 r12 190 [[ 185 ]] + 259 r13 190 [[ 185 ]] + 260 r14 190 [[ 185 ]] + 261 r15 190 [[ 185 ]] + 262 xmm6 190 [[ 185 ]] + 263 xmm7 190 [[ 185 ]] + 264 xmm8 190 [[ 185 ]] + 265 xmm9 190 [[ 185 ]] + 266 xmm10 190 [[ 185 ]] + 267 xmm11 190 [[ 185 ]] + 268 xmm12 190 [[ 185 ]] + 269 xmm13 190 [[ 185 ]] + 270 xmm14 190 [[ 185 ]] + 271 xmm15 190 [[ 185 ]] + 257 rdi 190 [[ 185 ]] + 256 rsi 190 [[ 185 ]] + 255 rbp 190 [[ 185 ]] + 254 rbx 190 [[ 185 ]] + +L58: [[ START ]] + 58 merge_s ____ 10 [[ 59 60 63 65 182 307 306 305 304 303 302 301 300 299 298 297 296 295 294 293 292 291 290 403 400 349 351 353 402 405 57 ]] Ctrl + 59 $mem 58 13 [[ 57 ]] #BOT + 60 a 58 61 [[ 400 ]] *[int] + 63 n 58 64 [[ 403 ]] int + 65 b 58 61 [[ 349 ]] *[int] + 182 $rpc 58 86 [[ 51 ]] $[ALL] + 405 mov 58 403 [[ 57 ]] + 402 mov 58 400 [[ 57 ]] + 353 #0 58 [[ 57 ]] 0 + 351 mov 58 349 [[ 57 ]] + 57 call 58 59 402 353 405 351 [[ 56 ]] Ctrl + 349 mov 58 65 [[ 350 351 ]] + 400 mov 58 60 [[ 401 402 ]] + 403 mov 58 63 [[ 404 405 ]] + 291 rbp 58 [[ 51 ]] + 295 r13 58 [[ 51 ]] + 296 r14 58 [[ 51 ]] + 297 r15 58 [[ 51 ]] + 298 xmm6 58 [[ 51 ]] + 299 xmm7 58 [[ 51 ]] + 300 xmm8 58 [[ 51 ]] + 301 xmm9 58 [[ 51 ]] + 302 xmm10 58 [[ 51 ]] + 303 xmm11 58 [[ 51 ]] + 304 xmm12 58 [[ 51 ]] + 305 xmm13 58 [[ 51 ]] + 306 xmm14 58 [[ 51 ]] + 307 xmm15 58 [[ 51 ]] + 290 rbx 58 [[ 51 ]] + 294 r12 58 [[ 51 ]] + 293 rdi 58 [[ 51 ]] + 292 rsi 58 [[ 51 ]] + +L93: [[ START ]] + 93 split_m ____ 10 [[ 99 101 102 103 106 177 253 252 251 250 249 248 247 246 245 244 243 242 241 240 239 238 237 236 391 336 332 328 342 395 110 108 92 ]] Ctrl + 99 $mem 93 13 [[ 97 175 ]] #BOT + 101 a 93 61 [[ 328 ]] *[int] + 102 b 93 61 [[ 332 ]] *[int] + 103 begin 93 64 [[ 391 ]] int + 106 end 93 64 [[ 336 ]] int + 177 $rpc 93 86 [[ 89 ]] $[ALL] + 395 mov 93 391 [[ 110 ]] + 332 mov 93 102 [[ 335 333 334 ]] + 336 mov 93 106 [[ 342 340 337 339 ]] + 391 mov 93 103 [[ 395 392 394 393 ]] + 342 mov 93 336 [[ 110 ]] + 328 mov 93 101 [[ 329 331 330 ]] + 110 sub 93 342 395 [[ 108 ]] int + 108 cmp 93 110 [[ 92 ]] bool + 92 j<= 93 108 [[ 91 98 ]] [ Ctrl, Ctrl] + 241 r13 93 [[ 89 ]] + 242 r14 93 [[ 89 ]] + 243 r15 93 [[ 89 ]] + 244 xmm6 93 [[ 89 ]] + 245 xmm7 93 [[ 89 ]] + 246 xmm8 93 [[ 89 ]] + 247 xmm9 93 [[ 89 ]] + 248 xmm10 93 [[ 89 ]] + 249 xmm11 93 [[ 89 ]] + 250 xmm12 93 [[ 89 ]] + 251 xmm13 93 [[ 89 ]] + 252 xmm14 93 [[ 89 ]] + 253 xmm15 93 [[ 89 ]] + 238 rsi 93 [[ 89 ]] + 237 rbp 93 [[ 89 ]] + 236 rbx 93 [[ 89 ]] + 239 rdi 93 [[ 89 ]] + 240 r12 93 [[ 89 ]] + +LOOP120: [[ L121 L122 ]] + 120 Loop ____ 121 420 [[ 137 145 150 155 170 119 ]] Ctrl + 137 Phi_i 120 376 139 [[ 148 135 140 139 157 ]] int + 145 Phi_j 120 381 146 [[ 162 142 146 147 161 ]] int + 150 Phi_$3 120 151 152 [[ 148 153 157 159 161 162 172 ]] #BOT + 155 Phi_k 120 138 156 [[ 170 153 156 159 ]] int + 170 cmp 120 155 144 [[ 119 ]] bool + 119 j>= 120 170 [[ 118 134 ]] [ Ctrl, Ctrl] + +LOOP189: [[ L190 L191 ]] + 189 Loop ____ 190 419 [[ 198 202 188 ]] Ctrl + 198 Phi_i 189 398 199 [[ 202 194 199 200 ]] int + 202 cmp 189 198 204 [[ 188 ]] bool + 188 j>= 189 202 [[ 187 193 ]] [ Ctrl, Ctrl] + +LOOP69: [[ L70 L71 ]] + 69 Loop ____ 70 425 [[ 74 80 72 68 ]] Ctrl + 74 Phi_k 69 75 76 [[ 72 76 81 83 ]] int + 80 Phi_$3 69 79 81 [[ 78 81 83 ]] #BOT + 72 cmp 69 74 77 [[ 68 ]] bool + 68 j>= 69 72 [[ 67 71 ]] [ Ctrl, Ctrl] + +L7: [[ L9 ]] + 7 CallEnd 8 [[ 6 184 ]] [ Ctrl, #BOT, 0] + 184 $mem 7 [[ 5 ]] #BOT + +L98: [[ L93 ]] + 98 False 92 [[ 339 394 105 107 104 345 330 335 348 393 97 ]] Ctrl + 330 mov 98 328 [[ 97 ]] + 335 mov 98 332 [[ 97 ]] + 393 mov 98 391 [[ 97 ]] + 348 mov 98 345 [[ 97 ]] + 97 call 98 99 330 393 348 335 [[ 96 ]] Ctrl + 339 mov 98 336 [[ 105 ]] + 394 mov 98 391 [[ 105 ]] + 105 add 98 339 394 [[ 104 ]] int + 107 #2 98 [[ 104 ]] 2 + 104 div 98 105 107 [[ 345 ]] int + 345 mov 98 104 [[ 348 347 346 ]] + +L56: [[ L58 ]] + 56 CallEnd 57 [[ 55 88 ]] [ Ctrl, #BOT, 0] + 88 $mem 56 [[ 54 ]] #BOT + +L91: [[ L93 ]] + 91 True 92 [[ 90 ]] Ctrl + +L6: [[ L7 ]] + 6 $ctrl 7 [[ 356 372 409 5 ]] Ctrl + 356 mov 6 355 [[ 5 ]] + 372 mov 6 371 [[ 5 ]] + 409 #10 6 [[ 5 ]] 10 + 5 call 6 184 356 372 409 [[ 4 ]] Ctrl + +L55: [[ L56 ]] + 55 $ctrl 56 [[ 350 354 401 404 54 ]] Ctrl + 350 mov 55 349 [[ 54 ]] + 354 #0 55 [[ 54 ]] 0 + 404 mov 55 403 [[ 54 ]] + 401 mov 55 400 [[ 54 ]] + 54 call 55 88 401 354 404 350 [[ 53 ]] Ctrl + +L118: [[ LOOP120 ]] + 118 True 119 [[ 172 414 415 117 ]] Ctrl + 172 ALLMEM 118 151 ____ 150 [[ 117 ]] #BOT + 414 mov 118 413 [[ 117 ]] + 415 #0 118 [[ 117 ]] 0 + 117 Return 118 172 415 173 414 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 [[ 1 ]] [ Ctrl, #BOT, 0] + +L134: [[ LOOP120 ]] + 134 False 119 [[ 135 133 ]] Ctrl + 135 cmp 134 137 141 [[ 133 ]] bool + 133 j< 134 135 [[ 132 163 ]] [ Ctrl, Ctrl] + +L187: [[ LOOP189 ]] + 187 True 188 [[ 169 186 ]] Ctrl + 169 #1 187 [[ 207 ]] 1 + +L193: [[ LOOP189 ]] + 193 False 188 [[ 200 194 192 ]] Ctrl + 200 ld8 193 196 201 198 [[ 194 ]] int + 194 cmp8 193 196 197 198 200 [[ 192 ]] bool + 192 j!= 193 194 [[ 191 205 ]] [ Ctrl, Ctrl] + +L67: [[ LOOP69 ]] + 67 True 68 [[ 78 62 66 ]] Ctrl + 78 ALLMEM 67 79 ____ 80 [[ 66 ]] #BOT + 62 #0 67 [[ 66 ]] 0 + 66 Return 67 78 62 85 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 [[ 1 ]] [ Ctrl, #BOT, 0] + +L71: [[ LOOP69 ]] + 71 False 68 [[ 83 81 76 425 ]] Ctrl + 76 inc 71 74 [[ 74 ]] int + 83 ld8 71 80 84 74 [[ 81 ]] int + 81 st8 71 80 82 74 83 [[ 80 ]] #3:Bot + +L96: [[ L98 ]] + 96 CallEnd 97 [[ 95 100 ]] [ Ctrl, #BOT, 0] + 100 $mem 96 [[ 94 ]] #BOT + +L4: [[ L6 ]] + 4 CallEnd 5 [[ 3 210 211 ]] [ Ctrl, #BOT, bool] + 210 $mem 4 [[ 2 ]] #BOT + 211 #2 4 [[ 2 ]] bool + +L95: [[ L96 ]] + 95 $ctrl 96 [[ 331 334 340 347 94 ]] Ctrl + 331 mov 95 328 [[ 94 ]] + 334 mov 95 332 [[ 94 ]] + 347 mov 95 345 [[ 94 ]] + 340 mov 95 336 [[ 94 ]] + 94 call 95 100 331 347 340 334 [[ 115 ]] Ctrl + +L132: [[ L134 ]] + 132 True 133 [[ 142 131 ]] Ctrl + 142 cmp 132 144 145 [[ 131 ]] bool + 131 j<= 132 142 [[ 130 164 ]] [ Ctrl, Ctrl] + +L53: [[ L55 ]] + 53 CallEnd 54 [[ 52 181 ]] [ Ctrl, #BOT, 0] + 181 $mem 53 [[ 51 ]] #BOT + +L163: [[ L134 ]] + 163 False 133 [[ 389 424 ]] Ctrl + 389 #0 163 [[ 168 ]] 0 + 424 jmp 163 [[ 127 ]] + +L191: [[ L193 ]] + 191 False 192 [[ 199 419 ]] Ctrl + 199 inc 191 198 [[ 198 ]] int + +L205: [[ L193 ]] + 205 True 192 [[ 399 418 ]] Ctrl + 399 #0 205 [[ 207 ]] 0 + 418 jmp 205 [[ 186 ]] + +L3: [[ L4 ]] + 3 $ctrl 4 [[ 417 2 ]] Ctrl + 417 mov 3 416 [[ 2 ]] + 2 Return 3 210 211 212 417 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 [[ 1 ]] [ Ctrl, #BOT, bool] + +L186: [[ L187 L205 ]] + 186 Region ____ 187 418 [[ 207 206 185 ]] Ctrl + 207 Phi_res 186 169 399 [[ 185 ]] bool + 206 ALLMEM 186 196 ____ 196 [[ 185 ]] #BOT + 185 Return 186 206 207 208 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 [[ 1 ]] [ Ctrl, #BOT, bool] + +L52: [[ L53 ]] + 52 $ctrl 53 [[ 352 51 ]] Ctrl + 352 #0 52 [[ 51 ]] 0 + 51 Return 52 181 352 182 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 [[ 1 ]] [ Ctrl, #BOT, 0] + +L115: [[ L95 ]] + 115 CallEnd 94 [[ 114 116 ]] [ Ctrl, #BOT, 0] + 116 $mem 115 [[ 113 ]] #BOT + +L130: [[ L132 ]] + 130 False 131 [[ 327 162 148 129 ]] Ctrl + 327 mov 130 326 [[ 162 ]] + 162 ld8 130 150 327 145 [[ 148 ]] int + 148 cmp8 130 150 326 137 162 [[ 129 ]] bool + 129 j<= 130 148 [[ 128 165 ]] [ Ctrl, Ctrl] + +L164: [[ L132 ]] + 164 True 131 [[ 388 127 ]] Ctrl + 388 #1 164 [[ 168 ]] 1 + +L114: [[ L115 ]] + 114 $ctrl 115 [[ 329 333 337 346 392 113 ]] Ctrl + 329 mov 114 328 [[ 113 ]] + 333 mov 114 332 [[ 113 ]] + 392 mov 114 391 [[ 113 ]] + 346 mov 114 345 [[ 113 ]] + 337 mov 114 336 [[ 113 ]] + 113 call 114 116 333 392 346 337 329 [[ 112 ]] Ctrl + +L128: [[ L130 ]] + 128 True 129 [[ 387 422 ]] Ctrl + 387 #1 128 [[ 168 ]] 1 + 422 jmp 128 [[ 127 ]] + +L165: [[ L130 ]] + 165 False 129 [[ 390 423 ]] Ctrl + 390 #0 165 [[ 168 ]] 0 + 423 jmp 165 [[ 127 ]] + +L112: [[ L114 ]] + 112 CallEnd 113 [[ 111 176 ]] [ Ctrl, #BOT, 0] + 176 $mem 112 [[ 175 ]] #BOT + +L127: [[ L128 L163 L164 L165 ]] + 127 Region ____ 422 424 164 423 [[ 168 166 126 ]] Ctrl + 168 Phi_con 127 387 389 388 390 [[ 166 ]] bool + 166 test 127 168 [[ 126 ]] + 126 j!= 127 166 [[ 123 160 ]] [ Ctrl, Ctrl] + +L111: [[ L112 ]] + 111 $ctrl 112 [[ 90 ]] Ctrl + +L90: [[ L91 L111 ]] + 90 Region ____ 91 111 [[ 175 215 89 ]] Ctrl + 175 Phi_$me 90 99 176 [[ 89 ]] #BOT + 215 #0 90 [[ 89 ]] 0 + 89 Return 90 175 215 177 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 [[ 1 ]] [ Ctrl, #BOT, 0] + +L160: [[ L127 ]] + 160 False 126 [[ 161 159 147 421 ]] Ctrl + 147 inc 160 145 [[ 146 ]] int + 161 ld8 160 150 326 145 [[ 159 ]] int + 421 jmp 160 [[ 122 ]] + 159 st8 160 150 154 155 161 [[ 152 ]] #3:Bot + +L123: [[ L127 ]] + 123 True 126 [[ 157 153 140 122 ]] Ctrl + 140 inc 123 137 [[ 139 ]] int + 157 ld8 123 150 326 137 [[ 153 ]] int + 153 st8 123 150 154 155 157 [[ 152 ]] #3:Bot + +L122: [[ L123 L160 ]] + 122 Region ____ 123 421 [[ 139 146 152 156 420 ]] Ctrl + 139 Phi_i 122 140 137 [[ 137 ]] int + 146 Phi_j 122 145 147 [[ 145 ]] int + 152 Phi_$3 122 153 159 [[ 150 ]] #3:Bot + 156 inc 122 155 [[ 155 ]] int + +L1: [[ L118 L67 L186 ]] + 1 Stop 2 51 89 117 66 185 [[ ]] Bot + + + +---split_merge { *![int] int int *![int] -> 0 #0}--------------------------- +0000 4883EC38 subi rsp -= #56 + a:r9,b:rcx,begin:rdx,end:r8 +0004 4889542428 mov [rsp+40] = rdx // def/loop #1 +0009 4C89442458 mov [rsp+88] = r8 // def/loop #0 +000E 48894C2450 mov [rsp+80] = rcx // def/loop #0 +0013 4C894C2448 mov [rsp+72] = r9 // def/loop #0 +0018 4C8B442458 mov r8 = [rsp+88] // use/loop/use #0 +001D 4C8B542428 mov r10 = [rsp+40] // use/loop/use #1 +0022 4D2BC2 sub r8 -= r10 +0025 4983F801 cmp r8, #1 +0029 7E6F j<= L90 // L98 +L98: +002B 488B442458 mov rax = [rsp+88] // use/loop/use #0 +0030 488B542428 mov rdx = [rsp+40] // use/loop/use #1 +0035 4803C2 add rax += rdx +0038 B902000000 ldi rcx = #2 +003D 489948F7F9 div rax = rax / rcx // kill rdx +0042 4889442440 mov [rsp+64] = rax // def/loop #0 +0047 488B4C2448 mov rcx = [rsp+72] // use/loop/use #0 +004C 4C8B4C2450 mov r9 = [rsp+80] // use/loop/use #0 +0051 4C8B442440 mov r8 = [rsp+64] // use/loop/use #0 +0056 488B542428 mov rdx = [rsp+40] // use/loop/use #1 +005B E8A0FFFFFF call split_merge rcx rdx r8 r9 +0060 488B4C2448 mov rcx = [rsp+72] // use/loop/use #0 +0065 4C8B4C2450 mov r9 = [rsp+80] // use/loop/use #0 +006A 4C8B442458 mov r8 = [rsp+88] // use/loop/use #0 +006F 488B542440 mov rdx = [rsp+64] // use/loop/use #0 +0074 E887FFFFFF call split_merge rcx rdx r8 r9 +0079 FF7424488F mov [rsp+32] = [rsp+72] // use/loop/use #0 +007E 442420 +0081 488B4C2450 mov rcx = [rsp+80] // use/loop/use #0 +0086 4C8B4C2458 mov r9 = [rsp+88] // use/loop/use #0 +008B 4C8B442440 mov r8 = [rsp+64] // use/loop/use #0 +0090 488B542428 mov rdx = [rsp+40] // use/loop/use #1 +0095 E836000000 call merge rcx rdx r8 r9 [stk#42] +L91: +L90: +009A 33C0 xor rax,rax +009C 4883C438C3 addi rsp += #56 +00A1 ret +---{ *![int] int int *![int] -> 0 #0}--------------------------- + +---copy_array { *![int] int int *![int] -> 0 #1}--------------------------- + begin:rdx,end:r8,b:r9,a:rcx +LOOP69: + k:rdx +00B0 493BD0 cmp rdx, r8 +00B3 7D10 j>= L67 // L71 +L71: +00B5 488B44D108 ld8 rax,[rcx+rdx*8+8] +00BA 498944D108 st8 [r9+rdx*8+8],rax +00BF 4883C201 inc rdx += #1 +00C3 EBEB jmp LOOP69 +L425: +L67: +00C5 33C0 xor rax,rax +00C7 C3 ret +---{ *![int] int int *![int] -> 0 #1}--------------------------- + +---merge { *![int] int int int *![int] -> 0 #0}--------------------------- + begin:rdx,middle:r8,end:r9,b:rcx,a:[rsp+40] +00D0 66480F6EC3 mov xmm0 = rbx // def/loop #2 +00D5 488B5C2428 mov rbx = [rsp+40] // def/empty1 #0 +00DA 4C8BDA mov r11 = rdx // use/self/phi #1 +00DD 4D8BD0 mov r10 = r8 // use/self/use #1 +LOOP120: + i:r11,j:r10,k:rdx +00E0 493BD1 cmp rdx, r9 +00E3 7D57 j>= L118 // L134 +L134: +00E5 4D3BD8 cmp r11, r8 +00E8 7C04 j< L132 // L163 +L163: +00EA 33C0 xor rax,rax +00EC EB24 jmp L127 +L424: +L132: +00EE 4D3BCA cmp r9, r10 +00F1 7E1A j<= L164 // L130 +L130: +00F3 488BC3 mov rax = rbx // use/empty1 #0 +00F6 4A8B44D008 ld8 rax,[rax+r10*8+8] +00FB 4A3944DB08 cmp8 rax, [rbx+r11*8+8] +0100 7E04 j<= L128 // L165 +L165: +0102 33C0 xor rax,rax +0104 EB0C jmp L127 +L423: +L128: +0106 B801000000 ldi rax = #1 +010B EB05 jmp L127 +L422: +L164: +010D B801000000 ldi rax = #1 +L127: + cond:rax +0112 4883F800 test rax +0116 7510 j!= L123 // L160 +L160: +0118 4A8B44D308 ld8 rax,[rbx+r10*8+8] +011D 488944D108 st8 [rcx+rdx*8+8],rax +0122 4983C201 inc r10 += #1 +0126 EB0E jmp L122 +L421: +L123: +0128 4A8B44DB08 ld8 rax,[rbx+r11*8+8] +012D 488944D108 st8 [rcx+rdx*8+8],rax +0132 4983C301 inc r11 += #1 +L122: + i:r11,j:r10 +0136 4883C201 inc rdx += #1 +013A EBA4 jmp LOOP120 +L420: +L118: +013C 66480F7EC3 mov rbx = xmm0 // use/loop/use #2 +0141 33C0 xor rax,rax +0143 C3 ret +---{ *![int] int int int *![int] -> 0 #0}--------------------------- + +---eq { *![int] *![int] int -> bool #1}--------------------------- + a:rcx,b:rdx,n:r8 +0150 33C0 xor rax,rax +LOOP189: + i:rax +0152 493BC0 cmp rax, r8 +0155 7D16 j>= L187 // L193 +L193: +0157 4C8B4CC208 ld8 r9,[rdx+rax*8+8] +015C 4C394CC108 cmp8 r9, [rcx+rax*8+8] +0161 7506 j!= L205 // L191 +L191: +0163 4883C001 inc rax += #1 +0167 EBE9 jmp LOOP189 +L419: +L205: +0169 33C0 xor rax,rax +016B EB05 jmp L186 +L418: +L187: +016D B801000000 ldi rax = #1 +L186: + result:rax +0172 C3 ret +---{ *![int] *![int] int -> bool #1}--------------------------- + +---main { -> bool #0}--------------------------- +0180 4883EC28 subi rsp -= #40 +0184 48895C2420 mov [rsp+32] = rbx // def/loop #2 +0189 BA58000000 ldi rdx = #88 +018E B901000000 alloc ldi rcx = #1 +0193 E800000000 call #calloc +0198 4889442418 mov [rsp+24] = rax // def/loop #0 +019D 4C8B4C2418 mov r9 = [rsp+24] // use/loop/use #0 +01A2 49C741080A st8 [r9+8],#10 +01A7 000000 +01AA 4C8B442418 mov r8 = [rsp+24] // use/loop/use #0 +01AF 49C7401009 st8 [r8+16],#9 +01B4 000000 +01B7 488B542418 mov rdx = [rsp+24] // use/loop/use #0 +01BC 48C7421808 st8 [rdx+24],#8 +01C1 000000 +01C4 488B4C2418 mov rcx = [rsp+24] // use/loop/use #0 +01C9 48C7412007 st8 [rcx+32],#7 +01CE 000000 +01D1 488B442418 mov rax = [rsp+24] // use/loop/use #0 +01D6 48C7402806 st8 [rax+40],#6 +01DB 000000 +01DE 4C8B5C2418 mov r11 = [rsp+24] // use/loop/use #0 +01E3 49C7433005 st8 [r11+48],#5 +01E8 000000 +01EB 4C8B542418 mov r10 = [rsp+24] // use/loop/use #0 +01F0 49C7423804 st8 [r10+56],#4 +01F5 000000 +01F8 4C8B4C2418 mov r9 = [rsp+24] // use/loop/use #0 +01FD 49C7414003 st8 [r9+64],#3 +0202 000000 +0205 4C8B442418 mov r8 = [rsp+24] // use/loop/use #0 +020A 49C7404802 st8 [r8+72],#2 +020F 000000 +0212 488B542418 mov rdx = [rsp+24] // use/loop/use #0 +0217 C7020A0000 st4 [rdx],#10 +021C 00 +021D 488B4C2418 mov rcx = [rsp+24] // use/loop/use #0 +0222 48C7415001 st8 [rcx+80],#1 +0227 000000 +022A BA58000000 ldi rdx = #88 +022F B901000000 alloc ldi rcx = #1 +0234 E800000000 call #calloc +0239 4889442410 mov [rsp+16] = rax // def/empty1 #1 +023E C7000A0000 st4 [rax],#10 +0243 00 +0244 BA58000000 ldi rdx = #88 +0249 B901000000 alloc ldi rcx = #1 +024E E800000000 call #calloc +0253 488BD8 mov rbx = rax // def/empty1 #0 +0256 48C7430801 st8 [rbx+8],#1 +025B 000000 +025E 48C7431002 st8 [rbx+16],#2 +0263 000000 +0266 48C7431803 st8 [rbx+24],#3 +026B 000000 +026E 48C7432004 st8 [rbx+32],#4 +0273 000000 +0276 48C7432805 st8 [rbx+40],#5 +027B 000000 +027E 48C7433006 st8 [rbx+48],#6 +0283 000000 +0286 48C7433807 st8 [rbx+56],#7 +028B 000000 +028E 48C7434008 st8 [rbx+64],#8 +0293 000000 +0296 48C7434809 st8 [rbx+72],#9 +029B 000000 +029E C7030A0000 st4 [rbx],#10 +02A3 00 +02A4 48C743500A st8 [rbx+80],#10 +02A9 000000 +02AC 488B4C2418 mov rcx = [rsp+24] // use/loop/use #0 +02B1 488B542410 mov rdx = [rsp+16] // use/empty1 #0 +02B6 41B80A0000 ldi r8 = #10 +02BB 00 +02BC E81F000000 call merge_sort rcx rdx r8 +02C1 488B4C2418 mov rcx = [rsp+24] // use/loop/use #0 +02C6 488BD3 mov rdx = rbx // use/empty1 #0 +02C9 41B80A0000 ldi r8 = #10 +02CE 00 +02CF E87CFEFFFF call eq rcx rdx r8 +02D4 488B5C2420 mov rbx = [rsp+32] // use/loop/use #2 +02D9 4883C428C3 addi rsp += #40 +02DE ret +---{ -> bool #0}--------------------------- + +---merge_sort { *![int] *![int] int -> 0 #0}--------------------------- +02E0 4883EC28 subi rsp -= #40 + a:rcx,n:r8,b:rdx +02E4 4C89442440 mov [rsp+64] = r8 // def/loop #1 +02E9 48894C2438 mov [rsp+56] = rcx // def/loop #1 +02EE 4889542430 mov [rsp+48] = rdx // def/loop #0 +02F3 4C8B4C2430 mov r9 = [rsp+48] // use/loop/use #0 +02F8 33D2 xor rdx,rdx +02FA 488B4C2438 mov rcx = [rsp+56] // use/loop/use #1 +02FF 4C8B442440 mov r8 = [rsp+64] // use/loop/use #1 +0304 E8A7FDFFFF call copy_array rcx rdx r8 r9 +0309 4C8B4C2430 mov r9 = [rsp+48] // use/loop/use #0 +030E 33D2 xor rdx,rdx +0310 488B4C2438 mov rcx = [rsp+56] // use/loop/use #1 +0315 4C8B442440 mov r8 = [rsp+64] // use/loop/use #1 +031A E8E1FCFFFF call split_merge rcx rdx r8 r9 +031F 33C0 xor rax,rax +0321 4883C428C3 addi rsp += #40 +0326 ret +---{ *![int] *![int] int -> 0 #0}---------------------------