001/* 002 * Copyright (c) 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.common; 024 025import java.util.*; 026 027import com.oracle.graal.graph.*; 028import com.oracle.graal.nodes.*; 029import com.oracle.graal.nodes.extended.*; 030import com.oracle.graal.phases.*; 031import com.oracle.graal.phases.graph.*; 032 033/** 034 * This phase performs a bit of hygiene on {@link ValueAnchorNode} by removing inputs that have 035 * already been anchored in a dominating value anchor. Value anchors that lose their last input, 036 * have no usages and are not marked as permanent are removed. 037 */ 038public class ValueAnchorCleanupPhase extends Phase { 039 040 private static class State extends MergeableState<State> implements Cloneable { 041 042 private final Set<Node> anchoredValues; 043 044 public State() { 045 anchoredValues = Node.newSet(); 046 } 047 048 public State(State other) { 049 anchoredValues = Node.newSet(other.anchoredValues); 050 } 051 052 @Override 053 public boolean merge(AbstractMergeNode merge, List<State> withStates) { 054 for (State other : withStates) { 055 anchoredValues.retainAll(other.anchoredValues); 056 } 057 return true; 058 } 059 060 @Override 061 public State clone() { 062 return new State(this); 063 } 064 } 065 066 private static class CleanupValueAnchorsClosure extends SinglePassNodeIterator<State> { 067 068 public CleanupValueAnchorsClosure(StartNode start) { 069 super(start, new State()); 070 } 071 072 @Override 073 protected void node(FixedNode node) { 074 if (node instanceof ValueAnchorNode) { 075 ValueAnchorNode anchor = (ValueAnchorNode) node; 076 ValueNode anchored = anchor.getAnchoredNode(); 077 if (anchored != null) { 078 if (state.anchoredValues.contains(anchored)) { 079 anchor.removeAnchoredNode(); 080 } else { 081 state.anchoredValues.add(anchored); 082 } 083 } 084 if (anchor.getAnchoredNode() == null && anchor.hasNoUsages()) { 085 node.graph().removeFixed(anchor); 086 } 087 } 088 } 089 } 090 091 @Override 092 protected void run(StructuredGraph graph) { 093 CleanupValueAnchorsClosure closure = new CleanupValueAnchorsClosure(graph.start()); 094 closure.apply(); 095 } 096}