use of jdk.vm.ci.meta.Constant in project graal by oracle.
the class AddNode method canonical.
private static ValueNode canonical(AddNode addNode, BinaryOp<Add> op, ValueNode forX, ValueNode forY, NodeView view) {
AddNode self = addNode;
boolean associative = op.isAssociative();
if (associative) {
if (forX instanceof SubNode) {
SubNode sub = (SubNode) forX;
if (sub.getY() == forY) {
// (a - b) + b
return sub.getX();
}
}
if (forY instanceof SubNode) {
SubNode sub = (SubNode) forY;
if (sub.getY() == forX) {
// b + (a - b)
return sub.getX();
}
}
}
if (forY.isConstant()) {
Constant c = forY.asConstant();
if (op.isNeutral(c)) {
return forX;
}
if (associative && self != null) {
// canonicalize expressions like "(a + 1) + 2"
ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view);
if (reassociated != self) {
return reassociated;
}
}
}
if (forX instanceof NegateNode) {
return BinaryArithmeticNode.sub(forY, ((NegateNode) forX).getValue(), view);
} else if (forY instanceof NegateNode) {
return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue(), view);
}
if (self == null) {
self = (AddNode) new AddNode(forX, forY).maybeCommuteInputs();
}
return self;
}
use of jdk.vm.ci.meta.Constant in project graal by oracle.
the class AndNode method canonical.
private static ValueNode canonical(AndNode self, BinaryOp<And> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
return forX;
}
if (forX.isConstant() && !forY.isConstant()) {
return new AndNode(forY, forX);
}
if (forY.isConstant()) {
Constant c = forY.asConstant();
if (op.isNeutral(c)) {
return forX;
}
if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
long rawY = ((PrimitiveConstant) c).asLong();
long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp));
if ((rawY & mask) == 0) {
return ConstantNode.forIntegerStamp(stamp, 0);
}
if (forX instanceof SignExtendNode) {
SignExtendNode ext = (SignExtendNode) forX;
if (rawY == ((1L << ext.getInputBits()) - 1)) {
return new ZeroExtendNode(ext.getValue(), ext.getResultBits());
}
}
IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
if (((xStamp.upMask() | xStamp.downMask()) & ~rawY) == 0) {
// No bits are set which are outside the mask, so the mask will have no effect.
return forX;
}
}
return reassociate(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
}
if (forX instanceof NotNode && forY instanceof NotNode) {
return new NotNode(OrNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
}
return self != null ? self : new AndNode(forX, forY).maybeCommuteInputs();
}
use of jdk.vm.ci.meta.Constant in project graal by oracle.
the class XorNode method canonical.
private static ValueNode canonical(XorNode self, BinaryOp<Xor> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
return ConstantNode.forPrimitive(stamp, op.getZero(forX.stamp(view)));
}
if (forX.isConstant() && !forY.isConstant()) {
return new XorNode(forY, forX);
}
if (forY.isConstant()) {
Constant c = forY.asConstant();
if (op.isNeutral(c)) {
return forX;
}
if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
long rawY = ((PrimitiveConstant) c).asLong();
long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp));
if ((rawY & mask) == mask) {
return new NotNode(forX);
}
}
return reassociate(self != null ? self : (XorNode) new XorNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
}
return self != null ? self : new XorNode(forX, forY).maybeCommuteInputs();
}
use of jdk.vm.ci.meta.Constant in project graal by oracle.
the class SPARCLIRGenerator method emitStrategySwitch.
@Override
public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) {
Variable scratchValue = newVariable(key.getValueKind());
AllocatableValue base = AllocatableValue.ILLEGAL;
for (Constant c : strategy.getKeyConstants()) {
if (!getMoveFactory().canInlineConstant(c)) {
base = constantTableBaseProvider.getConstantTableBase();
break;
}
}
append(createStrategySwitchOp(base, strategy, keyTargets, defaultTarget, key, scratchValue));
}
use of jdk.vm.ci.meta.Constant in project graal by oracle.
the class IfNode method removeIntermediateMaterialization.
/**
* Tries to connect code that initializes a variable directly with the successors of an if
* construct that switches on the variable. For example, the pseudo code below:
*
* <pre>
* contains(list, e, yes, no) {
* if (list == null || e == null) {
* condition = false;
* } else {
* condition = false;
* for (i in list) {
* if (i.equals(e)) {
* condition = true;
* break;
* }
* }
* }
* if (condition) {
* return yes;
* } else {
* return no;
* }
* }
* </pre>
*
* will be transformed into:
*
* <pre>
* contains(list, e, yes, no) {
* if (list == null || e == null) {
* return no;
* } else {
* condition = false;
* for (i in list) {
* if (i.equals(e)) {
* return yes;
* }
* }
* return no;
* }
* }
* </pre>
*
* @return true if a transformation was made, false otherwise
*/
private boolean removeIntermediateMaterialization(SimplifierTool tool) {
if (!(predecessor() instanceof AbstractMergeNode) || predecessor() instanceof LoopBeginNode) {
return false;
}
AbstractMergeNode merge = (AbstractMergeNode) predecessor();
if (!(condition() instanceof CompareNode)) {
return false;
}
CompareNode compare = (CompareNode) condition();
if (compare.getUsageCount() != 1) {
return false;
}
// Only consider merges with a single usage that is both a phi and an operand of the
// comparison
NodeIterable<Node> mergeUsages = merge.usages();
if (mergeUsages.count() != 1) {
return false;
}
Node singleUsage = mergeUsages.first();
if (!(singleUsage instanceof ValuePhiNode) || (singleUsage != compare.getX() && singleUsage != compare.getY())) {
return false;
}
// Ensure phi is used by at most the comparison and the merge's frame state (if any)
ValuePhiNode phi = (ValuePhiNode) singleUsage;
NodeIterable<Node> phiUsages = phi.usages();
if (phiUsages.count() > 2) {
return false;
}
for (Node usage : phiUsages) {
if (usage != compare && usage != merge.stateAfter()) {
return false;
}
}
List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
assert phi.valueCount() == merge.forwardEndCount();
Constant[] xs = constantValues(compare.getX(), merge, false);
Constant[] ys = constantValues(compare.getY(), merge, false);
if (xs == null || ys == null) {
return false;
}
// Sanity check that both ends are not followed by a merge without frame state.
if (!checkFrameState(trueSuccessor()) && !checkFrameState(falseSuccessor())) {
return false;
}
List<EndNode> falseEnds = new ArrayList<>(mergePredecessors.size());
List<EndNode> trueEnds = new ArrayList<>(mergePredecessors.size());
EconomicMap<AbstractEndNode, ValueNode> phiValues = EconomicMap.create(Equivalence.IDENTITY, mergePredecessors.size());
AbstractBeginNode oldFalseSuccessor = falseSuccessor();
AbstractBeginNode oldTrueSuccessor = trueSuccessor();
setFalseSuccessor(null);
setTrueSuccessor(null);
Iterator<EndNode> ends = mergePredecessors.iterator();
for (int i = 0; i < xs.length; i++) {
EndNode end = ends.next();
phiValues.put(end, phi.valueAt(end));
if (compare.condition().foldCondition(xs[i], ys[i], tool.getConstantReflection(), compare.unorderedIsTrue())) {
trueEnds.add(end);
} else {
falseEnds.add(end);
}
}
assert !ends.hasNext();
assert falseEnds.size() + trueEnds.size() == xs.length;
connectEnds(falseEnds, phiValues, oldFalseSuccessor, merge, tool);
connectEnds(trueEnds, phiValues, oldTrueSuccessor, merge, tool);
if (this.trueSuccessorProbability == 0.0) {
for (AbstractEndNode endNode : trueEnds) {
propagateZeroProbability(endNode);
}
}
if (this.trueSuccessorProbability == 1.0) {
for (AbstractEndNode endNode : falseEnds) {
propagateZeroProbability(endNode);
}
}
/*
* Remove obsolete ends only after processing all ends, otherwise oldTrueSuccessor or
* oldFalseSuccessor might have been removed if it is a LoopExitNode.
*/
if (falseEnds.isEmpty()) {
GraphUtil.killCFG(oldFalseSuccessor);
}
if (trueEnds.isEmpty()) {
GraphUtil.killCFG(oldTrueSuccessor);
}
GraphUtil.killCFG(merge);
assert !merge.isAlive() : merge;
assert !phi.isAlive() : phi;
assert !compare.isAlive() : compare;
assert !this.isAlive() : this;
return true;
}
Aggregations