From 300d2a9c3672acacc8bdd8d5370a424651a00571 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Sun, 18 Oct 2026 22:09:58 -0700 Subject: Cleanup & backport The phase rework, made new phases explicit and add them to the CodeGen driver. Fix the flag-spilling on X86 and ARM. Fix the GCM conservative anti-deps and backport. --- .../java/com/seaofnodes/simple/InstSelect.java | 74 ++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 chapter19/src/main/java/com/seaofnodes/simple/InstSelect.java (limited to 'chapter19/src/main/java/com/seaofnodes/simple/InstSelect.java') diff --git a/chapter19/src/main/java/com/seaofnodes/simple/InstSelect.java b/chapter19/src/main/java/com/seaofnodes/simple/InstSelect.java new file mode 100644 index 00000000..967a553c --- /dev/null +++ b/chapter19/src/main/java/com/seaofnodes/simple/InstSelect.java @@ -0,0 +1,74 @@ +package com.seaofnodes.simple; + +import com.seaofnodes.simple.node.*; +import java.util.BitSet; +import java.util.IdentityHashMap; +import com.seaofnodes.simple.node.cpus.x86_64_v2.MemOpX86; + +// Replace ideal nodes with machine nodes, then rebuild the copied graph's uses. +class InstSelect { + private final CodeGen _code; + InstSelect(CodeGen code) { _code=code; } + + @SuppressWarnings("unchecked") + void run(String cpu, String callingConv, String base) { + _code._callingConv = switch(callingConv) { + case "SystemV" -> CodeGen.CallingConv.SystemV; + case "Win64" -> CodeGen.CallingConv.Win64; + default -> throw Utils.TODO(); // Unknown calling convention + }; + + // Look for CPU in fixed named place: + // com.seaofnodes.simple.node.cpus."cpu"."cpu.class" + String clzFile = "com.seaofnodes.simple.node.cpus."+cpu+"."+cpu; + try { _code._mach = ((Class) Class.forName( clzFile )).getDeclaredConstructor().newInstance(); } + catch( Exception e ) { throw new RuntimeException(e); } + + // Convert to machine ops + _code._uid = 1; // All new machine nodes reset numbering + var map = new IdentityHashMap(); + _instSelect( _code._stop, map ); + _code._stop = ( StopNode)map.get(_code._stop ); + _code._start = (StartNode)map.get(_code._start); + _instOuts(_code._stop,_code.visit()); + _code._visit.clear(); + } + + private Node _instSelect( Node n, IdentityHashMap map ) { + if( n==null ) return null; + Node x = map.get(n); + if( x !=null ) return x; // Been there, done that + + // If n is a MachConcrete, then its part of a multi-node expansion. + // It does not need instruction selection (already selected!) + // but it does need its inputs walked. + if( n instanceof MachConcreteNode || n instanceof MemOpX86) { + for( int i=0; i < n.nIns(); i++ ) + n._inputs.set(i, _instSelect(n.in(i),map) ); + return n; + } + + // Produce a machine node from n; map it to flag as done so stops cycles. + map.put(n, x=_code._mach.instSelect(n) ); + // Walk machine op and replace inputs with mapped inputs + for( int i=0; i < x.nIns(); i++ ) + x._inputs.set(i, _instSelect(x.in(i),map) ); + if( x instanceof MachNode mach ) + mach.postSelect(); // Post selection action + + // Updates forward edges only. + n._outputs.clear(); + return x; + } + + private void _instOuts( Node n, BitSet visit ) { + if( visit.get(n._nid) ) return; + visit.set(n._nid); + for( Node in : n._inputs ) + if( in!=null ) { + in._outputs.push(n); + _instOuts(in,visit); + } + } + +} -- cgit v1.2.3