Search in sources :

Example 26 with Block

use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.

the class PartialEscapeClosure method stripKilledLoopLocations.

@Override
protected BlockT stripKilledLoopLocations(Loop<Block> loop, BlockT originalInitialState) {
    BlockT initialState = super.stripKilledLoopLocations(loop, originalInitialState);
    if (loop.getDepth() > GraalOptions.EscapeAnalysisLoopCutoff.getValue(cfg.graph.getOptions())) {
        /*
             * After we've reached the maximum loop nesting, we'll simply materialize everything we
             * can to make sure that the loops only need to be iterated one time. Care is taken here
             * to not materialize virtual objects that have the "ensureVirtualized" flag set.
             */
        LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
        AbstractEndNode end = loopBegin.forwardEnd();
        Block loopPredecessor = loop.getHeader().getFirstPredecessor();
        assert loopPredecessor.getEndNode() == end;
        int length = initialState.getStateCount();
        boolean change;
        BitSet ensureVirtualized = new BitSet(length);
        for (int i = 0; i < length; i++) {
            ObjectState state = initialState.getObjectStateOptional(i);
            if (state != null && state.isVirtual() && state.getEnsureVirtualized()) {
                ensureVirtualized.set(i);
            }
        }
        do {
            // propagate "ensureVirtualized" flag
            change = false;
            for (int i = 0; i < length; i++) {
                if (!ensureVirtualized.get(i)) {
                    ObjectState state = initialState.getObjectStateOptional(i);
                    if (state != null && state.isVirtual()) {
                        for (ValueNode entry : state.getEntries()) {
                            if (entry instanceof VirtualObjectNode) {
                                if (ensureVirtualized.get(((VirtualObjectNode) entry).getObjectId())) {
                                    change = true;
                                    ensureVirtualized.set(i);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        } while (change);
        for (int i = 0; i < length; i++) {
            ObjectState state = initialState.getObjectStateOptional(i);
            if (state != null && state.isVirtual() && !ensureVirtualized.get(i)) {
                initialState.materializeBefore(end, virtualObjects.get(i), blockEffects.get(loopPredecessor));
            }
        }
    }
    return initialState;
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualObjectState(org.graalvm.compiler.virtual.nodes.VirtualObjectState) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) BitSet(java.util.BitSet) ValueNode(org.graalvm.compiler.nodes.ValueNode) Block(org.graalvm.compiler.nodes.cfg.Block)

Example 27 with Block

use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.

the class EffectsClosure method applyEffects.

@Override
public void applyEffects() {
    final StructuredGraph graph = cfg.graph;
    final ArrayList<Node> obsoleteNodes = new ArrayList<>(0);
    final ArrayList<GraphEffectList> effectList = new ArrayList<>();
    /*
         * Effects are applied during a ordered iteration over the blocks to apply them in the
         * correct order, e.g., apply the effect that adds a node to the graph before the node is
         * used.
         */
    BlockIteratorClosure<Void> closure = new BlockIteratorClosure<Void>() {

        @Override
        protected Void getInitialState() {
            return null;
        }

        private void apply(GraphEffectList effects) {
            if (effects != null && !effects.isEmpty()) {
                effectList.add(effects);
            }
        }

        @Override
        protected Void processBlock(Block block, Void currentState) {
            apply(blockEffects.get(block));
            return currentState;
        }

        @Override
        protected Void merge(Block merge, List<Void> states) {
            return null;
        }

        @Override
        protected Void cloneState(Void oldState) {
            return oldState;
        }

        @Override
        protected List<Void> processLoop(Loop<Block> loop, Void initialState) {
            LoopInfo<Void> info = ReentrantBlockIterator.processLoop(this, loop, initialState);
            apply(loopMergeEffects.get(loop));
            return info.exitStates;
        }
    };
    ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
    for (GraphEffectList effects : effectList) {
        effects.apply(graph, obsoleteNodes, false);
    }
    /*
         * Effects that modify the cfg (e.g., removing a branch for an if that got a constant
         * condition) need to be performed after all other effects, because they change phi value
         * indexes.
         */
    for (GraphEffectList effects : effectList) {
        effects.apply(graph, obsoleteNodes, true);
    }
    debug.dump(DebugContext.DETAILED_LEVEL, graph, "After applying effects");
    assert VirtualUtil.assertNonReachable(graph, obsoleteNodes);
    for (Node node : obsoleteNodes) {
        if (node.isAlive() && node.hasNoUsages()) {
            if (node instanceof FixedWithNextNode) {
                assert ((FixedWithNextNode) node).next() == null;
            }
            node.replaceAtUsages(null);
            GraphUtil.killWithUnusedFloatingInputs(node);
        }
    }
}
Also used : Loop(org.graalvm.compiler.core.common.cfg.Loop) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) BlockIteratorClosure(org.graalvm.compiler.phases.graph.ReentrantBlockIterator.BlockIteratorClosure) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) AllocatedObjectNode(org.graalvm.compiler.nodes.virtual.AllocatedObjectNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) IfNode(org.graalvm.compiler.nodes.IfNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) ArrayList(java.util.ArrayList) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) Block(org.graalvm.compiler.nodes.cfg.Block) ArrayList(java.util.ArrayList) List(java.util.List)

Example 28 with Block

use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.

the class LoopFragment method toHirExits.

public static NodeIterable<AbstractBeginNode> toHirExits(final Iterable<Block> blocks) {
    return new NodeIterable<AbstractBeginNode>() {

        @Override
        public Iterator<AbstractBeginNode> iterator() {
            final Iterator<Block> it = blocks.iterator();
            return new Iterator<AbstractBeginNode>() {

                @Override
                public void remove() {
                    throw new UnsupportedOperationException();
                }

                /**
                 * Return the true LoopExitNode for this loop or the BeginNode for the block.
                 */
                @Override
                public AbstractBeginNode next() {
                    Block next = it.next();
                    LoopExitNode exit = next.getLoopExit();
                    if (exit != null) {
                        return exit;
                    }
                    return next.getBeginNode();
                }

                @Override
                public boolean hasNext() {
                    return it.hasNext();
                }
            };
        }
    };
}
Also used : NodeIterable(org.graalvm.compiler.graph.iterators.NodeIterable) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Iterator(java.util.Iterator) Block(org.graalvm.compiler.nodes.cfg.Block) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 29 with Block

use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.

the class ReplaceConstantNodesPhase method findFixedWithValidState.

/**
 * Find first dominating {@link FixedWithNextNode} that has a valid state reaching it starting
 * from the given node.
 *
 * @param graph
 * @param stateMapper
 * @param node
 * @return {@link FixedWithNextNode} that we can use as an insertion point
 */
private static FixedWithNextNode findFixedWithValidState(StructuredGraph graph, FrameStateMapperClosure stateMapper, FixedWithNextNode node) {
    ScheduleResult schedule = graph.getLastSchedule();
    NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
    Block block = nodeToBlock.get(node);
    Node n = node;
    do {
        if (isFixedWithValidState(stateMapper, n)) {
            return (FixedWithNextNode) n;
        }
        while (n != block.getBeginNode()) {
            n = n.predecessor();
            if (isFixedWithValidState(stateMapper, n)) {
                return (FixedWithNextNode) n;
            }
        }
        block = block.getDominator();
        if (block != null) {
            n = block.getEndNode();
        }
    } while (block != null);
    return graph.start();
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) LoadMethodCountersNode(org.graalvm.compiler.hotspot.nodes.aot.LoadMethodCountersNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoadConstantIndirectlyFixedNode(org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyFixedNode) LoadConstantIndirectlyNode(org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ResolveDynamicConstantNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicConstantNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ResolveConstantNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) InitializeKlassNode(org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) ResolveMethodAndLoadCountersNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveMethodAndLoadCountersNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) Block(org.graalvm.compiler.nodes.cfg.Block)

Example 30 with Block

use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.

the class ReplaceConstantNodesPhase method tryToReplaceWithExisting.

/**
 * Try to find dominating node doing the resolution that can be reused.
 *
 * @param graph
 * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs
 *            resolution.
 */
private static void tryToReplaceWithExisting(StructuredGraph graph, ConstantNode node) {
    ScheduleResult schedule = graph.getLastSchedule();
    NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
    BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap();
    EconomicMap<Block, Node> blockToExisting = EconomicMap.create();
    for (Node n : node.usages().filter(n -> isReplacementNode(n))) {
        blockToExisting.put(nodeToBlock.get(n), n);
    }
    for (Node use : node.usages().filter(n -> !isReplacementNode(n)).snapshot()) {
        boolean replaced = false;
        Block b = nodeToBlock.get(use);
        Node e = blockToExisting.get(b);
        if (e != null) {
            // the use is scheduled after it.
            for (Node n : blockToNodes.get(b)) {
                if (n.equals(use)) {
                    // Usage is before initialization, can't use it
                    break;
                }
                if (n.equals(e)) {
                    use.replaceFirstInput(node, e);
                    replaced = true;
                    break;
                }
            }
        }
        if (!replaced) {
            // Look for dominating blocks that have existing nodes
            for (Block d : blockToExisting.getKeys()) {
                if (strictlyDominates(d, b)) {
                    use.replaceFirstInput(node, blockToExisting.get(d));
                    break;
                }
            }
        }
    }
}
Also used : LoadMethodCountersNode(org.graalvm.compiler.hotspot.nodes.aot.LoadMethodCountersNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) BytecodeFrame(jdk.vm.ci.code.BytecodeFrame) Constant(jdk.vm.ci.meta.Constant) HotSpotResolvedObjectType(jdk.vm.ci.hotspot.HotSpotResolvedObjectType) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoadConstantIndirectlyFixedNode(org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyFixedNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) StampFactory(org.graalvm.compiler.core.common.type.StampFactory) EconomicMap(org.graalvm.collections.EconomicMap) LoadConstantIndirectlyNode(org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyNode) HotSpotConstantLoadAction(org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ReentrantNodeIterator(org.graalvm.compiler.phases.graph.ReentrantNodeIterator) NodeIteratorClosure(org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure) ResolveDynamicConstantNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicConstantNode) ConstantReflectionProvider(jdk.vm.ci.meta.ConstantReflectionProvider) BasePhase(org.graalvm.compiler.phases.BasePhase) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) SchedulingStrategy(org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy) Stamp(org.graalvm.compiler.core.common.type.Stamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) List(java.util.List) FrameState(org.graalvm.compiler.nodes.FrameState) ConstantNode.getConstantNodes(org.graalvm.compiler.nodes.ConstantNode.getConstantNodes) GraalError(org.graalvm.compiler.debug.GraalError) HotSpotMetaspaceConstant(jdk.vm.ci.hotspot.HotSpotMetaspaceConstant) ResolveConstantNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode) ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) StateSplit(org.graalvm.compiler.nodes.StateSplit) LoadMethodCountersNode.getLoadMethodCountersNodes(org.graalvm.compiler.hotspot.nodes.aot.LoadMethodCountersNode.getLoadMethodCountersNodes) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) SchedulePhase(org.graalvm.compiler.phases.schedule.SchedulePhase) HashSet(java.util.HashSet) InitializeKlassNode(org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode) PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) NodeMap(org.graalvm.compiler.graph.NodeMap) FixedNode(org.graalvm.compiler.nodes.FixedNode) ResolveMethodAndLoadCountersNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveMethodAndLoadCountersNode) AbstractControlFlowGraph.strictlyDominates(org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph.strictlyDominates) HotSpotObjectConstant(jdk.vm.ci.hotspot.HotSpotObjectConstant) BlockMap(org.graalvm.compiler.core.common.cfg.BlockMap) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Block(org.graalvm.compiler.nodes.cfg.Block) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) HotSpotResolvedJavaType(jdk.vm.ci.hotspot.HotSpotResolvedJavaType) ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) LoadMethodCountersNode(org.graalvm.compiler.hotspot.nodes.aot.LoadMethodCountersNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoadConstantIndirectlyFixedNode(org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyFixedNode) LoadConstantIndirectlyNode(org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ResolveDynamicConstantNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicConstantNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ResolveConstantNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) InitializeKlassNode(org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) ResolveMethodAndLoadCountersNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveMethodAndLoadCountersNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) Block(org.graalvm.compiler.nodes.cfg.Block) List(java.util.List)

Aggregations

Block (org.graalvm.compiler.nodes.cfg.Block)54 Node (org.graalvm.compiler.graph.Node)20 FixedNode (org.graalvm.compiler.nodes.FixedNode)17 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)14 ScheduleResult (org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult)14 ValueNode (org.graalvm.compiler.nodes.ValueNode)14 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)13 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)13 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)13 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)13 ControlFlowGraph (org.graalvm.compiler.nodes.cfg.ControlFlowGraph)12 SchedulePhase (org.graalvm.compiler.phases.schedule.SchedulePhase)11 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)9 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)9 PhiNode (org.graalvm.compiler.nodes.PhiNode)9 List (java.util.List)8 DebugContext (org.graalvm.compiler.debug.DebugContext)8 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)8 ArrayList (java.util.ArrayList)7 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)7