13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.virtual.phases.ea; 24 25 import static org.graalvm.compiler.core.common.GraalOptions.ReadEliminationMaxLoopVisits; 26 import static org.graalvm.word.LocationIdentity.any; 27 28 import java.util.Iterator; 29 import java.util.List; 30 31 import org.graalvm.compiler.core.common.cfg.Loop; 32 import org.graalvm.compiler.core.common.type.Stamp; 33 import org.graalvm.compiler.debug.Debug; 34 import org.graalvm.compiler.graph.Node; 35 import org.graalvm.compiler.nodes.FieldLocationIdentity; 36 import org.graalvm.compiler.nodes.FixedWithNextNode; 37 import org.graalvm.compiler.nodes.LoopExitNode; 38 import org.graalvm.compiler.nodes.PhiNode; 39 import org.graalvm.compiler.nodes.ProxyNode; 40 import org.graalvm.compiler.nodes.ValueNode; 41 import org.graalvm.compiler.nodes.ValuePhiNode; 42 import org.graalvm.compiler.nodes.ValueProxyNode; 43 import org.graalvm.compiler.nodes.cfg.Block; 44 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph; 45 import org.graalvm.compiler.nodes.extended.GuardedNode; 46 import org.graalvm.compiler.nodes.extended.GuardingNode; 47 import org.graalvm.compiler.nodes.extended.UnsafeAccessNode; 48 import org.graalvm.compiler.nodes.extended.RawLoadNode; 49 import org.graalvm.compiler.nodes.extended.RawStoreNode; 50 import org.graalvm.compiler.nodes.java.AccessFieldNode; 51 import org.graalvm.compiler.nodes.java.LoadFieldNode; 52 import org.graalvm.compiler.nodes.java.StoreFieldNode; 53 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint; 54 import org.graalvm.compiler.nodes.memory.ReadNode; 55 import org.graalvm.compiler.nodes.memory.WriteNode; 56 import org.graalvm.compiler.nodes.util.GraphUtil; 57 import org.graalvm.compiler.options.OptionValues; 58 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.CacheEntry; 59 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.LoadCacheEntry; 60 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.UnsafeLoadCacheEntry; 61 import org.graalvm.util.Equivalence; 62 import org.graalvm.util.EconomicMap; 63 import org.graalvm.util.EconomicSet; 64 import org.graalvm.util.MapCursor; 65 import org.graalvm.word.LocationIdentity; 66 67 import jdk.vm.ci.meta.JavaKind; 68 69 /** 70 * This closure initially handled a set of nodes that is disjunct from 71 * {@link PEReadEliminationClosure}, but over time both have evolved so that there's a significant 72 * overlap. 73 */ 74 public final class ReadEliminationClosure extends EffectsClosure<ReadEliminationBlockState> { 75 private final boolean considerGuards; 76 77 public ReadEliminationClosure(ControlFlowGraph cfg, boolean considerGuards) { 78 super(null, cfg); 79 this.considerGuards = considerGuards; 80 } 81 82 @Override 83 protected ReadEliminationBlockState getInitialState() { 342 } else { 343 OptionValues options = loop.getHeader().getBeginNode().getOptions(); 344 if (loopKilledLocations.visits() > ReadEliminationMaxLoopVisits.getValue(options)) { 345 // we have processed the loop too many times, kill all locations so the inner 346 // loop will never be processed more than once again on visit 347 loopKilledLocations.setKillsAll(); 348 } else { 349 // we have fully processed this loop >1 times, update the killed locations 350 EconomicSet<LocationIdentity> forwardEndLiveLocations = EconomicSet.create(Equivalence.DEFAULT); 351 for (CacheEntry<?> entry : initialState.readCache.getKeys()) { 352 forwardEndLiveLocations.add(entry.getIdentity()); 353 } 354 for (CacheEntry<?> entry : mergedStates.readCache.getKeys()) { 355 forwardEndLiveLocations.remove(entry.getIdentity()); 356 } 357 // every location that is alive before the loop but not after is killed by the 358 // loop 359 for (LocationIdentity location : forwardEndLiveLocations) { 360 loopKilledLocations.rememberLoopKilledLocation(location); 361 } 362 if (Debug.isLogEnabled() && loopKilledLocations != null) { 363 Debug.log("[Early Read Elimination] Setting loop killed locations of loop at node %s with %s", 364 loop.getHeader().getBeginNode(), forwardEndLiveLocations); 365 } 366 } 367 // remember the loop visit 368 loopKilledLocations.visited(); 369 } 370 } 371 } 372 373 @Override 374 protected ReadEliminationBlockState stripKilledLoopLocations(Loop<Block> loop, ReadEliminationBlockState originalInitialState) { 375 ReadEliminationBlockState initialState = super.stripKilledLoopLocations(loop, originalInitialState); 376 LoopKillCache loopKilledLocations = loopLocationKillCache.get(loop); 377 if (loopKilledLocations != null && loopKilledLocations.loopKillsLocations()) { 378 Iterator<CacheEntry<?>> it = initialState.readCache.getKeys().iterator(); 379 while (it.hasNext()) { 380 CacheEntry<?> entry = it.next(); 381 if (loopKilledLocations.containsLocation(entry.getIdentity())) { 382 it.remove(); 383 } | 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.virtual.phases.ea; 24 25 import static org.graalvm.compiler.core.common.GraalOptions.ReadEliminationMaxLoopVisits; 26 import static org.graalvm.word.LocationIdentity.any; 27 28 import java.util.Iterator; 29 import java.util.List; 30 31 import org.graalvm.compiler.core.common.cfg.Loop; 32 import org.graalvm.compiler.core.common.type.Stamp; 33 import org.graalvm.compiler.graph.Node; 34 import org.graalvm.compiler.nodes.FieldLocationIdentity; 35 import org.graalvm.compiler.nodes.FixedWithNextNode; 36 import org.graalvm.compiler.nodes.LoopExitNode; 37 import org.graalvm.compiler.nodes.PhiNode; 38 import org.graalvm.compiler.nodes.ProxyNode; 39 import org.graalvm.compiler.nodes.ValueNode; 40 import org.graalvm.compiler.nodes.ValuePhiNode; 41 import org.graalvm.compiler.nodes.ValueProxyNode; 42 import org.graalvm.compiler.nodes.cfg.Block; 43 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph; 44 import org.graalvm.compiler.nodes.extended.GuardedNode; 45 import org.graalvm.compiler.nodes.extended.GuardingNode; 46 import org.graalvm.compiler.nodes.extended.RawLoadNode; 47 import org.graalvm.compiler.nodes.extended.RawStoreNode; 48 import org.graalvm.compiler.nodes.extended.UnsafeAccessNode; 49 import org.graalvm.compiler.nodes.java.AccessFieldNode; 50 import org.graalvm.compiler.nodes.java.LoadFieldNode; 51 import org.graalvm.compiler.nodes.java.StoreFieldNode; 52 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint; 53 import org.graalvm.compiler.nodes.memory.ReadNode; 54 import org.graalvm.compiler.nodes.memory.WriteNode; 55 import org.graalvm.compiler.nodes.util.GraphUtil; 56 import org.graalvm.compiler.options.OptionValues; 57 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.CacheEntry; 58 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.LoadCacheEntry; 59 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.UnsafeLoadCacheEntry; 60 import org.graalvm.util.EconomicMap; 61 import org.graalvm.util.EconomicSet; 62 import org.graalvm.util.Equivalence; 63 import org.graalvm.util.MapCursor; 64 import org.graalvm.word.LocationIdentity; 65 66 import jdk.vm.ci.meta.JavaKind; 67 68 /** 69 * This closure initially handled a set of nodes that is disjunct from 70 * {@link PEReadEliminationClosure}, but over time both have evolved so that there's a significant 71 * overlap. 72 */ 73 public final class ReadEliminationClosure extends EffectsClosure<ReadEliminationBlockState> { 74 private final boolean considerGuards; 75 76 public ReadEliminationClosure(ControlFlowGraph cfg, boolean considerGuards) { 77 super(null, cfg); 78 this.considerGuards = considerGuards; 79 } 80 81 @Override 82 protected ReadEliminationBlockState getInitialState() { 341 } else { 342 OptionValues options = loop.getHeader().getBeginNode().getOptions(); 343 if (loopKilledLocations.visits() > ReadEliminationMaxLoopVisits.getValue(options)) { 344 // we have processed the loop too many times, kill all locations so the inner 345 // loop will never be processed more than once again on visit 346 loopKilledLocations.setKillsAll(); 347 } else { 348 // we have fully processed this loop >1 times, update the killed locations 349 EconomicSet<LocationIdentity> forwardEndLiveLocations = EconomicSet.create(Equivalence.DEFAULT); 350 for (CacheEntry<?> entry : initialState.readCache.getKeys()) { 351 forwardEndLiveLocations.add(entry.getIdentity()); 352 } 353 for (CacheEntry<?> entry : mergedStates.readCache.getKeys()) { 354 forwardEndLiveLocations.remove(entry.getIdentity()); 355 } 356 // every location that is alive before the loop but not after is killed by the 357 // loop 358 for (LocationIdentity location : forwardEndLiveLocations) { 359 loopKilledLocations.rememberLoopKilledLocation(location); 360 } 361 if (debug.isLogEnabled() && loopKilledLocations != null) { 362 debug.log("[Early Read Elimination] Setting loop killed locations of loop at node %s with %s", 363 loop.getHeader().getBeginNode(), forwardEndLiveLocations); 364 } 365 } 366 // remember the loop visit 367 loopKilledLocations.visited(); 368 } 369 } 370 } 371 372 @Override 373 protected ReadEliminationBlockState stripKilledLoopLocations(Loop<Block> loop, ReadEliminationBlockState originalInitialState) { 374 ReadEliminationBlockState initialState = super.stripKilledLoopLocations(loop, originalInitialState); 375 LoopKillCache loopKilledLocations = loopLocationKillCache.get(loop); 376 if (loopKilledLocations != null && loopKilledLocations.loopKillsLocations()) { 377 Iterator<CacheEntry<?>> it = initialState.readCache.getKeys().iterator(); 378 while (it.hasNext()) { 379 CacheEntry<?> entry = it.next(); 380 if (loopKilledLocations.containsLocation(entry.getIdentity())) { 381 it.remove(); 382 } |