use of org.graalvm.compiler.nodes.AbstractBeginNode in project graal by oracle.
the class IntegerSwitchNode method tryRemoveUnreachableKeys.
/**
* Remove unreachable keys from the switch based on the stamp of the value, i.e., based on the
* known range of the switch value.
*/
public boolean tryRemoveUnreachableKeys(SimplifierTool tool, Stamp valueStamp) {
if (!(valueStamp instanceof IntegerStamp)) {
return false;
}
IntegerStamp integerStamp = (IntegerStamp) valueStamp;
if (integerStamp.isUnrestricted()) {
return false;
}
List<KeyData> newKeyDatas = new ArrayList<>(keys.length);
ArrayList<AbstractBeginNode> newSuccessors = new ArrayList<>(blockSuccessorCount());
for (int i = 0; i < keys.length; i++) {
if (integerStamp.contains(keys[i]) && keySuccessor(i) != defaultSuccessor()) {
newKeyDatas.add(new KeyData(keys[i], keyProbabilities[i], addNewSuccessor(keySuccessor(i), newSuccessors)));
}
}
if (newKeyDatas.size() == keys.length) {
/* All keys are reachable. */
return false;
} else if (newKeyDatas.size() == 0) {
if (tool != null) {
tool.addToWorkList(defaultSuccessor());
}
graph().removeSplitPropagate(this, defaultSuccessor());
return true;
} else {
int newDefaultSuccessor = addNewSuccessor(defaultSuccessor(), newSuccessors);
double newDefaultProbability = keyProbabilities[keyProbabilities.length - 1];
doReplace(value(), newKeyDatas, newSuccessors, newDefaultSuccessor, newDefaultProbability);
return true;
}
}
use of org.graalvm.compiler.nodes.AbstractBeginNode in project graal by oracle.
the class IntegerSwitchNode method doReplace.
private void doReplace(ValueNode newValue, List<KeyData> newKeyDatas, ArrayList<AbstractBeginNode> newSuccessors, int newDefaultSuccessor, double newDefaultProbability) {
/* Sort the new keys (invariant of the IntegerSwitchNode). */
newKeyDatas.sort(Comparator.comparingInt(k -> k.key));
/* Create the final data arrays. */
int newKeyCount = newKeyDatas.size();
int[] newKeys = new int[newKeyCount];
double[] newKeyProbabilities = new double[newKeyCount + 1];
int[] newKeySuccessors = new int[newKeyCount + 1];
for (int i = 0; i < newKeyCount; i++) {
KeyData keyData = newKeyDatas.get(i);
newKeys[i] = keyData.key;
newKeyProbabilities[i] = keyData.keyProbability;
newKeySuccessors[i] = keyData.keySuccessor;
}
newKeySuccessors[newKeyCount] = newDefaultSuccessor;
newKeyProbabilities[newKeyCount] = newDefaultProbability;
/* Normalize new probabilities so that they sum up to 1. */
double totalProbability = 0;
for (double probability : newKeyProbabilities) {
totalProbability += probability;
}
if (totalProbability > 0) {
for (int i = 0; i < newKeyProbabilities.length; i++) {
newKeyProbabilities[i] /= totalProbability;
}
} else {
for (int i = 0; i < newKeyProbabilities.length; i++) {
newKeyProbabilities[i] = 1.0 / newKeyProbabilities.length;
}
}
/*
* Collect dead successors. Successors have to be cleaned before adding the new node to the
* graph.
*/
List<AbstractBeginNode> deadSuccessors = successors.filter(s -> !newSuccessors.contains(s)).snapshot();
successors.clear();
/*
* Create the new switch node. This is done before removing dead successors as `killCFG`
* could edit some of the inputs (e.g., if `newValue` is a loop-phi of the loop that dies
* while removing successors).
*/
AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
SwitchNode newSwitch = graph().add(new IntegerSwitchNode(newValue, successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
/* Remove dead successors. */
for (AbstractBeginNode successor : deadSuccessors) {
GraphUtil.killCFG(successor);
}
/* Replace ourselves with the new switch */
((FixedWithNextNode) predecessor()).setNext(newSwitch);
GraphUtil.killWithUnusedFloatingInputs(this);
}
use of org.graalvm.compiler.nodes.AbstractBeginNode in project graal by oracle.
the class ExceptionObjectNode method lower.
@Override
public void lower(LoweringTool tool) {
if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
/*
* Now the lowering to BeginNode+LoadExceptionNode can be performed, since no more
* deopts can float in between the begin node and the load exception node.
*/
LocationIdentity locationsKilledByInvoke = ((InvokeWithExceptionNode) predecessor()).getLocationIdentity();
AbstractBeginNode entry = graph().add(KillingBeginNode.create(locationsKilledByInvoke));
LoadExceptionObjectNode loadException = graph().add(new LoadExceptionObjectNode(stamp(NodeView.DEFAULT)));
loadException.setStateAfter(stateAfter());
replaceAtUsages(InputType.Value, loadException);
graph().replaceFixedWithFixed(this, entry);
entry.graph().addAfterFixed(entry, loadException);
loadException.lower(tool);
}
}
use of org.graalvm.compiler.nodes.AbstractBeginNode in project graal by oracle.
the class ConvertDeoptimizeToGuardPhase method processFixedGuardAndPhis.
private void processFixedGuardAndPhis(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi) {
AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard);
if (pred instanceof AbstractMergeNode) {
AbstractMergeNode merge = (AbstractMergeNode) pred;
if (xPhi != null && xPhi.merge() != merge) {
return;
}
if (yPhi != null && yPhi.merge() != merge) {
return;
}
processFixedGuardAndMerge(fixedGuard, context, compare, x, xPhi, y, yPhi, merge);
}
}
use of org.graalvm.compiler.nodes.AbstractBeginNode in project graal by oracle.
the class PropagateDeoptimizeProbabilityPhase method run.
@Override
@SuppressWarnings("try")
protected void run(final StructuredGraph graph, PhaseContext context) {
assert !graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
if (graph.hasNode(AbstractDeoptimizeNode.TYPE)) {
NodeStack stack = new NodeStack();
EconomicMap<ControlSplitNode, EconomicSet<AbstractBeginNode>> reachableSplits = EconomicMap.create();
// Mark all control flow nodes that are post-dominated by a deoptimization.
for (AbstractDeoptimizeNode d : graph.getNodes(AbstractDeoptimizeNode.TYPE)) {
stack.push(AbstractBeginNode.prevBegin(d));
while (!stack.isEmpty()) {
AbstractBeginNode beginNode = (AbstractBeginNode) stack.pop();
FixedNode fixedNode = (FixedNode) beginNode.predecessor();
if (fixedNode == null) {
// Can happen for start node.
} else if (fixedNode instanceof AbstractMergeNode) {
AbstractMergeNode mergeNode = (AbstractMergeNode) fixedNode;
for (AbstractEndNode end : mergeNode.forwardEnds()) {
AbstractBeginNode newBeginNode = AbstractBeginNode.prevBegin(end);
stack.push(newBeginNode);
}
} else if (fixedNode instanceof ControlSplitNode) {
ControlSplitNode controlSplitNode = (ControlSplitNode) fixedNode;
EconomicSet<AbstractBeginNode> reachableSuccessors = reachableSplits.get(controlSplitNode);
if (reachableSuccessors == null) {
reachableSuccessors = EconomicSet.create();
reachableSplits.put(controlSplitNode, reachableSuccessors);
}
if (controlSplitNode.getSuccessorCount() == reachableSuccessors.size() - 1) {
// All successors of this split lead to deopt, propagate reachability
// further upwards.
reachableSplits.removeKey(controlSplitNode);
stack.push(AbstractBeginNode.prevBegin((FixedNode) controlSplitNode.predecessor()));
} else {
reachableSuccessors.add(beginNode);
}
} else {
stack.push(AbstractBeginNode.prevBegin(fixedNode));
}
}
}
// Make sure the probability on the path towards the deoptimization is 0.0.
MapCursor<ControlSplitNode, EconomicSet<AbstractBeginNode>> entries = reachableSplits.getEntries();
while (entries.advance()) {
ControlSplitNode controlSplitNode = entries.getKey();
EconomicSet<AbstractBeginNode> value = entries.getValue();
for (AbstractBeginNode begin : value) {
double probability = controlSplitNode.probability(begin);
if (probability != 0.0) {
controlSplitNode.setProbability(begin, 0.0);
}
}
}
}
}
Aggregations