use of org.graalvm.compiler.nodes.calc.AddNode in project graal by oracle.
the class ArrayCopyCallNode method computeBase.
private ValueNode computeBase(ValueNode base, ValueNode pos) {
FixedWithNextNode basePtr = graph().add(new GetObjectAddressNode(base));
graph().addBeforeFixed(this, basePtr);
Stamp wordStamp = StampFactory.forKind(runtime.getTarget().wordJavaKind);
ValueNode wordPos = IntegerConvertNode.convert(pos, wordStamp, graph(), NodeView.DEFAULT);
int shift = CodeUtil.log2(getArrayIndexScale(elementKind));
ValueNode scaledIndex = graph().unique(new LeftShiftNode(wordPos, ConstantNode.forInt(shift, graph())));
ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerStamp(wordStamp, getArrayBaseOffset(elementKind), graph())));
return graph().unique(new OffsetAddressNode(basePtr, offset));
}
use of org.graalvm.compiler.nodes.calc.AddNode in project graal by oracle.
the class FinalizeProfileNodesPhase method assignRandomSources.
private static void assignRandomSources(StructuredGraph graph) {
ValueNode seed = graph.unique(new RandomSeedNode());
ControlFlowGraph cfg = ControlFlowGraph.compute(graph, false, true, false, false);
Map<LoopBeginNode, ValueNode> loopRandomValueCache = new HashMap<>();
for (ProfileNode node : getProfileNodes(graph)) {
ValueNode random;
Block block = cfg.blockFor(node);
Loop<Block> loop = block.getLoop();
// pseudo-random number generator into the loop
if (loop != null) {
LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
random = loopRandomValueCache.get(loopBegin);
if (random == null) {
PhiNode phi = graph.addWithoutUnique(new ValuePhiNode(seed.stamp(NodeView.DEFAULT), loopBegin));
phi.addInput(seed);
// X_{n+1} = a*X_n + c, using glibc-like constants
ValueNode a = ConstantNode.forInt(1103515245, graph);
ValueNode c = ConstantNode.forInt(12345, graph);
ValueNode next = graph.addOrUniqueWithInputs(new AddNode(c, new MulNode(phi, a)));
for (int i = 0; i < loopBegin.getLoopEndCount(); i++) {
phi.addInput(next);
}
random = phi;
loopRandomValueCache.put(loopBegin, random);
}
} else {
// Graal doesn't compile methods with irreducible loops. So all profile nodes that
// are not in a loop are guaranteed to be executed at most once. We feed the seed
// value to such nodes directly.
random = seed;
}
node.setRandom(random);
}
}
use of org.graalvm.compiler.nodes.calc.AddNode in project graal by oracle.
the class OffsetAddressNode method canonical.
@Override
public Node canonical(CanonicalizerTool tool) {
if (base instanceof OffsetAddressNode) {
NodeView view = NodeView.from(tool);
// Rewrite (&base[offset1])[offset2] to base[offset1 + offset2].
OffsetAddressNode b = (OffsetAddressNode) base;
return new OffsetAddressNode(b.getBase(), BinaryArithmeticNode.add(b.getOffset(), this.getOffset(), view));
} else if (base instanceof AddNode) {
AddNode add = (AddNode) base;
if (add.getY().isConstant()) {
return new OffsetAddressNode(add.getX(), new AddNode(add.getY(), getOffset()));
}
}
return this;
}
use of org.graalvm.compiler.nodes.calc.AddNode in project graal by oracle.
the class IntegerAddExactSplitNode method simplify.
@Override
public void simplify(SimplifierTool tool) {
NodeView view = NodeView.from(tool);
if (!IntegerStamp.addCanOverflow((IntegerStamp) x.stamp(view), (IntegerStamp) y.stamp(view))) {
tool.deleteBranch(overflowSuccessor);
tool.addToWorkList(next);
AddNode replacement = graph().unique(new AddNode(x, y));
graph().replaceSplitWithFloating(this, replacement, next);
tool.addToWorkList(replacement);
}
}
use of org.graalvm.compiler.nodes.calc.AddNode in project graal by oracle.
the class AMD64AddressLowering method improve.
/**
* Tries to optimize addresses so that they match the AMD64-specific addressing mode better
* (base + index * scale + displacement).
*
* @param graph the current graph
* @param debug the current debug context
* @param ret the address that should be optimized
* @param isBaseNegated determines if the address base is negated. if so, all values that are
* extracted from the base will be negated as well
* @param isIndexNegated determines if the index is negated. if so, all values that are
* extracted from the index will be negated as well
* @return true if the address was modified
*/
protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode ret, boolean isBaseNegated, boolean isIndexNegated) {
ValueNode newBase = improveInput(ret, ret.getBase(), 0, isBaseNegated);
if (newBase != ret.getBase()) {
ret.setBase(newBase);
return true;
}
ValueNode newIdx = improveInput(ret, ret.getIndex(), ret.getScale().log2, isIndexNegated);
if (newIdx != ret.getIndex()) {
ret.setIndex(newIdx);
return true;
}
if (ret.getIndex() instanceof LeftShiftNode) {
LeftShiftNode shift = (LeftShiftNode) ret.getIndex();
if (shift.getY().isConstant()) {
int amount = ret.getScale().log2 + shift.getY().asJavaConstant().asInt();
Scale scale = Scale.fromShift(amount);
if (scale != null) {
ret.setIndex(shift.getX());
ret.setScale(scale);
return true;
}
}
}
if (ret.getScale() == Scale.Times1) {
if (ret.getIndex() == null && ret.getBase() instanceof AddNode) {
AddNode add = (AddNode) ret.getBase();
ret.setBase(add.getX());
ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated));
return true;
}
if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
AddNode add = (AddNode) ret.getIndex();
ret.setBase(considerNegation(graph, add.getX(), isIndexNegated));
ret.setIndex(add.getY());
return true;
}
if (ret.getBase() instanceof LeftShiftNode && !(ret.getIndex() instanceof LeftShiftNode)) {
ValueNode tmp = ret.getBase();
ret.setBase(considerNegation(graph, ret.getIndex(), isIndexNegated != isBaseNegated));
ret.setIndex(considerNegation(graph, tmp, isIndexNegated != isBaseNegated));
return true;
}
}
return improveNegation(graph, debug, ret, isBaseNegated, isIndexNegated);
}
Aggregations