/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Common Public License (CPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/cpl1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.jikesrvm.compilers.opt;
import org.jikesrvm.compilers.opt.ir.OPT_BasicBlock;
import org.jikesrvm.compilers.opt.ir.OPT_IR;
import org.jikesrvm.compilers.opt.ir.OPT_Instruction;
import static org.jikesrvm.compilers.opt.ir.OPT_Operators.NULL_CHECK;
/**
* Dependence Graph Statistics
*
* (This module will only be used for experimental measurements, so
* compile-time overhead is less of a concern.)
*
* @see OPT_DepGraph
*/
class OPT_DepGraphStats {
/**
* The number of nodes in the dependence graph
*/
int numNodes;
/**
* The total volume (expected cycles) of work represented by nodes in
* the dependence graph.
*/
int totalTime;
/**
* The length of the critical path through the dependence graph
*/
int critPathLength;
static final boolean debug = false;
/**
* Create a statistical summary of a dependence graph for a given basic
* block.
*
* @param dg the dependence graph
* @param bbName name of the basic block
*/
OPT_DepGraphStats(OPT_DepGraph dg, String bbName) {
// First pass -- compute numNodes
int _numNodes = 0;
boolean containsLoadOrStore = false;
for (OPT_DepGraphNode n = (OPT_DepGraphNode) dg.firstNode(); n != null; n = (OPT_DepGraphNode) n.getNext()) {
_numNodes++;
OPT_Instruction instr = n.instruction();
if (instr.isImplicitStore() || instr.isImplicitLoad()) {
containsLoadOrStore = true;
}
}
OPT_DepGraphNode[] nodes = new OPT_DepGraphNode[_numNodes];
int[] ECT = new int[_numNodes]; // Earliest Completion Times
int _totalTime = 0;
int _critPathLength = 0;
// Second pass -- compute times
int i = 0;
for (OPT_DepGraphNode n = (OPT_DepGraphNode) dg.firstNode(); n != null; n = (OPT_DepGraphNode) n.getNext()) {
nodes[i] = n;
ECT[i] = 0;
for (OPT_DepGraphEdge e = (OPT_DepGraphEdge) n.firstInEdge(); e != null; e = (OPT_DepGraphEdge) e.getNextIn()) {
OPT_DepGraphNode pred = (OPT_DepGraphNode) e.fromNode();
// Look for pred in nodes[]
int j;
for (j = 0; j < i; j++) {
if (nodes[j] == pred) {
break;
}
}
if (j == i) {
// Not found
throw new OPT_OptimizingCompilerException("OPT_DepGraphStats: dep graph is not topologically sorted ???");
// NOTE: I could not use OPT_SortedGraphIterator
// for top sort because OPT_DepGraphNode
// is not a subclass of OPT_SortedGraphNode
}
// TODO: add edge latency also??
ECT[i] = Math.max(ECT[i], ECT[j]);
} // for ( e = ... )
OPT_Instruction instr = n.instruction();
int curTime = estimateExecutionTime(instr);
_totalTime += curTime;
ECT[i] += curTime;
_critPathLength = Math.max(_critPathLength, ECT[i]);
i++;
} // for ( n = ... )
System.out.println("@@@@ BB " +
bbName +
"; totalTime = " +
_totalTime +
"; containsLoadOrStore = " +
containsLoadOrStore +
"; critPathLength = " +
_critPathLength);
}
/**
* Print the dependence graph stats for all basic blocks in an IR.
* @param ir the IR
*/
static void printBasicBlockStatistics(OPT_IR ir) {
System.out.println();
System.out.println("**** START OF printBasicBlockStatistics() for method " + ir.method + " ****");
if (debug) {
ir.printInstructions();
}
// Performing live analysis may reduce dependences between PEIs and stores
if (ir.options.HANDLER_LIVENESS) {
new OPT_LiveAnalysis(false, false, true).perform(ir);
}
for (OPT_BasicBlock bb = ir.firstBasicBlockInCodeOrder(); bb != null; bb = bb.nextBasicBlockInCodeOrder()) {
//OPT_DepGraph dg =
new OPT_DepGraph(ir, bb.firstRealInstruction(), bb.lastRealInstruction(), bb);
}
System.out.println("**** END OF printBasicBlockStatistics() ****");
}
/**
* Return an estimate of the number of cycles for a given instruction.
* Currently, this estimate is comically simple.
* @param instr the instruction
*/
int estimateExecutionTime(OPT_Instruction instr) {
if (instr.operator() == NULL_CHECK) {
return 0;
} else {
return 1;
}
}
}