001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.compilers.opt.util;
014    
015    
016    /**
017     * SpaceEffGraphEdge is a generic graph edge.  Extend this to implement
018     * specific graph edge types, or use it as a generic edge.
019     * SpaceEffGraphEdges are directed, and therefore, have a from-node and
020     * a to-node.
021     */
022    public class SpaceEffGraphEdge implements GraphEdge {
023      /**
024       * End node.
025       */
026      protected SpaceEffGraphNode _toNode;
027    
028      /**
029       * Start node.
030       */
031      protected SpaceEffGraphNode _fromNode;
032    
033      /**
034       * The following word is defined for several uses.  The first 4 bits
035       * are reserved for SpaceEffGraph.  Classes that subclass this one
036       * can use the remaining 28 bits
037       */
038      protected int scratch;
039    
040      static final int VISITED = 0x10000000; // general purpose
041    
042      static final int BACK_EDGE = 0x20000000; // edge information
043      static final int DOMINATOR = 0x40000000; // edge information
044    
045      static final int INFO_MASK = 0x0fffffff;
046    
047      public final boolean visited() { return (scratch & VISITED) != 0; }
048    
049      public final boolean backEdge() { return (scratch & BACK_EDGE) != 0; }
050    
051      public final boolean dominatorEdge() { return (scratch & DOMINATOR) != 0; }
052    
053      public final void setVisited() { scratch |= VISITED; }
054    
055      public final void setBackEdge() { scratch |= BACK_EDGE; }
056    
057      public final void setDominatorEdge() { scratch |= DOMINATOR; }
058    
059      public final void clearVisited() { scratch &= ~VISITED; }
060    
061      public final void clearBackEdge() { scratch &= ~BACK_EDGE; }
062    
063      public final void clearDominatorEdge() { scratch &= ~DOMINATOR; }
064    
065      public final int getInfo() {
066        return scratch & INFO_MASK;
067      }
068    
069      public final void setInfo(int value) {
070        scratch = (scratch & ~INFO_MASK) | (value & INFO_MASK);
071      }
072    
073      /**
074       * Get the end node for the edge.
075       * @return end node for the edge
076       */
077      public final SpaceEffGraphNode toNode() { return _toNode; }
078    
079      /**
080       * Get the start node for the edge.
081       * @return start node for the edge
082       */
083      public final SpaceEffGraphNode fromNode() { return _fromNode; }
084    
085      /**
086       * Set end node.
087       * WARNING: use with caution
088       * @param toNode new end node
089       */
090      final void setToNode(SpaceEffGraphNode toNode) { _toNode = toNode; }
091    
092      /**
093       * Set start node.
094       * WARNING: use with caution
095       * @param fromNode new start node
096       */
097      final void setFromNode(SpaceEffGraphNode fromNode) {
098        _fromNode = fromNode;
099      }
100    
101      /**
102       * Constructs an empty edge.
103       */
104      SpaceEffGraphEdge() { }
105    
106      /**
107       * Constructs an edge starting at a given node and ending at a given node.
108       * @param fromNode start node
109       * @param toNode end node
110       */
111      protected SpaceEffGraphEdge(SpaceEffGraphNode fromNode, SpaceEffGraphNode toNode) {
112        _toNode = toNode;
113        _fromNode = fromNode;
114      }
115    
116      /**
117       * Delete this edge from the graph.
118       */
119      final void delete() {
120        _fromNode.removeOut(this);
121        _toNode.removeIn(this);
122      }
123    
124      /**
125       * Returns the string representation of the edge type.
126       * @return string representation of the edge type
127       */
128      public String getTypeString() { return ""; }
129    
130      /**
131       * Returns the string representation of the end node (used for printing).
132       * @return string representation of the end node
133       */
134      public String toNodeString() {
135        return "---> " + _toNode;
136      }
137    
138      /**
139       * Returns the string representation of the start node (used for printing).
140       * @return string representation of the start node
141       */
142      public String fromNodeString() {
143        return "<--- " + _fromNode;
144      }
145    
146      /**
147       * Get the end node for the edge.
148       * @return end node for the edge
149       */
150      @Override
151      public final GraphNode to() { return _toNode; }
152    
153      /**
154       * Get the start node for the edge.
155       * @return start node for the edge
156       */
157      @Override
158      public final GraphNode from() { return _fromNode; }
159    
160      /**
161       * Links inlined from LinkedListElement2.
162       */
163      protected SpaceEffGraphEdge nextIn, nextOut;
164    
165      /**
166       * Get the next in edge.
167       * @return next in edge.
168       */
169      public final SpaceEffGraphEdge getNextIn() { return nextIn; }
170    
171      /**
172       * Get the next out edge.
173       * @return next out edge.
174       */
175      public final SpaceEffGraphEdge getNextOut() { return nextOut; }
176    
177      /**
178       * Append a given edge after this edge as an in edge.
179       * @param e the edge to append
180       */
181      final void appendIn(SpaceEffGraphEdge e) { nextIn = e; }
182    
183      /**
184       * Append a given edge after this edge as an out edge.
185       * @param e the edge to append
186       */
187      final void appendOut(SpaceEffGraphEdge e) { nextOut = e; }
188    }
189