summaryrefslogtreecommitdiff
path: root/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2024-09-12 11:13:31 -0700
committerCliff Click <cliffc@acm.org>2024-10-23 17:51:09 -0700
commit67dc6202dee2ce983778ba3143cc3f00196aeb7c (patch)
treee1622c3cd33e3761b1fb5aa55de51765c93f3de3 /src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java
parentcb6d02efd0eca71076e458b890571385f0bf64a4 (diff)
downloadSimple-linear-chapter15.tar.gz
Simple-linear-chapter15.zip
Chapter 15: Arrayslinear-chapter15
Co-authored-by: XmiliaH <xmilia.hermit@gmail.com> Co-authored-by: Thalia Archibald <thalia@archibald.dev> Co-authored-by: Robert Obkircher <robert.obkircher@gmail.com>
Diffstat (limited to 'src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java')
-rw-r--r--src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java36
1 files changed, 18 insertions, 18 deletions
diff --git a/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java b/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java
index 8a96e69c..2eac6ccc 100644
--- a/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java
+++ b/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java
@@ -69,17 +69,6 @@ public abstract class GlobalCodeMotion {
cfg.loopDepth();
for( Node n : cfg._inputs )
_schedEarly(n,visit);
- // Strictly for dead infinite loops, we can have entire code blocks
- // not reachable from below - so we reach down, from above, one
- // step. Since _schedEarly modifies the output arrays, the normal
- // region._outputs ArrayList iterator throws CME. The extra edges
- // are always *added* after any Phis, so just walk the Phi prefix.
- if( cfg instanceof RegionNode region ) {
- int len = region.nOuts();
- for( int i=0; i<len; i++ )
- if( region.out(i) instanceof PhiNode phi )
- _schedEarly(phi,visit);
- }
}
}
@@ -95,18 +84,20 @@ public abstract class GlobalCodeMotion {
private static void _schedEarly(Node n, BitSet visit) {
if( n==null || visit.get(n._nid) ) return; // Been there, done that
+ assert !(n instanceof CFGNode);
visit.set(n._nid);
// Schedule not-pinned not-CFG inputs before self. Since skipping
// Pinned, this never walks the backedge of Phis (and thus spins around
// a data-only loop, eventually attempting relying on some pre-visited-
// not-post-visited data op with no scheduled control.
for( Node def : n._inputs )
- if( def!=null && !def.isPinned() )
+ if( def!=null )
_schedEarly(def,visit);
// If not-pinned (e.g. constants, projections, phi) and not-CFG
if( !n.isPinned() ) {
// Schedule at deepest input
CFGNode early = Parser.START; // Maximally early, lowest idepth
+ if( n.in(0) instanceof CFGNode cfg ) early = cfg;
for( int i=1; i<n.nIns(); i++ )
if( n.in(i).cfg0().idepth() > early.idepth() )
early = n.in(i).cfg0(); // Latest/deepest input
@@ -123,7 +114,7 @@ public abstract class GlobalCodeMotion {
// Copy the best placement choice into the control slot
for( int i=0; i<late.length; i++ )
- if( ns[i] != null )
+ if( ns[i] != null && !(ns[i] instanceof ProjNode) )
ns[i].setDef(0,late[i]);
}
@@ -138,18 +129,22 @@ public abstract class GlobalCodeMotion {
// These I know the late schedule of, and need to set early for loops
if( n instanceof CFGNode cfg ) late[n._nid] = cfg.blockHead() ? cfg : cfg.cfg(0);
else if( n instanceof PhiNode phi ) late[n._nid] = phi.region();
- else if( n.isPinned() ) late[n._nid] = n.cfg0();
+ else if( n instanceof ProjNode && n.in(0) instanceof CFGNode cfg ) late[n._nid] = cfg;
else {
// All uses done?
for( Node use : n._outputs )
- if( late[use._nid]==null )
+ if( use!=null && late[use._nid]==null )
continue outer; // Nope, await all uses done
// Loads need their memory inputs' uses also done
if( n instanceof LoadNode ld )
for( Node memuse : ld.mem()._outputs )
- if( memuse._type instanceof TypeMem && late[memuse._nid]==null )
+ if( late[memuse._nid]==null &&
+ // Load-use directly defines memory
+ (memuse._type instanceof TypeMem ||
+ // Load-use indirectly defines memory
+ (memuse._type instanceof TypeTuple tt && tt._types[ld._alias] instanceof TypeMem)) )
continue outer;
// All uses done, schedule
@@ -170,11 +165,12 @@ public abstract class GlobalCodeMotion {
private static void _doSchedLate(Node n, Node[] ns, CFGNode[] late) {
// Walk uses, gathering the LCA (Least Common Ancestor) of uses
- CFGNode early = (CFGNode)n.in(0);
+ CFGNode early = n.in(0) instanceof CFGNode cfg ? cfg : n.in(0).cfg0();
assert early != null;
CFGNode lca = null;
for( Node use : n._outputs )
- lca = use_block(n,use, late)._idom(lca,null);
+ if( use != null )
+ lca = use_block(n,use, late)._idom(lca,null);
// Loads may need anti-dependencies, raising their LCA
if( n instanceof LoadNode load )
@@ -226,6 +222,10 @@ public abstract class GlobalCodeMotion {
assert late[st._nid]!=null;
lca = anti_dep(load,late[st._nid],st.cfg0(),lca,st);
break;
+ case NewNode st:
+ assert late[st._nid]!=null;
+ lca = anti_dep(load,late[st._nid],st.cfg0(),lca,st);
+ break;
case PhiNode phi:
// Repeat anti-dep for matching Phi inputs.
// No anti-dep edges but may raise the LCA.