Search in sources :

Example 11 with ReadNode

use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.

the class WriteBarrierAdditionTest method testHelper.

@SuppressWarnings("try")
private void testHelper(final String snippetName, final int expectedBarriers) throws Exception, SecurityException {
    ResolvedJavaMethod snippet = getResolvedJavaMethod(snippetName);
    DebugContext debug = getDebugContext();
    try (DebugContext.Scope s = debug.scope("WriteBarrierAdditionTest", snippet)) {
        StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO, debug);
        HighTierContext highContext = getDefaultHighTierContext();
        MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
        new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext);
        new CanonicalizerPhase().apply(graph, highContext);
        new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext);
        new GuardLoweringPhase().apply(graph, midContext);
        new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
        new WriteBarrierAdditionPhase(config).apply(graph);
        debug.dump(DebugContext.BASIC_LEVEL, graph, "After Write Barrier Addition");
        int barriers = 0;
        if (config.useG1GC) {
            barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count();
        } else {
            barriers = graph.getNodes().filter(SerialWriteBarrier.class).count();
        }
        if (expectedBarriers != barriers) {
            Assert.assertEquals(getScheduledGraphString(graph), expectedBarriers, barriers);
        }
        for (WriteNode write : graph.getNodes().filter(WriteNode.class)) {
            if (config.useG1GC) {
                if (write.getBarrierType() != BarrierType.NONE) {
                    Assert.assertEquals(1, write.successors().count());
                    Assert.assertTrue(write.next() instanceof G1PostWriteBarrier);
                    Assert.assertTrue(write.predecessor() instanceof G1PreWriteBarrier);
                }
            } else {
                if (write.getBarrierType() != BarrierType.NONE) {
                    Assert.assertEquals(1, write.successors().count());
                    Assert.assertTrue(write.next() instanceof SerialWriteBarrier);
                }
            }
        }
        for (ReadNode read : graph.getNodes().filter(ReadNode.class)) {
            if (read.getBarrierType() != BarrierType.NONE) {
                Assert.assertTrue(read.getAddress() instanceof OffsetAddressNode);
                JavaConstant constDisp = ((OffsetAddressNode) read.getAddress()).getOffset().asJavaConstant();
                Assert.assertNotNull(constDisp);
                Assert.assertEquals(referentOffset, constDisp.asLong());
                Assert.assertTrue(config.useG1GC);
                Assert.assertEquals(BarrierType.PRECISE, read.getBarrierType());
                Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier);
            }
        }
    } catch (Throwable e) {
        throw debug.handle(e);
    }
}
Also used : InlineEverythingPolicy(org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy) GuardLoweringPhase(org.graalvm.compiler.phases.common.GuardLoweringPhase) LoweringPhase(org.graalvm.compiler.phases.common.LoweringPhase) WriteBarrierAdditionPhase(org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase) G1PreWriteBarrier(org.graalvm.compiler.hotspot.nodes.G1PreWriteBarrier) JavaConstant(jdk.vm.ci.meta.JavaConstant) DebugContext(org.graalvm.compiler.debug.DebugContext) SerialWriteBarrier(org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier) G1ReferentFieldReadBarrier(org.graalvm.compiler.hotspot.nodes.G1ReferentFieldReadBarrier) MidTierContext(org.graalvm.compiler.phases.tiers.MidTierContext) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) ReadNode(org.graalvm.compiler.nodes.memory.ReadNode) HighTierContext(org.graalvm.compiler.phases.tiers.HighTierContext) G1PostWriteBarrier(org.graalvm.compiler.hotspot.nodes.G1PostWriteBarrier) InliningPhase(org.graalvm.compiler.phases.common.inlining.InliningPhase) GuardLoweringPhase(org.graalvm.compiler.phases.common.GuardLoweringPhase) WriteNode(org.graalvm.compiler.nodes.memory.WriteNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 12 with ReadNode

use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.

the class ReadEliminationClosure method processNode.

@Override
protected boolean processNode(Node node, ReadEliminationBlockState state, GraphEffectList effects, FixedWithNextNode lastFixedNode) {
    boolean deleted = false;
    if (node instanceof AccessFieldNode) {
        AccessFieldNode access = (AccessFieldNode) node;
        if (access.isVolatile()) {
            processIdentity(state, any());
        } else {
            ValueNode object = GraphUtil.unproxify(access.object());
            LoadCacheEntry identifier = new LoadCacheEntry(object, new FieldLocationIdentity(access.field()));
            ValueNode cachedValue = state.getCacheEntry(identifier);
            if (node instanceof LoadFieldNode) {
                if (cachedValue != null && access.stamp(NodeView.DEFAULT).isCompatible(cachedValue.stamp(NodeView.DEFAULT))) {
                    effects.replaceAtUsages(access, cachedValue, access);
                    addScalarAlias(access, cachedValue);
                    deleted = true;
                } else {
                    state.addCacheEntry(identifier, access);
                }
            } else {
                assert node instanceof StoreFieldNode;
                StoreFieldNode store = (StoreFieldNode) node;
                ValueNode value = getScalarAlias(store.value());
                if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
                    effects.deleteNode(store);
                    deleted = true;
                }
                state.killReadCache(identifier.identity);
                state.addCacheEntry(identifier, value);
            }
        }
    } else if (node instanceof ReadNode) {
        ReadNode read = (ReadNode) node;
        if (read.getLocationIdentity().isSingle()) {
            ValueNode object = GraphUtil.unproxify(read.getAddress());
            LoadCacheEntry identifier = new LoadCacheEntry(object, read.getLocationIdentity());
            ValueNode cachedValue = state.getCacheEntry(identifier);
            if (cachedValue != null && areValuesReplaceable(read, cachedValue, considerGuards)) {
                effects.replaceAtUsages(read, cachedValue, read);
                addScalarAlias(read, cachedValue);
                deleted = true;
            } else {
                state.addCacheEntry(identifier, read);
            }
        }
    } else if (node instanceof WriteNode) {
        WriteNode write = (WriteNode) node;
        if (write.getLocationIdentity().isSingle()) {
            ValueNode object = GraphUtil.unproxify(write.getAddress());
            LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity());
            ValueNode cachedValue = state.getCacheEntry(identifier);
            ValueNode value = getScalarAlias(write.value());
            if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
                effects.deleteNode(write);
                deleted = true;
            }
            processIdentity(state, write.getLocationIdentity());
            state.addCacheEntry(identifier, value);
        } else {
            processIdentity(state, write.getLocationIdentity());
        }
    } else if (node instanceof UnsafeAccessNode) {
        ResolvedJavaType type = StampTool.typeOrNull(((UnsafeAccessNode) node).object());
        if (type != null && !type.isArray()) {
            if (node instanceof RawLoadNode) {
                RawLoadNode load = (RawLoadNode) node;
                if (load.getLocationIdentity().isSingle()) {
                    ValueNode object = GraphUtil.unproxify(load.object());
                    UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, load.offset(), load.getLocationIdentity());
                    ValueNode cachedValue = state.getCacheEntry(identifier);
                    if (cachedValue != null && areValuesReplaceable(load, cachedValue, considerGuards)) {
                        effects.replaceAtUsages(load, cachedValue, load);
                        addScalarAlias(load, cachedValue);
                        deleted = true;
                    } else {
                        state.addCacheEntry(identifier, load);
                    }
                }
            } else {
                assert node instanceof RawStoreNode;
                RawStoreNode write = (RawStoreNode) node;
                if (write.getLocationIdentity().isSingle()) {
                    ValueNode object = GraphUtil.unproxify(write.object());
                    UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, write.offset(), write.getLocationIdentity());
                    ValueNode cachedValue = state.getCacheEntry(identifier);
                    ValueNode value = getScalarAlias(write.value());
                    if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
                        effects.deleteNode(write);
                        deleted = true;
                    }
                    processIdentity(state, write.getLocationIdentity());
                    state.addCacheEntry(identifier, value);
                } else {
                    processIdentity(state, write.getLocationIdentity());
                }
            }
        }
    } else if (node instanceof MemoryCheckpoint.Single) {
        LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
        processIdentity(state, identity);
    } else if (node instanceof MemoryCheckpoint.Multi) {
        for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
            processIdentity(state, identity);
        }
    }
    return deleted;
}
Also used : RawStoreNode(org.graalvm.compiler.nodes.extended.RawStoreNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) UnsafeLoadCacheEntry(org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.UnsafeLoadCacheEntry) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) RawLoadNode(org.graalvm.compiler.nodes.extended.RawLoadNode) FieldLocationIdentity(org.graalvm.compiler.nodes.FieldLocationIdentity) UnsafeAccessNode(org.graalvm.compiler.nodes.extended.UnsafeAccessNode) MemoryCheckpoint(org.graalvm.compiler.nodes.memory.MemoryCheckpoint) AccessFieldNode(org.graalvm.compiler.nodes.java.AccessFieldNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LocationIdentity(org.graalvm.word.LocationIdentity) FieldLocationIdentity(org.graalvm.compiler.nodes.FieldLocationIdentity) ReadNode(org.graalvm.compiler.nodes.memory.ReadNode) WriteNode(org.graalvm.compiler.nodes.memory.WriteNode) LoadCacheEntry(org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.LoadCacheEntry) UnsafeLoadCacheEntry(org.graalvm.compiler.virtual.phases.ea.ReadEliminationBlockState.UnsafeLoadCacheEntry)

Example 13 with ReadNode

use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.

the class DefaultJavaLoweringProvider method lowerLoadIndexedNode.

protected void lowerLoadIndexedNode(LoadIndexedNode loadIndexed, LoweringTool tool) {
    StructuredGraph graph = loadIndexed.graph();
    ValueNode array = loadIndexed.array();
    array = createNullCheckedValue(array, loadIndexed, tool);
    JavaKind elementKind = loadIndexed.elementKind();
    Stamp loadStamp = loadStamp(loadIndexed.stamp(NodeView.DEFAULT), elementKind);
    GuardingNode boundsCheck = getBoundsCheck(loadIndexed, array, tool);
    AddressNode address = createArrayIndexAddress(graph, array, elementKind, loadIndexed.index(), boundsCheck);
    ReadNode memoryRead = graph.add(new ReadNode(address, NamedLocationIdentity.getArrayLocation(elementKind), loadStamp, BarrierType.NONE));
    memoryRead.setGuard(boundsCheck);
    ValueNode readValue = implicitLoadConvert(graph, elementKind, memoryRead);
    loadIndexed.replaceAtUsages(readValue);
    graph.replaceFixed(loadIndexed, memoryRead);
}
Also used : StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) JavaReadNode(org.graalvm.compiler.nodes.extended.JavaReadNode) ReadNode(org.graalvm.compiler.nodes.memory.ReadNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 14 with ReadNode

use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.

the class DefaultJavaLoweringProvider method createUnsafeRead.

protected ReadNode createUnsafeRead(StructuredGraph graph, RawLoadNode load, GuardingNode guard) {
    boolean compressible = load.accessKind() == JavaKind.Object;
    JavaKind readKind = load.accessKind();
    Stamp loadStamp = loadStamp(load.stamp(NodeView.DEFAULT), readKind, compressible);
    AddressNode address = createUnsafeAddress(graph, load.object(), load.offset());
    ReadNode memoryRead = graph.add(new ReadNode(address, load.getLocationIdentity(), loadStamp, BarrierType.NONE));
    if (guard == null) {
        // An unsafe read must not float otherwise it may float above
        // a test guaranteeing the read is safe.
        memoryRead.setForceFixed(true);
    } else {
        memoryRead.setGuard(guard);
    }
    ValueNode readValue = performBooleanCoercionIfNecessary(implicitLoadConvert(graph, readKind, memoryRead, compressible), readKind);
    load.replaceAtUsages(readValue);
    return memoryRead;
}
Also used : ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) JavaReadNode(org.graalvm.compiler.nodes.extended.JavaReadNode) ReadNode(org.graalvm.compiler.nodes.memory.ReadNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 15 with ReadNode

use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.

the class DefaultJavaLoweringProvider method lowerUnsafeMemoryLoadNode.

protected void lowerUnsafeMemoryLoadNode(UnsafeMemoryLoadNode load) {
    StructuredGraph graph = load.graph();
    JavaKind readKind = load.getKind();
    assert readKind != JavaKind.Object;
    Stamp loadStamp = loadStamp(load.stamp(NodeView.DEFAULT), readKind, false);
    AddressNode address = graph.addOrUniqueWithInputs(OffsetAddressNode.create(load.getAddress()));
    ReadNode memoryRead = graph.add(new ReadNode(address, load.getLocationIdentity(), loadStamp, BarrierType.NONE));
    // An unsafe read must not float otherwise it may float above
    // a test guaranteeing the read is safe.
    memoryRead.setForceFixed(true);
    ValueNode readValue = performBooleanCoercionIfNecessary(implicitLoadConvert(graph, readKind, memoryRead, false), readKind);
    load.replaceAtUsages(readValue);
    graph.replaceFixedWithFixed(load, memoryRead);
}
Also used : StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) JavaReadNode(org.graalvm.compiler.nodes.extended.JavaReadNode) ReadNode(org.graalvm.compiler.nodes.memory.ReadNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Aggregations

ReadNode (org.graalvm.compiler.nodes.memory.ReadNode)22 ValueNode (org.graalvm.compiler.nodes.ValueNode)14 AddressNode (org.graalvm.compiler.nodes.memory.address.AddressNode)13 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)11 OffsetAddressNode (org.graalvm.compiler.nodes.memory.address.OffsetAddressNode)10 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)9 Stamp (org.graalvm.compiler.core.common.type.Stamp)9 JavaReadNode (org.graalvm.compiler.nodes.extended.JavaReadNode)8 JavaKind (jdk.vm.ci.meta.JavaKind)7 FloatingReadNode (org.graalvm.compiler.nodes.memory.FloatingReadNode)6 IntegerStamp (org.graalvm.compiler.core.common.type.IntegerStamp)5 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)4 GuardingNode (org.graalvm.compiler.nodes.extended.GuardingNode)4 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)3 Node (org.graalvm.compiler.graph.Node)3 ComputeObjectAddressNode (org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode)3 GetObjectAddressNode (org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode)3 GraphBuilderContext (org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext)3 Registration (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration)3 WriteNode (org.graalvm.compiler.nodes.memory.WriteNode)3