001/* 002 * Copyright (c) 2011, 2011, 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.graph; 024 025import java.util.*; 026 027public final class NodeFlood implements Iterable<Node> { 028 029 private final NodeBitMap visited; 030 private final Queue<Node> worklist; 031 private int totalMarkedCount; 032 033 public NodeFlood(Graph graph) { 034 visited = graph.createNodeBitMap(); 035 worklist = new ArrayDeque<>(); 036 } 037 038 public void add(Node node) { 039 if (node != null && !visited.isMarked(node)) { 040 visited.mark(node); 041 worklist.add(node); 042 totalMarkedCount++; 043 } 044 } 045 046 public int getTotalMarkedCount() { 047 return totalMarkedCount; 048 } 049 050 public void addAll(Iterable<? extends Node> nodes) { 051 for (Node node : nodes) { 052 this.add(node); 053 } 054 } 055 056 public NodeBitMap getVisited() { 057 return visited; 058 } 059 060 public boolean isMarked(Node node) { 061 return visited.isMarked(node); 062 } 063 064 public boolean isNew(Node node) { 065 return visited.isNew(node); 066 } 067 068 private static class QueueConsumingIterator implements Iterator<Node> { 069 070 private final Queue<Node> queue; 071 072 public QueueConsumingIterator(Queue<Node> queue) { 073 this.queue = queue; 074 } 075 076 @Override 077 public boolean hasNext() { 078 return !queue.isEmpty(); 079 } 080 081 @Override 082 public Node next() { 083 return queue.remove(); 084 } 085 086 @Override 087 public void remove() { 088 throw new UnsupportedOperationException(); 089 } 090 } 091 092 @Override 093 public Iterator<Node> iterator() { 094 return new QueueConsumingIterator(worklist); 095 } 096 097 private static class UnmarkedNodeIterator implements Iterator<Node> { 098 099 private final NodeBitMap visited; 100 private Iterator<Node> nodes; 101 private Node nextNode; 102 103 public UnmarkedNodeIterator(NodeBitMap visited, Iterator<Node> nodes) { 104 this.visited = visited; 105 this.nodes = nodes; 106 forward(); 107 } 108 109 private void forward() { 110 do { 111 if (!nodes.hasNext()) { 112 nextNode = null; 113 return; 114 } 115 nextNode = nodes.next(); 116 } while (visited.isMarked(nextNode)); 117 } 118 119 @Override 120 public boolean hasNext() { 121 return nextNode != null; 122 } 123 124 @Override 125 public Node next() { 126 try { 127 return nextNode; 128 } finally { 129 forward(); 130 } 131 } 132 133 @Override 134 public void remove() { 135 throw new UnsupportedOperationException(); 136 } 137 } 138 139 public Iterable<Node> unmarkedNodes() { 140 return new Iterable<Node>() { 141 142 @Override 143 public Iterator<Node> iterator() { 144 return new UnmarkedNodeIterator(visited, visited.graph().getNodes().iterator()); 145 } 146 }; 147 } 148}