001/* 002 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.virtual.phases.ea; 024 025import java.util.*; 026 027import com.oracle.graal.graph.*; 028import com.oracle.graal.nodes.*; 029import com.oracle.graal.nodes.debug.*; 030import com.oracle.graal.nodes.util.*; 031import com.oracle.graal.nodes.virtual.*; 032import com.oracle.graal.phases.common.*; 033 034public class GraphEffectList extends EffectList { 035 036 public void addCounterBefore(String group, String name, int increment, boolean addContext, FixedNode position) { 037 add("add counter", graph -> DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position)); 038 } 039 040 public void addCounterAfter(String group, String name, int increment, boolean addContext, FixedWithNextNode position) { 041 FixedNode nextPosition = position.next(); 042 add("add counter after", graph -> DynamicCounterNode.addCounterBefore(group, name, increment, addContext, nextPosition)); 043 } 044 045 public void addWeakCounterCounterBefore(String group, String name, int increment, boolean addContext, ValueNode checkedValue, FixedNode position) { 046 add("add weak counter", graph -> WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position)); 047 } 048 049 /** 050 * Adds the given fixed node to the graph's control flow, before position (so that the original 051 * predecessor of position will then be node's predecessor). 052 * 053 * @param node The fixed node to be added to the graph. 054 * @param position The fixed node before which the node should be added. 055 */ 056 public void addFixedNodeBefore(FixedWithNextNode node, FixedNode position) { 057 add("add fixed node", graph -> { 058 assert !node.isAlive() && !node.isDeleted() && position.isAlive(); 059 graph.addBeforeFixed(position, graph.add(node)); 060 }); 061 } 062 063 public void ensureAdded(ValueNode node, FixedNode position) { 064 add("ensure added", graph -> { 065 assert position.isAlive(); 066 if (!node.isAlive()) { 067 graph.addWithoutUniqueWithInputs(node); 068 if (node instanceof FixedWithNextNode) { 069 graph.addBeforeFixed(position, (FixedWithNextNode) node); 070 } 071 } 072 }); 073 } 074 075 /** 076 * Add the given floating node to the graph. 077 * 078 * @param node The floating node to be added. 079 */ 080 public void addFloatingNode(ValueNode node, @SuppressWarnings("unused") String cause) { 081 add("add floating node", graph -> graph.addWithoutUnique(node)); 082 } 083 084 /** 085 * Sets the phi node's input at the given index to the given value, adding new phi inputs as 086 * needed. 087 * 088 * @param node The phi node whose input should be changed. 089 * @param index The index of the phi input to be changed. 090 * @param value The new value for the phi input. 091 */ 092 public void initializePhiInput(PhiNode node, int index, ValueNode value) { 093 add("set phi input", (graph, obsoleteNodes) -> { 094 assert node.isAlive() && value.isAlive() && index >= 0; 095 node.initializeValueAt(index, value); 096 }); 097 } 098 099 /** 100 * Adds a virtual object's state to the given frame state. If the given reusedVirtualObjects set 101 * contains the virtual object then old states for this object will be removed. 102 * 103 * @param node The frame state to which the state should be added. 104 * @param state The virtual object state to add. 105 */ 106 public void addVirtualMapping(FrameState node, EscapeObjectState state) { 107 add("add virtual mapping", new Effect() { 108 @Override 109 public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { 110 if (node.isAlive()) { 111 assert !state.isDeleted(); 112 FrameState stateAfter = node; 113 for (int i = 0; i < stateAfter.virtualObjectMappingCount(); i++) { 114 if (stateAfter.virtualObjectMappingAt(i).object() == state.object()) { 115 stateAfter.virtualObjectMappings().remove(i); 116 } 117 } 118 stateAfter.addVirtualObjectMapping(state.isAlive() ? state : graph.unique(state)); 119 } 120 } 121 122 @Override 123 public boolean isVisible() { 124 return false; 125 } 126 }); 127 } 128 129 /** 130 * Removes the given fixed node from the control flow and deletes it. 131 * 132 * @param node The fixed node that should be deleted. 133 */ 134 public void deleteNode(Node node) { 135 add("delete fixed node", (graph, obsoleteNodes) -> { 136 if (node instanceof FixedWithNextNode) { 137 GraphUtil.unlinkFixedNode((FixedWithNextNode) node); 138 } 139 obsoleteNodes.add(node); 140 }); 141 } 142 143 public void killIfBranch(IfNode ifNode, boolean constantCondition) { 144 add("kill if branch", new Effect() { 145 public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { 146 graph.removeSplitPropagate(ifNode, ifNode.getSuccessor(constantCondition)); 147 } 148 149 public boolean isCfgKill() { 150 return true; 151 } 152 }); 153 } 154 155 public void replaceWithSink(FixedWithNextNode node, ControlSinkNode sink) { 156 add("kill if branch", new Effect() { 157 public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { 158 node.replaceAtPredecessor(sink); 159 GraphUtil.killCFG(node); 160 } 161 162 public boolean isCfgKill() { 163 return true; 164 } 165 }); 166 } 167 168 /** 169 * Replaces the given node at its usages without deleting it. If the current node is a fixed 170 * node it will be disconnected from the control flow, so that it will be deleted by a 171 * subsequent {@link DeadCodeEliminationPhase} 172 * 173 * @param node The node to be replaced. 174 * @param replacement The node that should replace the original value. If the replacement is a 175 * non-connected {@link FixedWithNextNode} it will be added to the control flow. 176 * 177 */ 178 public void replaceAtUsages(ValueNode node, ValueNode replacement) { 179 assert node != null && replacement != null : node + " " + replacement; 180 add("replace at usages", (graph, obsoleteNodes) -> { 181 assert node.isAlive() && replacement.isAlive() : node + " " + replacement; 182 if (replacement instanceof FixedWithNextNode && ((FixedWithNextNode) replacement).next() == null) { 183 assert node instanceof FixedNode; 184 graph.addBeforeFixed((FixedNode) node, (FixedWithNextNode) replacement); 185 } 186 node.replaceAtUsages(replacement); 187 if (node instanceof FixedWithNextNode) { 188 GraphUtil.unlinkFixedNode((FixedWithNextNode) node); 189 } 190 obsoleteNodes.add(node); 191 }); 192 } 193 194 /** 195 * Replaces the first occurrence of oldInput in node with newInput. 196 * 197 * @param node The node whose input should be changed. 198 * @param oldInput The value to look for. 199 * @param newInput The value to replace with. 200 */ 201 public void replaceFirstInput(Node node, Node oldInput, Node newInput) { 202 assert node.isAlive() && oldInput.isAlive() && !newInput.isDeleted(); 203 add("replace first input", new Effect() { 204 @Override 205 public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { 206 if (node.isAlive()) { 207 assert oldInput.isAlive() && newInput.isAlive(); 208 node.replaceFirstInput(oldInput, newInput); 209 } 210 } 211 212 @Override 213 public boolean isVisible() { 214 return !(node instanceof FrameState); 215 } 216 }); 217 } 218}