use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.
the class LongNodeChainTest method longAddChain.
private void longAddChain(boolean reverse) {
HighTierContext context = getDefaultHighTierContext();
OptionValues options = getInitialOptions();
StructuredGraph graph = new StructuredGraph.Builder(options, new Builder(options).build()).build();
ValueNode constant = graph.unique(ConstantNode.forPrimitive(JavaConstant.INT_1));
ValueNode value = null;
if (reverse) {
// Make sure the constant's stamp is not used to infer the add node's stamp.
OpaqueNode opaque = graph.unique(new OpaqueNode(constant));
constant = opaque;
AddNode addNode = graph.unique(new AddNode(constant, constant));
value = addNode;
for (int i = 1; i < N; ++i) {
AddNode newAddNode = graph.addWithoutUnique(new AddNode(constant, constant));
addNode.setY(newAddNode);
addNode = newAddNode;
}
opaque.remove();
} else {
value = constant;
for (int i = 0; i < N; ++i) {
value = graph.unique(new AddNode(constant, value));
}
}
ReturnNode returnNode = graph.add(new ReturnNode(value));
graph.start().setNext(returnNode);
for (SchedulingStrategy s : Strategies) {
SchedulePhase.runWithoutContextOptimizations(graph, s);
}
this.createCanonicalizerPhase().apply(graph, context);
JavaConstant asConstant = (JavaConstant) returnNode.result().asConstant();
Assert.assertEquals(N + 1, asConstant.asInt());
}
use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.
the class UnschedulableGraphTest method checkLowTierGraph.
@Override
protected void checkLowTierGraph(StructuredGraph graph) {
super.checkLowTierGraph(graph);
ScheduleResult res = graph.getLastSchedule();
BlockMap<List<Node>> blockToNode = res.getBlockToNodesMap();
NodeMap<Block> nodeToBlock = res.getNodeToBlockMap();
Assert.assertEquals(4, res.getCFG().getBlocks().length);
Block split = res.getCFG().getStartBlock();
Assert.assertEquals(2, split.getSuccessorCount());
Block trueSucc = split.getSuccessors()[0];
Block falseSucc = split.getSuccessors()[1];
Block merge = trueSucc.getFirstSuccessor();
Assert.assertEquals(merge, falseSucc.getFirstSuccessor());
for (OpaqueNode op : graph.getNodes().filter(OpaqueNode.class)) {
Assert.assertEquals(merge, res.getNodeToBlockMap().get(op));
}
int k = 0;
// destroy dominance relation for NegateNode nodes, they no longer dominate the addition
for (NegateNode op : graph.getNodes().filter(NegateNode.class)) {
final Block nonDominatingBlock = k++ % 2 == 0 ? trueSucc : falseSucc;
blockToNode.get(merge).remove(op);
blockToNode.get(nonDominatingBlock).add(0, op);
nodeToBlock.set(op, nonDominatingBlock);
}
graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, graph, "After changing constant schedule");
}
use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.
the class LoopPartialUnrollPhase method unroll.
@SuppressWarnings("try")
private void unroll(StructuredGraph graph, CoreProviders context) {
EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener();
boolean changed = true;
EconomicMap<LoopBeginNode, OpaqueNode> opaqueUnrolledStrides = null;
boolean prePostInserted = false;
while (changed) {
changed = false;
try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
LoopsData dataCounted = context.getLoopsDataProvider().getLoopsData(graph);
dataCounted.detectedCountedLoops();
Graph.Mark mark = graph.getMark();
for (LoopEx loop : dataCounted.countedLoops()) {
if (!LoopTransformations.isUnrollableLoop(loop)) {
continue;
}
if (getPolicies().shouldPartiallyUnroll(loop, context)) {
if (loop.loopBegin().isSimpleLoop()) {
// First perform the pre/post transformation and do the partial
// unroll when we come around again.
LoopTransformations.insertPrePostLoops(loop);
prePostInserted = true;
changed = true;
} else if (prePostInserted) {
if (opaqueUnrolledStrides == null) {
opaqueUnrolledStrides = EconomicMap.create(Equivalence.IDENTITY);
}
LoopTransformations.partialUnroll(loop, opaqueUnrolledStrides);
changed = true;
}
}
}
dataCounted.deleteUnusedNodes();
if (!listener.getNodes().isEmpty()) {
canonicalizer.applyIncremental(graph, context, listener.getNodes());
listener.getNodes().clear();
}
assert !prePostInserted || checkCounted(graph, context.getLoopsDataProvider(), mark);
}
}
if (opaqueUnrolledStrides != null) {
try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
for (OpaqueNode opaque : opaqueUnrolledStrides.getValues()) {
opaque.remove();
}
if (!listener.getNodes().isEmpty()) {
canonicalizer.applyIncremental(graph, context, listener.getNodes());
}
}
}
}
use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.
the class DataPatchTest method registerInvocationPlugins.
@Override
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
Registration r = new Registration(invocationPlugins, DataPatchTest.class);
r.register(new InvocationPlugin("compressUncompress", Object.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
CompressEncoding encoding = runtime().getVMConfig().getOopEncoding();
ValueNode compressed = b.add(HotSpotCompressionNode.compress(arg, encoding));
ValueNode proxy = b.add(new OpaqueNode(compressed));
b.addPush(JavaKind.Object, HotSpotCompressionNode.uncompress(proxy, encoding));
return true;
}
});
super.registerInvocationPlugins(invocationPlugins);
}
use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.
the class LoopFragmentInside method insertWithinAfter.
/**
* Duplicate the body within the loop after the current copy copy of the body, updating the
* iteration limit to account for the duplication.
*/
public void insertWithinAfter(LoopEx loop, EconomicMap<LoopBeginNode, OpaqueNode> opaqueUnrolledStrides) {
assert isDuplicate() && original().loop() == loop;
patchNodes(dataFixWithinAfter);
/*
* Collect any new back edges values before updating them since they might reference each
* other.
*/
LoopBeginNode mainLoopBegin = loop.loopBegin();
ArrayList<ValueNode> backedgeValues = new ArrayList<>();
EconomicMap<Node, Node> new2OldPhis = EconomicMap.create();
EconomicMap<Node, Node> originalPhi2Backedges = EconomicMap.create();
for (PhiNode mainPhiNode : mainLoopBegin.phis()) {
originalPhi2Backedges.put(mainPhiNode, mainPhiNode.valueAt(1));
}
for (PhiNode mainPhiNode : mainLoopBegin.phis()) {
ValueNode originalNode = mainPhiNode.valueAt(1);
ValueNode duplicatedNode = getDuplicatedNode(originalNode);
if (duplicatedNode == null) {
if (mainLoopBegin.isPhiAtMerge(originalNode)) {
duplicatedNode = ((PhiNode) (originalNode)).valueAt(1);
} else {
assert originalNode.isConstant() || loop.isOutsideLoop(originalNode) : "Not duplicated node " + originalNode;
}
}
if (duplicatedNode != null) {
new2OldPhis.put(duplicatedNode, originalNode);
}
backedgeValues.add(duplicatedNode);
}
int index = 0;
for (PhiNode mainPhiNode : mainLoopBegin.phis()) {
ValueNode duplicatedNode = backedgeValues.get(index++);
if (duplicatedNode != null) {
mainPhiNode.setValueAt(1, duplicatedNode);
}
}
CompareNode condition = placeNewSegmentAndCleanup(loop, new2OldPhis, originalPhi2Backedges);
// Remove any safepoints from the original copy leaving only the duplicated one
assert loop.whole().nodes().filter(SafepointNode.class).count() == nodes().filter(SafepointNode.class).count();
for (SafepointNode safepoint : loop.whole().nodes().filter(SafepointNode.class)) {
graph().removeFixed(safepoint);
}
StructuredGraph graph = mainLoopBegin.graph();
if (opaqueUnrolledStrides != null) {
OpaqueNode opaque = opaqueUnrolledStrides.get(loop.loopBegin());
CountedLoopInfo counted = loop.counted();
ValueNode counterStride = counted.getLimitCheckedIV().strideNode();
if (opaque == null || opaque.isDeleted()) {
ValueNode limit = counted.getLimit();
opaque = new OpaqueNode(AddNode.add(counterStride, counterStride, NodeView.DEFAULT));
ValueNode newLimit = partialUnrollOverflowCheck(opaque, limit, counted);
condition.replaceFirstInput(limit, graph.addOrUniqueWithInputs(newLimit));
opaqueUnrolledStrides.put(loop.loopBegin(), opaque);
} else {
assert counted.getLimitCheckedIV().isConstantStride();
assert Math.addExact(counted.getLimitCheckedIV().constantStride(), counted.getLimitCheckedIV().constantStride()) == counted.getLimitCheckedIV().constantStride() * 2;
ValueNode previousValue = opaque.getValue();
opaque.setValue(graph.addOrUniqueWithInputs(AddNode.add(counterStride, previousValue, NodeView.DEFAULT)));
GraphUtil.tryKillUnused(previousValue);
}
}
mainLoopBegin.setUnrollFactor(mainLoopBegin.getUnrollFactor() * 2);
graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "LoopPartialUnroll %s", loop);
mainLoopBegin.getDebug().dump(DebugContext.VERBOSE_LEVEL, mainLoopBegin.graph(), "After insertWithinAfter %s", mainLoopBegin);
}
Aggregations