Mirror of the BLOAT repository
https://www.cs.purdue.edu/homes/hosking/bloat/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
371 lines
9.0 KiB
371 lines
9.0 KiB
/**
|
|
* All files in the distribution of BLOAT (Bytecode Level Optimization and
|
|
* Analysis tool for Java(tm)) are Copyright 1997-2001 by the Purdue
|
|
* Research Foundation of Purdue University. All rights reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
package EDU.purdue.cs.bloat.cfg;
|
|
|
|
import java.util.*;
|
|
|
|
import EDU.purdue.cs.bloat.editor.*;
|
|
import EDU.purdue.cs.bloat.tree.*;
|
|
import EDU.purdue.cs.bloat.util.*;
|
|
|
|
/**
|
|
* <tt>Block</tt> represents a basic block of code used in control flow
|
|
* graphs. A basic block is always entered at its beginning and exits at its
|
|
* end. That is, its first statement is a label and its last statement is a
|
|
* jump. There are no other labels or jumps in between.
|
|
* <p>
|
|
* Each <tt>Block</tt> knows its parent block and its children in the
|
|
* dominator and postdominator trees. It also knows which blocks are in its
|
|
* dominance frontier and its postdominance frontier.
|
|
*
|
|
* @see FlowGraph
|
|
* @see DominatorTree
|
|
* @see DominanceFrontier
|
|
*/
|
|
public class Block extends GraphNode {
|
|
// There are several "types" of Blocks. A NON_HEADER block is not the
|
|
// header of a loop. An IRREDUCIBLE block is one of the headers of an
|
|
// irreducible loop. An irriducible loop has more than one entry
|
|
// point. They are very rare and are really ugly. The loop
|
|
// transformer tries to fix up mutiple headers. A REDUCIBLE header is
|
|
// a header for a reducible loop.
|
|
public static final int NON_HEADER = 0;
|
|
|
|
public static final int IRREDUCIBLE = 1;
|
|
|
|
public static final int REDUCIBLE = 2;
|
|
|
|
FlowGraph graph; // CFG to which this Block belongs
|
|
|
|
Label label; // This Block's Label
|
|
|
|
Tree tree; // Expression tree for this block
|
|
|
|
Block domParent; // Block that (immediately) dominates this Block
|
|
|
|
Block pdomParent;
|
|
|
|
Set domChildren; // Blocks that this Block dominates
|
|
|
|
Set pdomChildren; // The postdominator children of this block
|
|
|
|
Set domFrontier; // This Block's dominance frontier
|
|
|
|
Set pdomFrontier; // This Block's postdominace frontier
|
|
|
|
int blockType; // NON_HEADER, IRREDUCIBLE, or REDUCIBLE
|
|
|
|
Block header; // The block's loop header
|
|
|
|
StackOptimizer stackOptimizer; // Stack Optimizer
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param label
|
|
* The block's label. The label may be thought of as the line of
|
|
* code at which the block begins.
|
|
* @param graph
|
|
* The CFG containing the block.
|
|
*/
|
|
Block(final Label label, final FlowGraph graph) {
|
|
this.label = label;
|
|
this.graph = graph;
|
|
this.tree = null;
|
|
this.header = null;
|
|
this.blockType = Block.NON_HEADER;
|
|
|
|
label.setStartsBlock(true);
|
|
|
|
domParent = null;
|
|
pdomParent = null;
|
|
|
|
domChildren = new HashSet();
|
|
pdomChildren = new HashSet();
|
|
|
|
domFrontier = new HashSet();
|
|
pdomFrontier = new HashSet();
|
|
|
|
stackOptimizer = new StackOptimizer(this); // make StackOptimizer
|
|
// object
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns the stack optimizer for this block.
|
|
*
|
|
* @return The stack optimizer.
|
|
*/
|
|
public StackOptimizer stackOptimizer() {
|
|
return stackOptimizer;
|
|
}
|
|
|
|
/**
|
|
* Returns the expression tree for this block.
|
|
*
|
|
* @return The tree.
|
|
*/
|
|
public Tree tree() {
|
|
return tree;
|
|
}
|
|
|
|
/**
|
|
* Sets the expression tree for this block.
|
|
*/
|
|
public void setTree(final Tree tree) {
|
|
this.tree = tree;
|
|
}
|
|
|
|
/**
|
|
* Returns the CFG containing the block.
|
|
*
|
|
* @return The CFG.
|
|
*/
|
|
public FlowGraph graph() {
|
|
return graph;
|
|
}
|
|
|
|
/**
|
|
* Returns the label associated with this block.
|
|
*/
|
|
public Label label() {
|
|
return label;
|
|
}
|
|
|
|
/**
|
|
* Visits the expression tree contained in this block.
|
|
*/
|
|
public void visitChildren(final TreeVisitor visitor) {
|
|
if (tree != null) {
|
|
tree.visit(visitor);
|
|
}
|
|
}
|
|
|
|
public void visit(final TreeVisitor visitor) {
|
|
visitor.visitBlock(this);
|
|
}
|
|
|
|
/**
|
|
* Sets the type of this Block. A Block may have one of three types:
|
|
*
|
|
* <ul>
|
|
* <li><tt>NON_HEADER</tt>: Not the header of any loop
|
|
* <li><tt>IRREDUCIBLE</tt>: Header of an irreducible loop
|
|
* <li><tt>REDUCIBLE</tt>: Header of a reducible loop
|
|
* </ul>
|
|
*
|
|
* A <i>loop</i> is a strongly connected component of a control flow graph.
|
|
* A loop's <i>header</i> is the block that dominates all other blocks in
|
|
* the loop. A loop is <i>reducible</i> if the only way to enter the loop
|
|
* is through the header.
|
|
*/
|
|
void setBlockType(final int blockType) {
|
|
this.blockType = blockType;
|
|
|
|
if (FlowGraph.DEBUG) {
|
|
System.out.println(" Set block type " + this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the type of this Block.
|
|
*/
|
|
int blockType() {
|
|
return blockType;
|
|
}
|
|
|
|
public void setHeader(final Block header) {
|
|
this.header = header;
|
|
|
|
if (FlowGraph.DEBUG) {
|
|
System.out.println(" Set header " + this);
|
|
}
|
|
}
|
|
|
|
public Block header() {
|
|
return header;
|
|
}
|
|
|
|
/**
|
|
* Returns a string representation of this block.
|
|
*/
|
|
public String toString() {
|
|
String s = "<block " + label + " hdr=";
|
|
|
|
if (header != null) {
|
|
s += header.label();
|
|
} else {
|
|
s += "null";
|
|
}
|
|
|
|
switch (blockType) {
|
|
case NON_HEADER:
|
|
break;
|
|
case IRREDUCIBLE:
|
|
s += " irred";
|
|
break;
|
|
case REDUCIBLE:
|
|
s += " red";
|
|
break;
|
|
}
|
|
|
|
if (this == graph.source()) {
|
|
return s + " source>";
|
|
} else if (this == graph.init()) {
|
|
return s + " init>";
|
|
} else if (this == graph.sink()) {
|
|
return s + " sink>";
|
|
} else {
|
|
return s + ">";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the basic blocks that this Block immediately dominates. That is,
|
|
* it returns this Block's children in the dominator tree for the CFG.
|
|
*/
|
|
Collection domChildren() {
|
|
return domChildren;
|
|
}
|
|
|
|
/**
|
|
* Returns the immediate dominator of this Block. That is, it returns the
|
|
* Block's parent in the dominator tree, its immediate dominator.
|
|
*/
|
|
Block domParent() {
|
|
return domParent;
|
|
}
|
|
|
|
/**
|
|
* Specifies that Block dominates this Block (parent in the dominator tree,
|
|
* the immediate dominator).
|
|
*
|
|
* @param block
|
|
* Block that dominates this Block.
|
|
*/
|
|
void setDomParent(final Block block) {
|
|
// If this Block already had a dominator specified, remove
|
|
// it from its dominator's children.
|
|
if (domParent != null) {
|
|
domParent.domChildren.remove(this);
|
|
}
|
|
|
|
domParent = block;
|
|
|
|
// Add this Block to its new dominator's children.
|
|
if (domParent != null) {
|
|
domParent.domChildren.add(this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns whether or this Block dominates another given Block. A node X
|
|
* dominates a node Y when every path from the first node in the CFG (Enter)
|
|
* to Y must pass through X.
|
|
*/
|
|
public boolean dominates(final Block block) {
|
|
Block p = block;
|
|
|
|
while (p != null) {
|
|
if (p == this) {
|
|
return true;
|
|
}
|
|
p = p.domParent();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns the children of this Block in the CFG's postdominator tree.
|
|
*/
|
|
Collection pdomChildren() {
|
|
return pdomChildren;
|
|
}
|
|
|
|
/**
|
|
* Returns the parent of this Block in the CFG's postdominator tree.
|
|
*/
|
|
Block pdomParent() {
|
|
return pdomParent;
|
|
}
|
|
|
|
/**
|
|
* Sets this Block's parent in the postdominator tree.
|
|
*/
|
|
void setPdomParent(final Block block) {
|
|
if (pdomParent != null) {
|
|
pdomParent.pdomChildren.remove(this);
|
|
}
|
|
|
|
pdomParent = block;
|
|
|
|
if (pdomParent != null) {
|
|
pdomParent.pdomChildren.add(this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determines whether or not this block postdominates a given block. A block
|
|
* X is said to postdominate a block Y when every path from Y to the last
|
|
* node in the CFG (Exit) passes through X. This relationship can be thought
|
|
* of as the reverse of dominance. That is, X dominates Y in the reverse
|
|
* CFG.
|
|
*
|
|
* @see DominatorTree
|
|
*/
|
|
public boolean postdominates(final Block block) {
|
|
Block p = block;
|
|
|
|
while (p != null) {
|
|
if (p == this) {
|
|
return true;
|
|
}
|
|
p = p.pdomParent();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns the blocks that are in this block's dominance frontier. The
|
|
* dominance frontier of a node X in a CFG is the set of all nodes Y such
|
|
* that X dominates a predacessor of Y, but does not strictly dominate Y.
|
|
* Nodes in the dominance frontier always have more than one parent (a
|
|
* join).
|
|
*
|
|
* @see DominanceFrontier
|
|
*/
|
|
Collection domFrontier() {
|
|
Assert.isTrue(domFrontier != null);
|
|
return domFrontier;
|
|
}
|
|
|
|
/**
|
|
* Returns the postdominance frontier for this node. A postdominace frontier
|
|
* is essentially the same as a dominace frontier, but the postdominance
|
|
* relationship is used instead of the dominance relationship.
|
|
*/
|
|
Collection pdomFrontier() {
|
|
Assert.isTrue(pdomFrontier != null);
|
|
return pdomFrontier;
|
|
}
|
|
}
|
|
|