< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java

Print this page




  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  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;


 129                 }
 130             }
 131         } else if (node instanceof WriteNode) {
 132             WriteNode write = (WriteNode) node;
 133             if (write.getLocationIdentity().isSingle()) {
 134                 ValueNode object = GraphUtil.unproxify(write.getAddress());
 135                 LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity());
 136                 ValueNode cachedValue = state.getCacheEntry(identifier);
 137 
 138                 ValueNode value = getScalarAlias(write.value());
 139                 if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
 140                     effects.deleteNode(write);
 141                     deleted = true;
 142                 }
 143                 processIdentity(state, write.getLocationIdentity());
 144                 state.addCacheEntry(identifier, value);
 145             } else {
 146                 processIdentity(state, write.getLocationIdentity());
 147             }
 148         } else if (node instanceof UnsafeAccessNode) {


 149             if (node instanceof RawLoadNode) {
 150                 RawLoadNode load = (RawLoadNode) node;
 151                 if (load.getLocationIdentity().isSingle()) {
 152                     ValueNode object = GraphUtil.unproxify(load.object());
 153                     UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, load.offset(), load.getLocationIdentity());
 154                     ValueNode cachedValue = state.getCacheEntry(identifier);
 155                     if (cachedValue != null && areValuesReplaceable(load, cachedValue, considerGuards)) {
 156                         effects.replaceAtUsages(load, cachedValue, load);
 157                         addScalarAlias(load, cachedValue);
 158                         deleted = true;
 159                     } else {
 160                         state.addCacheEntry(identifier, load);
 161                     }
 162                 }
 163             } else {
 164                 assert node instanceof RawStoreNode;
 165                 RawStoreNode write = (RawStoreNode) node;
 166                 if (write.getLocationIdentity().isSingle()) {
 167                     ValueNode object = GraphUtil.unproxify(write.object());
 168                     UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, write.offset(), write.getLocationIdentity());
 169                     ValueNode cachedValue = state.getCacheEntry(identifier);
 170 
 171                     ValueNode value = getScalarAlias(write.value());
 172                     if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
 173                         effects.deleteNode(write);
 174                         deleted = true;
 175                     }
 176                     processIdentity(state, write.getLocationIdentity());
 177                     state.addCacheEntry(identifier, value);
 178                 } else {
 179                     processIdentity(state, write.getLocationIdentity());

 180                 }
 181             }
 182         } else if (node instanceof MemoryCheckpoint.Single) {
 183             LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
 184             processIdentity(state, identity);
 185         } else if (node instanceof MemoryCheckpoint.Multi) {
 186             for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
 187                 processIdentity(state, identity);
 188             }
 189         }
 190         return deleted;
 191     }
 192 
 193     private static boolean areValuesReplaceable(ValueNode originalValue, ValueNode replacementValue, boolean considerGuards) {
 194         return originalValue.stamp().isCompatible(replacementValue.stamp()) &&
 195                         (!considerGuards || (getGuard(originalValue) == null || getGuard(originalValue) == getGuard(replacementValue)));
 196     }
 197 
 198     private static GuardingNode getGuard(ValueNode node) {
 199         if (node instanceof GuardedNode) {




  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  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 jdk.vm.ci.meta.ResolvedJavaType;
  32 import org.graalvm.compiler.core.common.cfg.Loop;
  33 import org.graalvm.compiler.core.common.type.Stamp;
  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.RawLoadNode;
  48 import org.graalvm.compiler.nodes.extended.RawStoreNode;
  49 import org.graalvm.compiler.nodes.extended.UnsafeAccessNode;
  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.type.StampTool;
  57 import org.graalvm.compiler.nodes.util.GraphUtil;
  58 import org.graalvm.compiler.options.OptionValues;
  59 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.CacheEntry;
  60 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.LoadCacheEntry;
  61 import org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.UnsafeLoadCacheEntry;
  62 import org.graalvm.util.EconomicMap;
  63 import org.graalvm.util.EconomicSet;
  64 import org.graalvm.util.Equivalence;
  65 import org.graalvm.util.MapCursor;
  66 import org.graalvm.word.LocationIdentity;
  67 
  68 import jdk.vm.ci.meta.JavaKind;
  69 
  70 /**
  71  * This closure initially handled a set of nodes that is disjunct from
  72  * {@link PEReadEliminationClosure}, but over time both have evolved so that there's a significant
  73  * overlap.
  74  */
  75 public final class ReadEliminationClosure extends EffectsClosure<ReadEliminationBlockState> {
  76     private final boolean considerGuards;


 131                 }
 132             }
 133         } else if (node instanceof WriteNode) {
 134             WriteNode write = (WriteNode) node;
 135             if (write.getLocationIdentity().isSingle()) {
 136                 ValueNode object = GraphUtil.unproxify(write.getAddress());
 137                 LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity());
 138                 ValueNode cachedValue = state.getCacheEntry(identifier);
 139 
 140                 ValueNode value = getScalarAlias(write.value());
 141                 if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
 142                     effects.deleteNode(write);
 143                     deleted = true;
 144                 }
 145                 processIdentity(state, write.getLocationIdentity());
 146                 state.addCacheEntry(identifier, value);
 147             } else {
 148                 processIdentity(state, write.getLocationIdentity());
 149             }
 150         } else if (node instanceof UnsafeAccessNode) {
 151             ResolvedJavaType type = StampTool.typeOrNull(((UnsafeAccessNode) node).object());
 152             if (type != null && !type.isArray()) {
 153                 if (node instanceof RawLoadNode) {
 154                     RawLoadNode load = (RawLoadNode) node;
 155                     if (load.getLocationIdentity().isSingle()) {
 156                         ValueNode object = GraphUtil.unproxify(load.object());
 157                         UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, load.offset(), load.getLocationIdentity());
 158                         ValueNode cachedValue = state.getCacheEntry(identifier);
 159                         if (cachedValue != null && areValuesReplaceable(load, cachedValue, considerGuards)) {
 160                             effects.replaceAtUsages(load, cachedValue, load);
 161                             addScalarAlias(load, cachedValue);
 162                             deleted = true;
 163                         } else {
 164                             state.addCacheEntry(identifier, load);
 165                         }
 166                     }
 167                 } else {
 168                     assert node instanceof RawStoreNode;
 169                     RawStoreNode write = (RawStoreNode) node;
 170                     if (write.getLocationIdentity().isSingle()) {
 171                         ValueNode object = GraphUtil.unproxify(write.object());
 172                         UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, write.offset(), write.getLocationIdentity());
 173                         ValueNode cachedValue = state.getCacheEntry(identifier);
 174 
 175                         ValueNode value = getScalarAlias(write.value());
 176                         if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
 177                             effects.deleteNode(write);
 178                             deleted = true;
 179                         }
 180                         processIdentity(state, write.getLocationIdentity());
 181                         state.addCacheEntry(identifier, value);
 182                     } else {
 183                         processIdentity(state, write.getLocationIdentity());
 184                     }
 185                 }
 186             }
 187         } else if (node instanceof MemoryCheckpoint.Single) {
 188             LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
 189             processIdentity(state, identity);
 190         } else if (node instanceof MemoryCheckpoint.Multi) {
 191             for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
 192                 processIdentity(state, identity);
 193             }
 194         }
 195         return deleted;
 196     }
 197 
 198     private static boolean areValuesReplaceable(ValueNode originalValue, ValueNode replacementValue, boolean considerGuards) {
 199         return originalValue.stamp().isCompatible(replacementValue.stamp()) &&
 200                         (!considerGuards || (getGuard(originalValue) == null || getGuard(originalValue) == getGuard(replacementValue)));
 201     }
 202 
 203     private static GuardingNode getGuard(ValueNode node) {
 204         if (node instanceof GuardedNode) {


< prev index next >