use of org.graalvm.compiler.lir.LabelRef in project graal by oracle.
the class AMD64NodeMatchRules method emitIntegerTestBranchMemory.
private ComplexMatchResult emitIntegerTestBranchMemory(IfNode x, ValueNode value, LIRLowerableAccess access) {
LabelRef trueLabel = getLIRBlock(x.trueSuccessor());
LabelRef falseLabel = getLIRBlock(x.falseSuccessor());
double trueLabelProbability = x.probability(x.trueSuccessor());
AMD64Kind kind = getMemoryKind(access);
OperandSize size = kind == AMD64Kind.QWORD ? QWORD : DWORD;
if (value.isConstant()) {
JavaConstant constant = value.asJavaConstant();
if (constant != null && kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) {
// Only imm32 as long
return null;
}
return builder -> {
AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
gen.append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.TEST, size, address, (int) constant.asLong(), getState(access)));
gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
return null;
};
} else {
return builder -> {
AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
gen.append(new AMD64BinaryConsumer.MemoryRMOp(AMD64RMOp.TEST, size, gen.asAllocatable(operand(value)), address, getState(access)));
gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
return null;
};
}
}
use of org.graalvm.compiler.lir.LabelRef in project graal by oracle.
the class AMD64NodeMatchRules method emitCompareBranchMemory.
protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, LIRLowerableAccess access) {
Condition cond = compare.condition().asCondition();
AMD64Kind kind = getMemoryKind(access);
// For assertion checking
boolean matchedAsConstant = false;
if (value.isConstant()) {
JavaConstant constant = value.asJavaConstant();
if (constant != null) {
if (kind == AMD64Kind.QWORD && !constant.getJavaKind().isObject() && !NumUtil.isInt(constant.asLong())) {
// Only imm32 as long
return null;
}
// A QWORD that can be encoded as int can be embedded as a constant
matchedAsConstant = kind == AMD64Kind.QWORD && !constant.getJavaKind().isObject() && NumUtil.isInt(constant.asLong());
}
if (kind == AMD64Kind.DWORD) {
// Any DWORD value should be embeddable as a constant
matchedAsConstant = true;
}
if (kind.isXMM()) {
ifNode.getDebug().log("Skipping constant compares for float kinds");
return null;
}
}
boolean matchedAsConstantFinal = matchedAsConstant;
/*
* emitCompareBranchMemory expects the memory on the right, so mirror the condition if
* that's not true. It might be mirrored again the actual compare is emitted but that's ok.
*/
Condition finalCondition = GraphUtil.unproxify(compare.getX()) == access ? cond.mirror() : cond;
return new ComplexMatchResult() {
@Override
public Value evaluate(NodeLIRBuilder builder) {
LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor());
LabelRef falseLabel = getLIRBlock(ifNode.falseSuccessor());
boolean unorderedIsTrue = compare.unorderedIsTrue();
double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor());
Value other = operand(value);
/*
* Check that patterns which were matched as a constant actually end up seeing a
* constant in the LIR.
*/
assert !matchedAsConstantFinal || !LIRValueUtil.isVariable(other) : "expected constant value " + value;
AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
getLIRGeneratorTool().emitCompareBranchMemory(kind, other, address, getState(access), finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability);
return null;
}
};
}
use of org.graalvm.compiler.lir.LabelRef in project graal by oracle.
the class NodeLIRBuilder method emitConstantBranch.
public void emitConstantBranch(boolean value, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock) {
LabelRef block = value ? trueSuccessorBlock : falseSuccessorBlock;
gen.emitJump(block);
}
use of org.graalvm.compiler.lir.LabelRef in project graal by oracle.
the class LIRGenerator method emitStrategySwitch.
@Override
public void emitStrategySwitch(JavaConstant[] keyConstants, double[] keyProbabilities, LabelRef[] keyTargets, LabelRef defaultTarget, Variable value) {
int keyCount = keyConstants.length;
SwitchStrategy strategy = SwitchStrategy.getBestStrategy(keyProbabilities, keyConstants, keyTargets);
long valueRange = keyConstants[keyCount - 1].asLong() - keyConstants[0].asLong() + 1;
double tableSwitchDensity = keyCount / (double) valueRange;
/*
* This heuristic tries to find a compromise between the effort for the best switch strategy
* and the density of a tableswitch. If the effort for the strategy is at least 4, then a
* tableswitch is preferred if better than a certain value that starts at 0.5 and lowers
* gradually with additional effort.
*/
if (strategy.getAverageEffort() < 4 || tableSwitchDensity < (1 / Math.sqrt(strategy.getAverageEffort()))) {
emitStrategySwitch(strategy, value, keyTargets, defaultTarget);
} else {
int minValue = keyConstants[0].asInt();
assert valueRange < Integer.MAX_VALUE;
LabelRef[] targets = new LabelRef[(int) valueRange];
for (int i = 0; i < valueRange; i++) {
targets[i] = defaultTarget;
}
for (int i = 0; i < keyCount; i++) {
targets[keyConstants[i].asInt() - minValue] = keyTargets[i];
}
emitTableSwitch(minValue, defaultTarget, targets, value);
}
}
use of org.graalvm.compiler.lir.LabelRef in project graal by oracle.
the class SPARCNodeMatchRules method ifCompareLogicCas.
@MatchRule("(If (ObjectEquals=compare value LogicCompareAndSwap=cas))")
@MatchRule("(If (PointerEquals=compare value LogicCompareAndSwap=cas))")
@MatchRule("(If (FloatEquals=compare value LogicCompareAndSwap=cas))")
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
JavaConstant constant = value.asJavaConstant();
assert compare.condition() == CanonicalCondition.EQ;
if (constant != null && cas.usages().count() == 1) {
long constantValue = constant.asLong();
boolean successIsTrue;
if (constantValue == 0) {
successIsTrue = false;
} else if (constantValue == 1) {
successIsTrue = true;
} else {
return null;
}
return builder -> {
LIRKind kind = getLirKind(cas);
LabelRef trueLabel = getLIRBlock(root.trueSuccessor());
LabelRef falseLabel = getLIRBlock(root.falseSuccessor());
double trueLabelProbability = root.probability(root.trueSuccessor());
Value expectedValue = operand(cas.getExpectedValue());
Value newValue = operand(cas.getNewValue());
SPARCAddressValue address = (SPARCAddressValue) operand(cas.getAddress());
Condition condition = successIsTrue ? Condition.EQ : Condition.NE;
Value result = getLIRGeneratorTool().emitValueCompareAndSwap(address, expectedValue, newValue);
getLIRGeneratorTool().emitCompareBranch(kind.getPlatformKind(), result, expectedValue, condition, false, trueLabel, falseLabel, trueLabelProbability);
return null;
};
}
return null;
}
Aggregations