use of org.graalvm.compiler.nodes.extended.IntegerSwitchNode in project graal by oracle.
the class SimplifyingGraphDecoder method canonicalizeFixedNode.
/**
* Canonicalizes the provided node, which was originally a {@link FixedNode} but can already be
* canonicalized (and therefore be a non-fixed node).
*
* @param methodScope The current method.
* @param node The node to be canonicalized.
*/
protected Node canonicalizeFixedNode(MethodScope methodScope, Node node) {
if (node instanceof LoadFieldNode) {
LoadFieldNode loadFieldNode = (LoadFieldNode) node;
return loadFieldNode.canonical(canonicalizerTool);
} else if (node instanceof FixedGuardNode) {
FixedGuardNode guard = (FixedGuardNode) node;
if (guard.getCondition() instanceof LogicConstantNode) {
LogicConstantNode condition = (LogicConstantNode) guard.getCondition();
if (condition.getValue() == guard.isNegated()) {
DeoptimizeNode deopt = new DeoptimizeNode(guard.getAction(), guard.getReason(), guard.getSpeculation());
if (guard.stateBefore() != null) {
deopt.setStateBefore(guard.stateBefore());
}
return deopt;
} else {
return null;
}
}
return node;
} else if (node instanceof IfNode) {
IfNode ifNode = (IfNode) node;
if (ifNode.condition() instanceof LogicNegationNode) {
ifNode.eliminateNegation();
}
if (ifNode.condition() instanceof LogicConstantNode) {
boolean condition = ((LogicConstantNode) ifNode.condition()).getValue();
AbstractBeginNode survivingSuccessor = ifNode.getSuccessor(condition);
AbstractBeginNode deadSuccessor = ifNode.getSuccessor(!condition);
graph.removeSplit(ifNode, survivingSuccessor);
assert deadSuccessor.next() == null : "must not be parsed yet";
deadSuccessor.safeDelete();
}
return node;
} else if (node instanceof LoadIndexedNode) {
LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
return loadIndexedNode.canonical(canonicalizerTool);
} else if (node instanceof ArrayLengthNode) {
ArrayLengthNode arrayLengthNode = (ArrayLengthNode) node;
return arrayLengthNode.canonical(canonicalizerTool);
} else if (node instanceof IntegerSwitchNode && ((IntegerSwitchNode) node).value().isConstant()) {
IntegerSwitchNode switchNode = (IntegerSwitchNode) node;
int value = switchNode.value().asJavaConstant().asInt();
AbstractBeginNode survivingSuccessor = switchNode.successorAtKey(value);
List<Node> allSuccessors = switchNode.successors().snapshot();
graph.removeSplit(switchNode, survivingSuccessor);
for (Node successor : allSuccessors) {
if (successor != survivingSuccessor) {
assert ((AbstractBeginNode) successor).next() == null : "must not be parsed yet";
successor.safeDelete();
}
}
return node;
} else if (node instanceof Canonicalizable) {
return ((Canonicalizable) node).canonical(canonicalizerTool);
} else {
return node;
}
}
use of org.graalvm.compiler.nodes.extended.IntegerSwitchNode in project graal by oracle.
the class BytecodeParser method genIntegerSwitch.
protected void genIntegerSwitch(ValueNode value, ArrayList<BciBlock> actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
if (value.isConstant()) {
JavaConstant constant = (JavaConstant) value.asConstant();
int constantValue = constant.asInt();
for (int i = 0; i < keys.length; ++i) {
if (keys[i] == constantValue) {
appendGoto(actualSuccessors.get(keySuccessors[i]));
return;
}
}
appendGoto(actualSuccessors.get(keySuccessors[keys.length]));
} else {
this.controlFlowSplit = true;
double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities);
IntegerSwitchNode switchNode = append(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors));
for (int i = 0; i < actualSuccessors.size(); i++) {
switchNode.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState));
}
}
}
use of org.graalvm.compiler.nodes.extended.IntegerSwitchNode in project graal by oracle.
the class NodeLIRBuilder method emitSwitch.
/**
* This method tries to create a switch implementation that is optimal for the given switch. It
* will either generate a sequential if/then/else cascade, a set of range tests or a table
* switch.
*
* If the given switch does not contain int keys, it will always create a sequential
* implementation.
*/
@Override
public void emitSwitch(SwitchNode x) {
assert x.defaultSuccessor() != null;
LabelRef defaultTarget = getLIRBlock(x.defaultSuccessor());
int keyCount = x.keyCount();
if (keyCount == 0) {
gen.emitJump(defaultTarget);
} else {
Variable value = gen.load(operand(x.value()));
if (keyCount == 1) {
assert defaultTarget != null;
double probability = x.probability(x.keySuccessor(0));
LIRKind kind = gen.getLIRKind(x.value().stamp(NodeView.DEFAULT));
Value key = gen.emitConstant(kind, x.keyAt(0));
gen.emitCompareBranch(kind.getPlatformKind(), gen.load(operand(x.value())), key, Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
} else if (x instanceof IntegerSwitchNode && x.isSorted()) {
IntegerSwitchNode intSwitch = (IntegerSwitchNode) x;
LabelRef[] keyTargets = new LabelRef[keyCount];
JavaConstant[] keyConstants = new JavaConstant[keyCount];
double[] keyProbabilities = new double[keyCount];
JavaKind keyKind = intSwitch.keyAt(0).getJavaKind();
for (int i = 0; i < keyCount; i++) {
keyTargets[i] = getLIRBlock(intSwitch.keySuccessor(i));
keyConstants[i] = intSwitch.keyAt(i);
keyProbabilities[i] = intSwitch.keyProbability(i);
assert keyConstants[i].getJavaKind() == keyKind;
}
gen.emitStrategySwitch(keyConstants, keyProbabilities, keyTargets, defaultTarget, value);
} else {
// keyKind != JavaKind.Int || !x.isSorted()
LabelRef[] keyTargets = new LabelRef[keyCount];
Constant[] keyConstants = new Constant[keyCount];
double[] keyProbabilities = new double[keyCount];
for (int i = 0; i < keyCount; i++) {
keyTargets[i] = getLIRBlock(x.keySuccessor(i));
keyConstants[i] = x.keyAt(i);
keyProbabilities[i] = x.keyProbability(i);
}
// hopefully only a few entries
gen.emitStrategySwitch(new SwitchStrategy.SequentialStrategy(keyProbabilities, keyConstants), value, keyTargets, defaultTarget);
}
}
}
Aggregations