001/*
002 * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.phases.graph;
024
025import java.util.*;
026
027import com.oracle.graal.graph.*;
028import com.oracle.graal.nodes.*;
029import com.oracle.graal.nodes.cfg.*;
030import com.oracle.graal.phases.schedule.*;
031
032/**
033 * Iterates over a list of nodes, which usually comes from
034 * {@link SchedulePhase#getBlockToNodesMap()}.
035 *
036 * While iterating, it is possible to {@link #insert(FixedNode, FixedWithNextNode) insert} and
037 * {@link #replaceCurrent(FixedWithNextNode) replace} nodes.
038 */
039public abstract class ScheduledNodeIterator {
040
041    private FixedWithNextNode lastFixed;
042    private FixedWithNextNode reconnect;
043    private ListIterator<Node> iterator;
044
045    public void processNodes(Block block, SchedulePhase shedule) {
046        lastFixed = block.getBeginNode();
047        assert lastFixed != null;
048        reconnect = null;
049        iterator = shedule.nodesFor(block).listIterator();
050
051        while (iterator.hasNext()) {
052            Node node = iterator.next();
053            if (!node.isAlive()) {
054                continue;
055            }
056            if (reconnect != null && node instanceof FixedNode) {
057                reconnect.setNext((FixedNode) node);
058                reconnect = null;
059            }
060            if (node instanceof FixedWithNextNode) {
061                lastFixed = (FixedWithNextNode) node;
062            }
063            processNode(node);
064        }
065        if (reconnect != null) {
066            assert block.getSuccessorCount() == 1;
067            reconnect.setNext(block.getFirstSuccessor().getBeginNode());
068        }
069    }
070
071    protected void insert(FixedNode start, FixedWithNextNode end) {
072        this.lastFixed.setNext(start);
073        this.lastFixed = end;
074        this.reconnect = end;
075    }
076
077    protected void replaceCurrent(FixedWithNextNode newNode) {
078        Node current = iterator.previous();
079        iterator.next(); // needed because of the previous() call
080        current.replaceAndDelete(newNode);
081        insert(newNode, newNode);
082        iterator.set(newNode);
083    }
084
085    protected abstract void processNode(Node node);
086}