206 @Override 207 public boolean isCfgKill() { 208 return true; 209 } 210 }); 211 } 212 213 /** 214 * Replaces the given node at its usages without deleting it. If the current node is a fixed 215 * node it will be disconnected from the control flow, so that it will be deleted by a 216 * subsequent {@link DeadCodeEliminationPhase} 217 * 218 * @param node The node to be replaced. 219 * @param replacement The node that should replace the original value. If the replacement is a 220 * non-connected {@link FixedWithNextNode} it will be added to the control flow. 221 * @param insertBefore 222 * 223 */ 224 public void replaceAtUsages(ValueNode node, ValueNode replacement, FixedNode insertBefore) { 225 assert node != null && replacement != null : node + " " + replacement; 226 assert node.stamp(NodeView.DEFAULT).isCompatible(replacement.stamp(NodeView.DEFAULT)) : "Replacement node stamp not compatible " + node.stamp(NodeView.DEFAULT) + " vs " + 227 replacement.stamp(NodeView.DEFAULT); 228 add("replace at usages", (graph, obsoleteNodes) -> { 229 assert node.isAlive(); 230 ValueNode replacementNode = graph.addOrUniqueWithInputs(replacement); 231 assert replacementNode.isAlive(); 232 assert insertBefore != null; 233 if (replacementNode instanceof FixedWithNextNode && ((FixedWithNextNode) replacementNode).next() == null) { 234 graph.addBeforeFixed(insertBefore, (FixedWithNextNode) replacementNode); 235 } 236 /* 237 * Keep the (better) stamp information when replacing a node with another one if the 238 * replacement has a less precise stamp than the original node. This can happen for 239 * example in the context of read nodes and unguarded pi nodes where the pi will be used 240 * to improve the stamp information of the read. Such a read might later be replaced 241 * with a read with a less precise stamp. 242 */ 243 if (!node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) { 244 replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT))); 245 } 246 node.replaceAtUsages(replacementNode); 247 if (node instanceof FixedWithNextNode) { 248 GraphUtil.unlinkFixedNode((FixedWithNextNode) node); 249 } 250 obsoleteNodes.add(node); 251 }); 252 } 253 254 /** 255 * Replaces the first occurrence of oldInput in node with newInput. 256 * 257 * @param node The node whose input should be changed. 258 * @param oldInput The value to look for. 259 * @param newInput The value to replace with. 260 */ 261 public void replaceFirstInput(Node node, Node oldInput, Node newInput) { 262 assert node.isAlive() && oldInput.isAlive() && !newInput.isDeleted(); 263 add("replace first input", new Effect() { | 206 @Override 207 public boolean isCfgKill() { 208 return true; 209 } 210 }); 211 } 212 213 /** 214 * Replaces the given node at its usages without deleting it. If the current node is a fixed 215 * node it will be disconnected from the control flow, so that it will be deleted by a 216 * subsequent {@link DeadCodeEliminationPhase} 217 * 218 * @param node The node to be replaced. 219 * @param replacement The node that should replace the original value. If the replacement is a 220 * non-connected {@link FixedWithNextNode} it will be added to the control flow. 221 * @param insertBefore 222 * 223 */ 224 public void replaceAtUsages(ValueNode node, ValueNode replacement, FixedNode insertBefore) { 225 assert node != null && replacement != null : node + " " + replacement; 226 assert !node.hasUsages() || node.stamp(NodeView.DEFAULT).isCompatible(replacement.stamp(NodeView.DEFAULT)) : "Replacement node stamp not compatible " + node.stamp(NodeView.DEFAULT) + " vs " + 227 replacement.stamp(NodeView.DEFAULT); 228 add("replace at usages", (graph, obsoleteNodes) -> { 229 assert node.isAlive(); 230 ValueNode replacementNode = graph.addOrUniqueWithInputs(replacement); 231 assert replacementNode.isAlive(); 232 assert insertBefore != null; 233 if (replacementNode instanceof FixedWithNextNode && ((FixedWithNextNode) replacementNode).next() == null) { 234 graph.addBeforeFixed(insertBefore, (FixedWithNextNode) replacementNode); 235 } 236 /* 237 * Keep the (better) stamp information when replacing a node with another one if the 238 * replacement has a less precise stamp than the original node. This can happen for 239 * example in the context of read nodes and unguarded pi nodes where the pi will be used 240 * to improve the stamp information of the read. Such a read might later be replaced 241 * with a read with a less precise stamp. 242 */ 243 if (node.hasUsages() && !node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) { 244 replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT))); 245 } 246 node.replaceAtUsages(replacementNode); 247 if (node instanceof FixedWithNextNode) { 248 GraphUtil.unlinkFixedNode((FixedWithNextNode) node); 249 } 250 obsoleteNodes.add(node); 251 }); 252 } 253 254 /** 255 * Replaces the first occurrence of oldInput in node with newInput. 256 * 257 * @param node The node whose input should be changed. 258 * @param oldInput The value to look for. 259 * @param newInput The value to replace with. 260 */ 261 public void replaceFirstInput(Node node, Node oldInput, Node newInput) { 262 assert node.isAlive() && oldInput.isAlive() && !newInput.isDeleted(); 263 add("replace first input", new Effect() { |