Fixed compilation errors, command-line argument declarations, cleaned up code to

look nicer and removed useless stuff.

Also renamed a few variables, moved them into namespaces, converted outputting
to a file into a print to std::cerr with a DEBUG() guard, as all passes should
do anyway.

No functional changes have been made. However, this code now compiles.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5769 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Misha Brukman 2003-04-10 19:19:23 +00:00
parent 8baa01c1d7
commit 2c821cc06e
8 changed files with 514 additions and 534 deletions

View File

@ -12,35 +12,41 @@
#include "llvm/Target/TargetSchedInfo.h"
#include "Support/StringExtras.h"
#include "Support/STLExtras.h"
#include "Support/hash_map"
#include "Support/Statistic.h"
#include "ModuloScheduling.h"
#include "ModuloSchedGraph.h"
#include <algorithm>
#include <ostream>
#include <vector>
// FIXME: Should be using #include <cmath>
#include <math.h>
//#include <swig.h>
#define UNIDELAY 1
extern std::ostream modSched_os;
extern ModuloSchedDebugLevel_t ModuloSchedDebugLevel;
//*********************** Internal Data Structures *************************/
// The following two types need to be classes, not typedefs, so we can use
// opaque declarations in SchedGraph.h
//
struct RefVec:public std::vector < std::pair < ModuloSchedGraphNode *, int >> {
struct RefVec:public std::vector<std::pair<ModuloSchedGraphNode*,int> > {
typedef std::vector<std::pair<ModuloSchedGraphNode*,
int> >::iterator iterator;
typedef std::vector<std::pair<ModuloSchedGraphNode*,
int> >::const_iterator const_iterator;
};
struct RegToRefVecMap:public std::hash_map < int, RefVec > {
typedef std::hash_map<int,RefVec>::iterator iterator;
typedef std::hash_map<int,RefVec>::const_iterator const_iterator;
struct RegToRefVecMap:public hash_map<int,RefVec> {
typedef hash_map<int,RefVec>::iterator iterator;
typedef hash_map<int,RefVec>::const_iterator const_iterator;
};
struct ValueToDefVecMap:public std::hash_map < const Instruction *, RefVec > {
typedef std::hash_map<const Instruction*, RefVec>::iterator iterator;
typedef std::hash_map<const Instruction*,
struct ValueToDefVecMap:public hash_map<const Instruction*,RefVec> {
typedef hash_map<const Instruction*, RefVec>::iterator iterator;
typedef hash_map<const Instruction*,
RefVec>::const_iterator const_iterator;
};
@ -603,21 +609,21 @@ SchedGraphEdge *ModuloSchedGraph::getMaxDelayEdge(unsigned srcId,
void ModuloSchedGraph::dumpCircuits()
{
modSched_os << "dumping circuits for graph: " << "\n";
DEBUG(std::cerr << "dumping circuits for graph:\n");
int j = -1;
while (circuits[++j][0] != 0) {
int k = -1;
while (circuits[j][++k] != 0)
modSched_os << circuits[j][k] << "\t";
modSched_os << "\n";
DEBUG(std::cerr << circuits[j][k] << "\t");
DEBUG(std::cerr << "\n");
}
}
void ModuloSchedGraph::dumpSet(std::vector < ModuloSchedGraphNode * >set)
{
for (unsigned i = 0; i < set.size(); i++)
modSched_os << set[i]->getNodeId() << "\t";
modSched_os << "\n";
DEBUG(std::cerr << set[i]->getNodeId() << "\t");
DEBUG(std::cerr << "\n");
}
std::vector<ModuloSchedGraphNode*>
@ -674,7 +680,7 @@ void ModuloSchedGraph::orderNodes() {
const BasicBlock *bb = bbVec[0];
unsigned numNodes = bb->size();
//first order all the sets
// first order all the sets
int j = -1;
int totalDelay = -1;
int preDelay = -1;
@ -691,7 +697,7 @@ void ModuloSchedGraph::orderNodes() {
totalDelay += edge->getMinDelay();
}
if (preDelay != -1 && totalDelay > preDelay) {
//swap circuits[j][] and cuicuits[j-1][]
// swap circuits[j][] and cuicuits[j-1][]
unsigned temp[MAXNODE];
for (int k = 0; k < MAXNODE; k++) {
temp[k] = circuits[j - 1][k];
@ -703,11 +709,11 @@ void ModuloSchedGraph::orderNodes() {
}
}
//build the first set
// build the first set
int backEdgeSrc;
int backEdgeSink;
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "building the first set" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "building the first set" << "\n");
int setSeq = -1;
int k = -1;
setSeq++;
@ -717,17 +723,17 @@ void ModuloSchedGraph::orderNodes() {
backEdgeSrc = circuits[setSeq][k - 1];
backEdgeSink = circuits[setSeq][0];
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "the first set is:";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "the first set is:");
dumpSet(set);
}
//implement the ordering algorithm
// implement the ordering algorithm
enum OrderSeq { bottom_up, top_down };
OrderSeq order;
std::vector<ModuloSchedGraphNode*> R;
while (!set.empty()) {
std::vector < ModuloSchedGraphNode * >pset = predSet(oNodes);
std::vector < ModuloSchedGraphNode * >sset = succSet(oNodes);
std::vector<ModuloSchedGraphNode*> pset = predSet(oNodes);
std::vector<ModuloSchedGraphNode*> sset = succSet(oNodes);
if (!pset.empty() && !vectorConj(pset, set).empty()) {
R = vectorConj(pset, set);
@ -751,8 +757,8 @@ void ModuloSchedGraph::orderNodes() {
while (!R.empty()) {
if (order == top_down) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "in top_down round" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "in top_down round\n");
while (!R.empty()) {
int maxHeight = -1;
NodeVec::iterator chosenI;
@ -795,8 +801,8 @@ void ModuloSchedGraph::orderNodes() {
order = bottom_up;
R = vectorConj(predSet(oNodes), set);
} else {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "in bottom up round" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "in bottom up round\n");
while (!R.empty()) {
int maxDepth = -1;
NodeVec::iterator chosenI;
@ -822,17 +828,17 @@ void ModuloSchedGraph::orderNodes() {
R = vectorConj(succSet(oNodes), set);
}
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "order finished" << "\n";
modSched_os << "dumping the ordered nodes: " << "\n";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "order finished\n");
DEBUG(std::cerr << "dumping the ordered nodes:\n");
dumpSet(oNodes);
dumpCircuits();
}
//create a new set
//FIXME: the nodes between onodes and this circuit should also be include in
//this set
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "building the next set" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "building the next set\n");
set.clear();
int k = -1;
setSeq++;
@ -845,9 +851,8 @@ void ModuloSchedGraph::orderNodes() {
if (set.empty()) {
//no circuits any more
//collect all other nodes
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "no circuits any more, collect the rest nodes" <<
"\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "no circuits any more, collect the rest nodes\n");
for (unsigned i = 2; i < numNodes + 2; i++) {
bool inset = false;
for (unsigned j = 0; j < oNodes.size(); j++)
@ -859,8 +864,8 @@ void ModuloSchedGraph::orderNodes() {
set.push_back(getNode(i));
}
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "next set is: " << "\n";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "next set is:\n");
dumpSet(set);
}
} //while(!set.empty())
@ -869,9 +874,6 @@ void ModuloSchedGraph::orderNodes() {
void ModuloSchedGraph::buildGraph(const TargetMachine & target)
{
const BasicBlock *bb = bbVec[0];
@ -888,7 +890,7 @@ void ModuloSchedGraph::buildGraph(const TargetMachine & target)
// We use this to add memory dependence edges without a second full walk.
//
// vector<const Instruction*> memVec;
std::vector < ModuloSchedGraphNode * >memNodeVec;
std::vector<ModuloSchedGraphNode*> memNodeVec;
// Use this data structure to note any uses or definitions of
// machine registers so we can add edges for those later without
@ -900,8 +902,6 @@ void ModuloSchedGraph::buildGraph(const TargetMachine & target)
//
RegToRefVecMap regToRefVecMap;
// Make a dummy root node. We'll add edges to the real roots later.
graphRoot = new ModuloSchedGraphNode(0, NULL, NULL, -1, target);
graphLeaf = new ModuloSchedGraphNode(1, NULL, NULL, -1, target);
@ -919,11 +919,11 @@ void ModuloSchedGraph::buildGraph(const TargetMachine & target)
//dump only the blocks which are from loops
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
this->dump(bb);
if (!isLoop(bb)) {
modSched_os << " dumping non-loop BB:\n";
DEBUG(std::cerr << " dumping non-loop BB:\n");
dump(bb);
}
if (isLoop(bb)) {
@ -937,21 +937,21 @@ void ModuloSchedGraph::buildGraph(const TargetMachine & target)
//this->dump();
int ResII = this->computeResII(bb);
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "ResII is " << ResII << "\n";;
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "ResII is " << ResII << "\n");
int RecII = this->computeRecII(bb);
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "RecII is " << RecII << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "RecII is " << RecII << "\n");
this->MII = std::max(ResII, RecII);
this->computeNodeProperty(bb);
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
this->dumpNodeProperty();
this->orderNodes();
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
this->dump();
//this->instrScheduling();
@ -974,7 +974,6 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
//os<<"begining computerRecII()"<<"\n";
//FIXME: only deal with circuits starting at the first node: the phi node
//nodeId=2;
@ -984,7 +983,6 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
unsigned path[MAXNODE];
unsigned stack[MAXNODE][MAXNODE];
for (int j = 0; j < MAXNODE; j++) {
path[j] = 0;
for (int k = 0; k < MAXNODE; k++)
@ -1004,19 +1002,19 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
while (currentNode != NULL) {
unsigned currentNodeId = currentNode->getNodeId();
// modSched_os<<"current node is "<<currentNodeId<<"\n";
// DEBUG(std::cerr<<"current node is "<<currentNodeId<<"\n");
ModuloSchedGraphNode *nextNode = NULL;
for (ModuloSchedGraphNode::const_iterator I =
currentNode->beginOutEdges(), E = currentNode->endOutEdges();
I != E; I++) {
//modSched_os <<" searching in outgoint edges of node
//DEBUG(std::cerr <<" searching in outgoint edges of node
//"<<currentNodeId<<"\n";
unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
bool inpath = false, instack = false;
int k;
//modSched_os<<"nodeId is "<<nodeId<<"\n";
//DEBUG(std::cerr<<"nodeId is "<<nodeId<<"\n");
k = -1;
while (path[++k] != 0)
@ -1040,7 +1038,7 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
}
if (nextNode != NULL) {
//modSched_os<<"find the next Node "<<nextNode->getNodeId()<<"\n";
//DEBUG(std::cerr<<"find the next Node "<<nextNode->getNodeId()<<"\n");
int j = 0;
while (stack[i][j] != 0)
@ -1051,7 +1049,7 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
path[i] = nextNode->getNodeId();
currentNode = nextNode;
} else {
//modSched_os<<"no expansion any more"<<"\n";
//DEBUG(std::cerr<<"no expansion any more"<<"\n");
//confirmCircuit();
for (ModuloSchedGraphNode::const_iterator I =
currentNode->beginOutEdges(), E = currentNode->endOutEdges();
@ -1077,16 +1075,16 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
}
if (i == 0) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "circuits found are: " << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "circuits found are:\n");
int j = -1;
while (circuits[++j][0] != 0) {
int k = -1;
while (circuits[j][++k] != 0)
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << circuits[j][k] << "\t";
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << circuits[j][k] << "\t");
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "\n");
//for this circuit, compute the sum of all edge delay
int sumDelay = 0;
@ -1115,9 +1113,9 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
// assume we have distance 1, in this case the sumDelay is RecII
// this is correct for SSA form only
//
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "The total Delay in the circuit is " << sumDelay
<< "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "The total Delay in the circuit is " << sumDelay
<< "\n");
RecII = RecII > sumDelay ? RecII : sumDelay;
@ -1133,7 +1131,7 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
void ModuloSchedGraph::addResourceUsage(std::vector<std::pair<int,int> > &ruVec,
int rid)
{
//modSched_os<<"\nadding a resouce , current resouceUsage vector size is
//DEBUG(std::cerr<<"\nadding a resouce , current resouceUsage vector size is
//"<<ruVec.size()<<"\n";
bool alreadyExists = false;
for (unsigned i = 0; i < ruVec.size(); i++) {
@ -1145,26 +1143,26 @@ void ModuloSchedGraph::addResourceUsage(std::vector<std::pair<int,int> > &ruVec,
}
if (!alreadyExists)
ruVec.push_back(std::make_pair(rid, 1));
//modSched_os<<"current resouceUsage vector size is "<<ruVec.size()<<"\n";
//DEBUG(std::cerr<<"current resouceUsage vector size is "<<ruVec.size()<<"\n";
}
void ModuloSchedGraph::dumpResourceUsage(std::vector<std::pair<int,int> > &ru)
{
TargetSchedInfo & msi = (TargetSchedInfo &) target.getSchedInfo();
std::vector<std::pair<int,int>> resourceNumVector = msi.resourceNumVector;
modSched_os << "resourceID\t" << "resourceNum" << "\n";
std::vector<std::pair<int,int> > resourceNumVector = msi.resourceNumVector;
DEBUG(std::cerr << "resourceID\t" << "resourceNum\n");
for (unsigned i = 0; i < resourceNumVector.size(); i++)
modSched_os << resourceNumVector[i].
first << "\t" << resourceNumVector[i].second << "\n";
DEBUG(std::cerr << resourceNumVector[i].
first << "\t" << resourceNumVector[i].second << "\n");
modSched_os << " maxNumIssueTotal(issue slot in one cycle) = " << msi.
maxNumIssueTotal << "\n";
modSched_os << "resourceID\t resourceUsage\t ResourceNum" << "\n";
DEBUG(std::cerr << " maxNumIssueTotal(issue slot in one cycle) = " << msi.
maxNumIssueTotal << "\n");
DEBUG(std::cerr << "resourceID\t resourceUsage\t ResourceNum\n");
for (unsigned i = 0; i < ru.size(); i++) {
modSched_os << ru[i].first << "\t" << ru[i].second;
DEBUG(std::cerr << ru[i].first << "\t" << ru[i].second);
const unsigned resNum = msi.getCPUResourceNum(ru[i].first);
modSched_os << "\t" << resNum << "\n";
DEBUG(std::cerr << "\t" << resNum << "\n");
}
}
@ -1175,7 +1173,7 @@ int ModuloSchedGraph::computeResII(const BasicBlock * bb)
const TargetSchedInfo & msi = target.getSchedInfo();
int ResII;
std::vector<std::pair<int,int>> resourceUsage;
std::vector<std::pair<int,int> > resourceUsage;
//pair<int resourceid, int resourceUsageTimes_in_the_whole_block>
//FIXME: number of functional units the target machine can provide should be
@ -1183,15 +1181,15 @@ int ModuloSchedGraph::computeResII(const BasicBlock * bb)
for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
I++) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "machine instruction for llvm instruction( node " <<
getGraphNodeForInst(I)->getNodeId() << ")" << "\n";
modSched_os << "\t" << *I;
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "machine instruction for llvm instruction( node " <<
getGraphNodeForInst(I)->getNodeId() << ")\n");
DEBUG(std::cerr << "\t" << *I);
}
MachineCodeForInstruction & tempMvec =
MachineCodeForInstruction::get(I);
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "size =" << tempMvec.size() << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "size =" << tempMvec.size() << "\n");
for (unsigned i = 0; i < tempMvec.size(); i++) {
MachineInstr *minstr = tempMvec[i];
@ -1201,27 +1199,27 @@ int ModuloSchedGraph::computeResII(const BasicBlock * bb)
msi.getClassRUsage(mii.getSchedClass(minstr->getOpCode()));
unsigned totCycles = classRUsage.totCycles;
std::vector<std::vector<resourceId_t>> resources =rUsage.resourcesByCycle;
std::vector<std::vector<resourceId_t> > resources=rUsage.resourcesByCycle;
assert(totCycles == resources.size());
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "resources Usage for this Instr(totCycles=" <<
totCycles << ",mindLatency=" << mii.minLatency(minstr->
getOpCode()) <<
"): " << *minstr << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "resources Usage for this Instr(totCycles="
<< totCycles << ",mindLatency="
<< mii.minLatency(minstr->getOpCode()) << "): " << *minstr
<< "\n");
for (unsigned j = 0; j < resources.size(); j++) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "cycle " << j << ": ";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "cycle " << j << ": ");
for (unsigned k = 0; k < resources[j].size(); k++) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "\t" << resources[j][k];
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "\t" << resources[j][k]);
addResourceUsage(resourceUsage, resources[j][k]);
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "\n");
}
}
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
this->dumpResourceUsage(resourceUsage);
//compute ResII
@ -1240,8 +1238,8 @@ int ModuloSchedGraph::computeResII(const BasicBlock * bb)
return ResII;
}
ModuloSchedGraphSet::ModuloSchedGraphSet(const Function * function,
const TargetMachine & target)
ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *function,
const TargetMachine &target)
: method(function)
{
buildGraphsForMethod(method, target);
@ -1257,20 +1255,20 @@ ModuloSchedGraphSet::~ModuloSchedGraphSet()
void ModuloSchedGraphSet::dump() const
{
modSched_os << " ====== ModuloSched graphs for function `" <<
method->getName() << "' =========\n\n";
DEBUG(std::cerr << " ====== ModuloSched graphs for function `" <<
method->getName() << "' =========\n\n");
for (const_iterator I = begin(); I != end(); ++I)
(*I)->dump();
modSched_os << "\n=========End graphs for funtion` " << method->getName()
<< "' ==========\n\n";
DEBUG(std::cerr << "\n=========End graphs for function `" << method->getName()
<< "' ==========\n\n");
}
void ModuloSchedGraph::dump(const BasicBlock * bb)
{
modSched_os << "dumping basic block:";
modSched_os << (bb->hasName()? bb->getName() : "block")
<< " (" << bb << ")" << "\n";
DEBUG(std::cerr << "dumping basic block:");
DEBUG(std::cerr << (bb->hasName()? bb->getName() : "block")
<< " (" << bb << ")" << "\n");
}
@ -1283,27 +1281,27 @@ void ModuloSchedGraph::dump(const BasicBlock * bb, std::ostream & os)
void ModuloSchedGraph::dump() const
{
modSched_os << " ModuloSchedGraph for basic Blocks:";
DEBUG(std::cerr << " ModuloSchedGraph for basic Blocks:");
for (unsigned i = 0, N = bbVec.size(); i < N; i++) {
modSched_os << (bbVec[i]->hasName()? bbVec[i]->getName() : "block")
<< " (" << bbVec[i] << ")" << ((i == N - 1) ? "" : ", ");
DEBUG(std::cerr << (bbVec[i]->hasName()? bbVec[i]->getName() : "block")
<< " (" << bbVec[i] << ")" << ((i == N - 1) ? "" : ", "));
}
modSched_os << "\n\n Actual Root nodes : ";
DEBUG(std::cerr << "\n\n Actual Root nodes : ");
for (unsigned i = 0, N = graphRoot->outEdges.size(); i < N; i++)
modSched_os << graphRoot->outEdges[i]->getSink()->getNodeId()
<< ((i == N - 1) ? "" : ", ");
DEBUG(std::cerr << graphRoot->outEdges[i]->getSink()->getNodeId()
<< ((i == N - 1) ? "" : ", "));
modSched_os << "\n Graph Nodes:\n";
DEBUG(std::cerr << "\n Graph Nodes:\n");
//for (const_iterator I=begin(); I != end(); ++I)
//modSched_os << "\n" << *I->second;
//DEBUG(std::cerr << "\n" << *I->second;
unsigned numNodes = bbVec[0]->size();
for (unsigned i = 2; i < numNodes + 2; i++) {
ModuloSchedGraphNode *node = getNode(i);
modSched_os << "\n" << *node;
DEBUG(std::cerr << "\n" << *node);
}
modSched_os << "\n";
DEBUG(std::cerr << "\n");
}
void ModuloSchedGraph::dumpNodeProperty() const
@ -1312,13 +1310,12 @@ void ModuloSchedGraph::dumpNodeProperty() const
unsigned numNodes = bb->size();
for (unsigned i = 2; i < numNodes + 2; i++) {
ModuloSchedGraphNode *node = getNode(i);
modSched_os << "NodeId " << node->getNodeId() << "\t";
modSched_os << "ASAP " << node->getASAP() << "\t";
modSched_os << "ALAP " << node->getALAP() << "\t";
modSched_os << "mov " << node->getMov() << "\t";
modSched_os << "depth " << node->getDepth() << "\t";
modSched_os << "height " << node->getHeight() << "\t";
modSched_os << "\n";
DEBUG(std::cerr << "NodeId " << node->getNodeId() << "\t");
DEBUG(std::cerr << "ASAP " << node->getASAP() << "\t");
DEBUG(std::cerr << "ALAP " << node->getALAP() << "\t");
DEBUG(std::cerr << "mov " << node->getMov() << "\t");
DEBUG(std::cerr << "depth " << node->getDepth() << "\t");
DEBUG(std::cerr << "height " << node->getHeight() << "\t\n");
}
}

View File

@ -13,17 +13,10 @@
#include "llvm/Target/TargetInstrInfo.h"
#include "Support/HashExtras.h"
#include "Support/GraphTraits.h"
#include "Support/hash_map"
#include "../InstrSched/SchedGraphCommon.h"
#include <iostream>
//for debug information selecton
enum ModuloSchedDebugLevel_t {
ModuloSched_NoDebugInfo,
ModuloSched_Disable,
ModuloSched_PrintSchedule,
ModuloSched_PrintScheduleProcess,
};
//===----------------------------------------------------------------------===//
// ModuloSchedGraphNode - Implement a data structure based on the
// SchedGraphNodeCommon this class stores informtion needed later to order the
@ -160,20 +153,20 @@ private:
typedef std::vector<ModuloSchedGraphNode*> NodeVec;
//the function to compute properties
void computeNodeASAP(const BasicBlock * bb);
void computeNodeALAP(const BasicBlock * bb);
void computeNodeMov(const BasicBlock * bb);
void computeNodeDepth(const BasicBlock * bb);
void computeNodeHeight(const BasicBlock * bb);
void computeNodeASAP(const BasicBlock *bb);
void computeNodeALAP(const BasicBlock *bb);
void computeNodeMov(const BasicBlock *bb);
void computeNodeDepth(const BasicBlock *bb);
void computeNodeHeight(const BasicBlock *bb);
//the function to compute node property
void computeNodeProperty(const BasicBlock * bb);
void computeNodeProperty(const BasicBlock *bb);
//the function to sort nodes
void orderNodes();
//add the resource usage
void addResourceUsage(std::vector<pair<int,int>>&, int);
void addResourceUsage(std::vector<std::pair<int,int> > &, int);
//debug functions:
//dump circuits
@ -181,7 +174,7 @@ void addResourceUsage(std::vector<pair<int,int>>&, int);
//dump the input set of nodes
void dumpSet(std::vector<ModuloSchedGraphNode*> set);
//dump the input resource usage table
void dumpResourceUsage(std::vector<pair<int,int>> &);
void dumpResourceUsage(std::vector<std::pair<int,int> > &);
public:
//help functions
@ -195,16 +188,16 @@ public:
NodeVec predSet(NodeVec set);
//get the predessor set of the node
NodeVec predSet(ModuloSchedGraphNode * node, unsigned, unsigned);
NodeVec predSet(ModuloSchedGraphNode * node);
NodeVec predSet(ModuloSchedGraphNode *node, unsigned, unsigned);
NodeVec predSet(ModuloSchedGraphNode *node);
//get the successor set of the set
NodeVec succSet(NodeVec set, unsigned, unsigned);
NodeVec succSet(NodeVec set);
//get the succssor set of the node
NodeVec succSet(ModuloSchedGraphNode * node, unsigned, unsigned);
NodeVec succSet(ModuloSchedGraphNode * node);
NodeVec succSet(ModuloSchedGraphNode *node, unsigned, unsigned);
NodeVec succSet(ModuloSchedGraphNode *node);
//return the uniton of the two vectors
NodeVec vectorUnion(NodeVec set1, NodeVec set2);
@ -248,17 +241,22 @@ public:
//return this basibBlock contains a loop
bool isLoop();
//return the node for the input instruction
ModuloSchedGraphNode *getGraphNodeForInst(const Instruction * inst) const {
const_iterator onePair = this->find(inst);
return (onePair != this->end()) ? (*onePair).second : NULL;
}
//Debugging support//dump the graph void dump() const;
//dump the basicBlock
// Debugging support
//dump the graph
void dump() const;
// dump the basicBlock
void dump(const BasicBlock * bb);
//dump the basicBlock into 'os' stream
void dump(const BasicBlock * bb, std::ostream & os);
//dump the node property
void dumpNodeProperty() const;
@ -267,7 +265,8 @@ private:
public:
ModuloSchedGraph(const BasicBlock *bb, const TargetMachine &_target)
:SchedGraphCommon(bb), target(_target) {
:SchedGraphCommon(bb), target(_target)
{
buildGraph(target);
}
@ -276,8 +275,8 @@ public:
delete I->second;
}
//unorder iterators
//return values are pair<const Instruction*, ModuloSchedGraphNode*>
// Unorder iterators
// return values are pair<const Instruction*, ModuloSchedGraphNode*>
using map_base::begin;
using map_base::end;
@ -348,8 +347,8 @@ public:
using baseVector::begin;
using baseVector::end;
// Debugging support
void dump() const;
// Debugging support
void dump() const;
private:
void addGraph(ModuloSchedGraph *graph) {
@ -360,6 +359,6 @@ private:
// Graph builder
void buildGraphsForMethod(const Function *F,
const TargetMachine &target);
}
};
#endif

View File

@ -19,6 +19,7 @@
#include "llvm/Target/TargetSchedInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "Support/CommandLine.h"
#include "Support/Statistic.h"
#include "ModuloSchedGraph.h"
#include "ModuloScheduling.h"
#include <algorithm>
@ -34,29 +35,26 @@
// see ModuloSchedulingPass::runOnFunction()
//************************************************************
ModuloSchedDebugLevel_t ModuloSchedDebugLevel;
static cl::opt<ModuloSchedDebugLevel_t,true>
SDL_opt("modsched", cl::Hidden, cl::location(ModuloSchedDebugLevel),
cl::desc("enable modulo scheduling debugging information"),
cl::values(clEnumValN
(ModuloSched_NoDebugInfo, "n", "disable debug output"),
clEnumValN(ModuloSched_Disable, "off",
"disable modulo scheduling"),
clEnumValN(ModuloSched_PrintSchedule, "psched",
"print original and new schedule"),
clEnumValN(ModuloSched_PrintScheduleProcess, "pschedproc",
"print how the new schdule is produced"), 0));
std::filebuf modSched_fb;
std::ostream modSched_os(&modSched_fb);
namespace {
cl::opt<ModuloScheduling::DebugLevel_t,true>
SDL_opt("modsched", cl::Hidden, cl::location(ModuloScheduling::DebugLevel),
cl::desc("enable modulo scheduling debugging information"),
cl::values(clEnumValN(ModuloScheduling::DebugLevel_NoDebugInfo,
"none", "disable debug output"),
clEnumValN(ModuloScheduling::DebugLevel_PrintSchedule,
"psched", "print original and new schedule"),
clEnumValN(ModuloScheduling::DebugLevel_PrintScheduleProcess,
"pschedproc",
"print how the new schdule is produced"),
0));
}
// Computes the schedule and inserts epilogue and prologue
//
void ModuloScheduling::instrScheduling()
{
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "*************** computing modulo schedule **************\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "************ computing modulo schedule ***********\n");
const TargetSchedInfo & msi = target.getSchedInfo();
@ -74,13 +72,13 @@ void ModuloScheduling::instrScheduling()
if (!success) {
II++;
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "increase II to " << II << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "increase II to " << II << "\n");
}
}
//print the final schedule if necessary
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule)
if (ModuloScheduling::printSchedule())
dumpScheduling();
//the schedule has been computed
@ -90,8 +88,8 @@ void ModuloScheduling::instrScheduling()
BasicBlock *succ_bb = getSuccBB(bb);
//print the original BasicBlock if necessary
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule) {
modSched_os << "dumping the orginal block\n";
if (ModuloScheduling::printSchedule()) {
DEBUG(std::cerr << "dumping the orginal block\n");
graph.dump(bb);
}
//construction of prologue, kernel and epilogue
@ -109,12 +107,12 @@ void ModuloScheduling::instrScheduling()
constructEpilogue(epilogue, succ_bb);
//print the BasicBlocks if necessary
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule) {
modSched_os << "dumping the prologue block:\n";
if (ModuloScheduling::printSchedule()) {
DEBUG(std::cerr << "dumping the prologue block:\n");
graph.dump(prologue);
modSched_os << "dumping the kernel block\n";
DEBUG(std::cerr << "dumping the kernel block\n");
graph.dump(kernel);
modSched_os << "dumping the epilogue block\n";
DEBUG(std::cerr << "dumping the epilogue block\n");
graph.dump(epilogue);
}
}
@ -125,11 +123,10 @@ void ModuloScheduling::clearInitMem(const TargetSchedInfo & msi)
{
unsigned numIssueSlots = msi.maxNumIssueTotal;
// clear nodeScheduled from the last round
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "***** new round with II= " << II <<
" *******************\n";
modSched_os <<
" ************clear the vector nodeScheduled*************\n";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "***** new round with II= " << II << " ***********\n");
DEBUG(std::cerr <<
" ************clear the vector nodeScheduled*************\n");
}
nodeScheduled.clear();
@ -158,13 +155,13 @@ void ModuloScheduling::clearInitMem(const TargetSchedInfo & msi)
bool ModuloScheduling::computeSchedule()
{
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "start to compute schedule\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "start to compute schedule\n");
// Loop over the ordered nodes
for (NodeVec::const_iterator I = oNodes.begin(); I != oNodes.end(); ++I) {
// Try to schedule for node I
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
dumpScheduling();
ModuloSchedGraphNode *node = *I;
@ -255,8 +252,8 @@ bool ModuloScheduling::computeSchedule()
endTime = node->getEarlyStart() + II - 1;
}
//try to schedule this node based on the startTime and endTime
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "scheduling the node " << (*I)->getNodeId() << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "scheduling the node " << (*I)->getNodeId() << "\n");
bool success =
this->ScheduleNode(node, startTime, endTime, nodeScheduled);
@ -337,10 +334,9 @@ BasicBlock *ModuloScheduling::getPredBB(BasicBlock *bb)
//
void ModuloScheduling::constructPrologue(BasicBlock *prologue)
{
InstListType & prologue_ist = prologue->getInstList();
vvNodeType & tempSchedule_prologue =
*(new vector < std::vector < ModuloSchedGraphNode * >>(schedule));
*(new std::vector<std::vector<ModuloSchedGraphNode*> >(schedule));
//compute the schedule for prologue
unsigned round = 0;
@ -395,7 +391,6 @@ void ModuloScheduling::constructKernel(BasicBlock *prologue,
BasicBlock *kernel,
BasicBlock *epilogue)
{
//*************fill instructions in the kernel****************
InstListType & kernel_ist = kernel->getInstList();
BranchInst *brchInst;
@ -472,8 +467,8 @@ void ModuloScheduling::constructEpilogue(BasicBlock *epilogue,
{
//compute the schedule for epilogue
vvNodeType & tempSchedule_epilogue =
*(new vector < std::vector < ModuloSchedGraphNode * >>(schedule));
vvNodeType &tempSchedule_epilogue =
*(new std::vector<std::vector<ModuloSchedGraphNode*> >(schedule));
unsigned scheduleSize = schedule.size();
int round = 0;
while (round < ceil(1.0 * scheduleSize / II) - 1) {
@ -626,17 +621,17 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
const TargetSchedInfo & msi = target.getSchedInfo();
unsigned int numIssueSlots = msi.maxNumIssueTotal;
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "startTime= " << start << " endTime= " << end << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "startTime= " << start << " endTime= " << end << "\n");
bool isScheduled = false;
for (unsigned i = start; i <= end; i++) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << " now try cycle " << i << ":" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << " now try cycle " << i << ":" << "\n");
for (unsigned j = 0; j < numIssueSlots; j++) {
unsigned int core_i = i % II;
unsigned int core_j = j;
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "\t Trying slot " << j << "...........";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "\t Trying slot " << j << "...........");
//check the resouce table, make sure there is no resource conflicts
const Instruction *instr = node->getInst();
MachineCodeForInstruction & tempMvec =
@ -675,10 +670,9 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
}
}
if (!resourceConflict && !coreSchedule[core_i][core_j]) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << " OK!" << "\n";
modSched_os << "Node " << node->
getNodeId() << " is scheduleed." << "\n";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << " OK!" << "\n");
DEBUG(std::cerr << "Node " << node->getNodeId() << " scheduled.\n");
}
//schedule[i][j]=node;
while (schedule.size() <= i) {
@ -688,7 +682,7 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
newCycle->push_back(NULL);
schedule.push_back(*newCycle);
}
vector < ModuloSchedGraphNode * >::iterator startIterator;
std::vector<ModuloSchedGraphNode*>::iterator startIterator;
startIterator = schedule[i].begin();
schedule[i].insert(startIterator + j, node);
startIterator = schedule[i].begin();
@ -697,8 +691,8 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
//update coreSchedule
//coreSchedule[core_i][core_j]=node;
while (coreSchedule.size() <= core_i) {
std::vector < ModuloSchedGraphNode * >*newCycle =
new std::vector < ModuloSchedGraphNode * >();
std::vector<ModuloSchedGraphNode*> *newCycle =
new std::vector<ModuloSchedGraphNode*>();
for (unsigned k = 0; k < numIssueSlots; k++)
newCycle->push_back(NULL);
coreSchedule.push_back(*newCycle);
@ -715,11 +709,11 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
break;
} else if (coreSchedule[core_i][core_j]) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << " Slot not available " << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << " Slot not available\n");
} else {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << " Resource conflicts" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << " Resource conflicts\n");
}
}
if (isScheduled)
@ -804,12 +798,12 @@ bool ModuloScheduling::resourceTableNegative()
void ModuloScheduling::dumpResourceUsageTable()
{
modSched_os << "dumping resource usage table" << "\n";
DEBUG(std::cerr << "dumping resource usage table\n");
for (unsigned i = 0; i < resourceTable.size(); i++) {
for (unsigned j = 0; j < resourceTable[i].size(); j++)
modSched_os << resourceTable[i][j].
first << ":" << resourceTable[i][j].second << " ";
modSched_os << "\n";
DEBUG(std::cerr << resourceTable[i][j].first
<< ":" << resourceTable[i][j].second << " ");
DEBUG(std::cerr << "\n");
}
}
@ -825,18 +819,17 @@ void ModuloScheduling::dumpSchedule(vvNodeType thisSchedule)
const TargetSchedInfo & msi = target.getSchedInfo();
unsigned numIssueSlots = msi.maxNumIssueTotal;
for (unsigned i = 0; i < numIssueSlots; i++)
modSched_os << "\t#";
modSched_os << "\n";
DEBUG(std::cerr << "\t#");
DEBUG(std::cerr << "\n");
for (unsigned i = 0; i < thisSchedule.size(); i++) {
modSched_os << "cycle" << i << ": ";
DEBUG(std::cerr << "cycle" << i << ": ");
for (unsigned j = 0; j < thisSchedule[i].size(); j++)
if (thisSchedule[i][j] != NULL)
modSched_os << thisSchedule[i][j]->getNodeId() << "\t";
DEBUG(std::cerr << thisSchedule[i][j]->getNodeId() << "\t");
else
modSched_os << "\t";
modSched_os << "\n";
DEBUG(std::cerr << "\t");
DEBUG(std::cerr << "\n");
}
}
@ -849,34 +842,34 @@ void ModuloScheduling::dumpSchedule(vvNodeType thisSchedule)
void ModuloScheduling::dumpScheduling()
{
modSched_os << "dump schedule:" << "\n";
DEBUG(std::cerr << "dump schedule:" << "\n");
const TargetSchedInfo & msi = target.getSchedInfo();
unsigned numIssueSlots = msi.maxNumIssueTotal;
for (unsigned i = 0; i < numIssueSlots; i++)
modSched_os << "\t#";
modSched_os << "\n";
DEBUG(std::cerr << "\t#");
DEBUG(std::cerr << "\n");
for (unsigned i = 0; i < schedule.size(); i++) {
modSched_os << "cycle" << i << ": ";
DEBUG(std::cerr << "cycle" << i << ": ");
for (unsigned j = 0; j < schedule[i].size(); j++)
if (schedule[i][j] != NULL)
modSched_os << schedule[i][j]->getNodeId() << "\t";
DEBUG(std::cerr << schedule[i][j]->getNodeId() << "\t");
else
modSched_os << "\t";
modSched_os << "\n";
DEBUG(std::cerr << "\t");
DEBUG(std::cerr << "\n");
}
modSched_os << "dump coreSchedule:" << "\n";
DEBUG(std::cerr << "dump coreSchedule:" << "\n");
for (unsigned i = 0; i < numIssueSlots; i++)
modSched_os << "\t#";
modSched_os << "\n";
DEBUG(std::cerr << "\t#");
DEBUG(std::cerr << "\n");
for (unsigned i = 0; i < coreSchedule.size(); i++) {
modSched_os << "cycle" << i << ": ";
DEBUG(std::cerr << "cycle" << i << ": ");
for (unsigned j = 0; j < coreSchedule[i].size(); j++)
if (coreSchedule[i][j] != NULL)
modSched_os << coreSchedule[i][j]->getNodeId() << "\t";
DEBUG(std::cerr << coreSchedule[i][j]->getNodeId() << "\t");
else
modSched_os << "\t";
modSched_os << "\n";
DEBUG(std::cerr << "\t");
DEBUG(std::cerr << "\n");
}
}
@ -893,12 +886,15 @@ void ModuloScheduling::dumpScheduling()
namespace {
class ModuloSchedulingPass:public FunctionPass {
const TargetMachine & target;
const TargetMachine &target;
public:
ModuloSchedulingPass(const TargetMachine &T):target(T) {
} const char *getPassName() const {
ModuloSchedulingPass(const TargetMachine &T):target(T) {}
const char *getPassName() const {
return "Modulo Scheduling";
}
// getAnalysisUsage - We use LiveVarInfo...
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
//AU.addRequired(FunctionLiveVarInfo::ID);
@ -909,24 +905,9 @@ namespace {
bool ModuloSchedulingPass::runOnFunction(Function &F)
{
//if necessary , open the output for debug purpose
if (ModuloSchedDebugLevel == ModuloSched_Disable)
return false;
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule) {
modSched_fb.open("moduloSchedDebugInfo.output", std::ios::out);
modSched_os <<
"******************Modula Scheduling debug information****************"
<< "\n ";
}
ModuloSchedGraphSet *graphSet = new ModuloSchedGraphSet(&F, target);
ModuloSchedulingSet ModuloSchedulingSet(*graphSet);
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule)
modSched_fb.close();
return false;
}

View File

@ -60,19 +60,32 @@ public:
~ModuloScheduling() {};
///the method to compute schedule and instert epilogue and prologue
// for debug information selecton
enum DebugLevel_t {
DebugLevel_NoDebugInfo,
DebugLevel_PrintSchedule,
DebugLevel_PrintScheduleProcess,
};
static DebugLevel_t DebugLevel;
static bool printSchedule() { return DebugLevel >= DebugLevel_PrintSchedule; }
static bool printScheduleProcess() {
return DebugLevel >= DebugLevel_PrintScheduleProcess;
}
// The method to compute schedule and instert epilogue and prologue
void instrScheduling();
///debug functions:
///dump the schedule and core schedule
void
dumpScheduling();
// Debug functions:
// Dump the schedule and core schedule
void dumpScheduling();
///dump the input vector of nodes
//sch: the input vector of nodes
void dumpSchedule(std::vector<std::vector<ModuloSchedGraphNode*>> sch);
// Dump the input vector of nodes
// sch: the input vector of nodes
void dumpSchedule(std::vector<std::vector<ModuloSchedGraphNode*> > sch);
///dump the resource usage table
// Dump the resource usage table
void dumpResourceUsageTable();
//*******************internal functions*******************************
@ -94,13 +107,13 @@ private:
// update the resource table at the startCycle
// vec: the resouce usage
// startCycle: the start cycle the resouce usage is
void updateResourceTable(std::vector<std::vector<unsigned int>> vec,
void updateResourceTable(std::vector<std::vector<unsigned> > vec,
int startCycle);
// un-do the update in the resource table in the startCycle
// vec: the resouce usage
// startCycle: the start cycle the resouce usage is
void undoUpdateResourceTable(std::vector<vector<unsigned int>> vec,
void undoUpdateResourceTable(std::vector<std::vector<unsigned> > vec,
int startCycle);
// return whether the resourcetable has negative element

View File

@ -12,35 +12,41 @@
#include "llvm/Target/TargetSchedInfo.h"
#include "Support/StringExtras.h"
#include "Support/STLExtras.h"
#include "Support/hash_map"
#include "Support/Statistic.h"
#include "ModuloScheduling.h"
#include "ModuloSchedGraph.h"
#include <algorithm>
#include <ostream>
#include <vector>
// FIXME: Should be using #include <cmath>
#include <math.h>
//#include <swig.h>
#define UNIDELAY 1
extern std::ostream modSched_os;
extern ModuloSchedDebugLevel_t ModuloSchedDebugLevel;
//*********************** Internal Data Structures *************************/
// The following two types need to be classes, not typedefs, so we can use
// opaque declarations in SchedGraph.h
//
struct RefVec:public std::vector < std::pair < ModuloSchedGraphNode *, int >> {
struct RefVec:public std::vector<std::pair<ModuloSchedGraphNode*,int> > {
typedef std::vector<std::pair<ModuloSchedGraphNode*,
int> >::iterator iterator;
typedef std::vector<std::pair<ModuloSchedGraphNode*,
int> >::const_iterator const_iterator;
};
struct RegToRefVecMap:public std::hash_map < int, RefVec > {
typedef std::hash_map<int,RefVec>::iterator iterator;
typedef std::hash_map<int,RefVec>::const_iterator const_iterator;
struct RegToRefVecMap:public hash_map<int,RefVec> {
typedef hash_map<int,RefVec>::iterator iterator;
typedef hash_map<int,RefVec>::const_iterator const_iterator;
};
struct ValueToDefVecMap:public std::hash_map < const Instruction *, RefVec > {
typedef std::hash_map<const Instruction*, RefVec>::iterator iterator;
typedef std::hash_map<const Instruction*,
struct ValueToDefVecMap:public hash_map<const Instruction*,RefVec> {
typedef hash_map<const Instruction*, RefVec>::iterator iterator;
typedef hash_map<const Instruction*,
RefVec>::const_iterator const_iterator;
};
@ -603,21 +609,21 @@ SchedGraphEdge *ModuloSchedGraph::getMaxDelayEdge(unsigned srcId,
void ModuloSchedGraph::dumpCircuits()
{
modSched_os << "dumping circuits for graph: " << "\n";
DEBUG(std::cerr << "dumping circuits for graph:\n");
int j = -1;
while (circuits[++j][0] != 0) {
int k = -1;
while (circuits[j][++k] != 0)
modSched_os << circuits[j][k] << "\t";
modSched_os << "\n";
DEBUG(std::cerr << circuits[j][k] << "\t");
DEBUG(std::cerr << "\n");
}
}
void ModuloSchedGraph::dumpSet(std::vector < ModuloSchedGraphNode * >set)
{
for (unsigned i = 0; i < set.size(); i++)
modSched_os << set[i]->getNodeId() << "\t";
modSched_os << "\n";
DEBUG(std::cerr << set[i]->getNodeId() << "\t");
DEBUG(std::cerr << "\n");
}
std::vector<ModuloSchedGraphNode*>
@ -674,7 +680,7 @@ void ModuloSchedGraph::orderNodes() {
const BasicBlock *bb = bbVec[0];
unsigned numNodes = bb->size();
//first order all the sets
// first order all the sets
int j = -1;
int totalDelay = -1;
int preDelay = -1;
@ -691,7 +697,7 @@ void ModuloSchedGraph::orderNodes() {
totalDelay += edge->getMinDelay();
}
if (preDelay != -1 && totalDelay > preDelay) {
//swap circuits[j][] and cuicuits[j-1][]
// swap circuits[j][] and cuicuits[j-1][]
unsigned temp[MAXNODE];
for (int k = 0; k < MAXNODE; k++) {
temp[k] = circuits[j - 1][k];
@ -703,11 +709,11 @@ void ModuloSchedGraph::orderNodes() {
}
}
//build the first set
// build the first set
int backEdgeSrc;
int backEdgeSink;
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "building the first set" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "building the first set" << "\n");
int setSeq = -1;
int k = -1;
setSeq++;
@ -717,17 +723,17 @@ void ModuloSchedGraph::orderNodes() {
backEdgeSrc = circuits[setSeq][k - 1];
backEdgeSink = circuits[setSeq][0];
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "the first set is:";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "the first set is:");
dumpSet(set);
}
//implement the ordering algorithm
// implement the ordering algorithm
enum OrderSeq { bottom_up, top_down };
OrderSeq order;
std::vector<ModuloSchedGraphNode*> R;
while (!set.empty()) {
std::vector < ModuloSchedGraphNode * >pset = predSet(oNodes);
std::vector < ModuloSchedGraphNode * >sset = succSet(oNodes);
std::vector<ModuloSchedGraphNode*> pset = predSet(oNodes);
std::vector<ModuloSchedGraphNode*> sset = succSet(oNodes);
if (!pset.empty() && !vectorConj(pset, set).empty()) {
R = vectorConj(pset, set);
@ -751,8 +757,8 @@ void ModuloSchedGraph::orderNodes() {
while (!R.empty()) {
if (order == top_down) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "in top_down round" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "in top_down round\n");
while (!R.empty()) {
int maxHeight = -1;
NodeVec::iterator chosenI;
@ -795,8 +801,8 @@ void ModuloSchedGraph::orderNodes() {
order = bottom_up;
R = vectorConj(predSet(oNodes), set);
} else {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "in bottom up round" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "in bottom up round\n");
while (!R.empty()) {
int maxDepth = -1;
NodeVec::iterator chosenI;
@ -822,17 +828,17 @@ void ModuloSchedGraph::orderNodes() {
R = vectorConj(succSet(oNodes), set);
}
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "order finished" << "\n";
modSched_os << "dumping the ordered nodes: " << "\n";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "order finished\n");
DEBUG(std::cerr << "dumping the ordered nodes:\n");
dumpSet(oNodes);
dumpCircuits();
}
//create a new set
//FIXME: the nodes between onodes and this circuit should also be include in
//this set
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "building the next set" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "building the next set\n");
set.clear();
int k = -1;
setSeq++;
@ -845,9 +851,8 @@ void ModuloSchedGraph::orderNodes() {
if (set.empty()) {
//no circuits any more
//collect all other nodes
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "no circuits any more, collect the rest nodes" <<
"\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "no circuits any more, collect the rest nodes\n");
for (unsigned i = 2; i < numNodes + 2; i++) {
bool inset = false;
for (unsigned j = 0; j < oNodes.size(); j++)
@ -859,8 +864,8 @@ void ModuloSchedGraph::orderNodes() {
set.push_back(getNode(i));
}
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "next set is: " << "\n";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "next set is:\n");
dumpSet(set);
}
} //while(!set.empty())
@ -869,9 +874,6 @@ void ModuloSchedGraph::orderNodes() {
void ModuloSchedGraph::buildGraph(const TargetMachine & target)
{
const BasicBlock *bb = bbVec[0];
@ -888,7 +890,7 @@ void ModuloSchedGraph::buildGraph(const TargetMachine & target)
// We use this to add memory dependence edges without a second full walk.
//
// vector<const Instruction*> memVec;
std::vector < ModuloSchedGraphNode * >memNodeVec;
std::vector<ModuloSchedGraphNode*> memNodeVec;
// Use this data structure to note any uses or definitions of
// machine registers so we can add edges for those later without
@ -900,8 +902,6 @@ void ModuloSchedGraph::buildGraph(const TargetMachine & target)
//
RegToRefVecMap regToRefVecMap;
// Make a dummy root node. We'll add edges to the real roots later.
graphRoot = new ModuloSchedGraphNode(0, NULL, NULL, -1, target);
graphLeaf = new ModuloSchedGraphNode(1, NULL, NULL, -1, target);
@ -919,11 +919,11 @@ void ModuloSchedGraph::buildGraph(const TargetMachine & target)
//dump only the blocks which are from loops
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
this->dump(bb);
if (!isLoop(bb)) {
modSched_os << " dumping non-loop BB:\n";
DEBUG(std::cerr << " dumping non-loop BB:\n");
dump(bb);
}
if (isLoop(bb)) {
@ -937,21 +937,21 @@ void ModuloSchedGraph::buildGraph(const TargetMachine & target)
//this->dump();
int ResII = this->computeResII(bb);
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "ResII is " << ResII << "\n";;
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "ResII is " << ResII << "\n");
int RecII = this->computeRecII(bb);
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "RecII is " << RecII << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "RecII is " << RecII << "\n");
this->MII = std::max(ResII, RecII);
this->computeNodeProperty(bb);
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
this->dumpNodeProperty();
this->orderNodes();
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
this->dump();
//this->instrScheduling();
@ -974,7 +974,6 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
//os<<"begining computerRecII()"<<"\n";
//FIXME: only deal with circuits starting at the first node: the phi node
//nodeId=2;
@ -984,7 +983,6 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
unsigned path[MAXNODE];
unsigned stack[MAXNODE][MAXNODE];
for (int j = 0; j < MAXNODE; j++) {
path[j] = 0;
for (int k = 0; k < MAXNODE; k++)
@ -1004,19 +1002,19 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
while (currentNode != NULL) {
unsigned currentNodeId = currentNode->getNodeId();
// modSched_os<<"current node is "<<currentNodeId<<"\n";
// DEBUG(std::cerr<<"current node is "<<currentNodeId<<"\n");
ModuloSchedGraphNode *nextNode = NULL;
for (ModuloSchedGraphNode::const_iterator I =
currentNode->beginOutEdges(), E = currentNode->endOutEdges();
I != E; I++) {
//modSched_os <<" searching in outgoint edges of node
//DEBUG(std::cerr <<" searching in outgoint edges of node
//"<<currentNodeId<<"\n";
unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId();
bool inpath = false, instack = false;
int k;
//modSched_os<<"nodeId is "<<nodeId<<"\n";
//DEBUG(std::cerr<<"nodeId is "<<nodeId<<"\n");
k = -1;
while (path[++k] != 0)
@ -1040,7 +1038,7 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
}
if (nextNode != NULL) {
//modSched_os<<"find the next Node "<<nextNode->getNodeId()<<"\n";
//DEBUG(std::cerr<<"find the next Node "<<nextNode->getNodeId()<<"\n");
int j = 0;
while (stack[i][j] != 0)
@ -1051,7 +1049,7 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
path[i] = nextNode->getNodeId();
currentNode = nextNode;
} else {
//modSched_os<<"no expansion any more"<<"\n";
//DEBUG(std::cerr<<"no expansion any more"<<"\n");
//confirmCircuit();
for (ModuloSchedGraphNode::const_iterator I =
currentNode->beginOutEdges(), E = currentNode->endOutEdges();
@ -1077,16 +1075,16 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
}
if (i == 0) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "circuits found are: " << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "circuits found are:\n");
int j = -1;
while (circuits[++j][0] != 0) {
int k = -1;
while (circuits[j][++k] != 0)
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << circuits[j][k] << "\t";
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << circuits[j][k] << "\t");
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "\n");
//for this circuit, compute the sum of all edge delay
int sumDelay = 0;
@ -1115,9 +1113,9 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
// assume we have distance 1, in this case the sumDelay is RecII
// this is correct for SSA form only
//
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "The total Delay in the circuit is " << sumDelay
<< "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "The total Delay in the circuit is " << sumDelay
<< "\n");
RecII = RecII > sumDelay ? RecII : sumDelay;
@ -1133,7 +1131,7 @@ int ModuloSchedGraph::computeRecII(const BasicBlock *bb)
void ModuloSchedGraph::addResourceUsage(std::vector<std::pair<int,int> > &ruVec,
int rid)
{
//modSched_os<<"\nadding a resouce , current resouceUsage vector size is
//DEBUG(std::cerr<<"\nadding a resouce , current resouceUsage vector size is
//"<<ruVec.size()<<"\n";
bool alreadyExists = false;
for (unsigned i = 0; i < ruVec.size(); i++) {
@ -1145,26 +1143,26 @@ void ModuloSchedGraph::addResourceUsage(std::vector<std::pair<int,int> > &ruVec,
}
if (!alreadyExists)
ruVec.push_back(std::make_pair(rid, 1));
//modSched_os<<"current resouceUsage vector size is "<<ruVec.size()<<"\n";
//DEBUG(std::cerr<<"current resouceUsage vector size is "<<ruVec.size()<<"\n";
}
void ModuloSchedGraph::dumpResourceUsage(std::vector<std::pair<int,int> > &ru)
{
TargetSchedInfo & msi = (TargetSchedInfo &) target.getSchedInfo();
std::vector<std::pair<int,int>> resourceNumVector = msi.resourceNumVector;
modSched_os << "resourceID\t" << "resourceNum" << "\n";
std::vector<std::pair<int,int> > resourceNumVector = msi.resourceNumVector;
DEBUG(std::cerr << "resourceID\t" << "resourceNum\n");
for (unsigned i = 0; i < resourceNumVector.size(); i++)
modSched_os << resourceNumVector[i].
first << "\t" << resourceNumVector[i].second << "\n";
DEBUG(std::cerr << resourceNumVector[i].
first << "\t" << resourceNumVector[i].second << "\n");
modSched_os << " maxNumIssueTotal(issue slot in one cycle) = " << msi.
maxNumIssueTotal << "\n";
modSched_os << "resourceID\t resourceUsage\t ResourceNum" << "\n";
DEBUG(std::cerr << " maxNumIssueTotal(issue slot in one cycle) = " << msi.
maxNumIssueTotal << "\n");
DEBUG(std::cerr << "resourceID\t resourceUsage\t ResourceNum\n");
for (unsigned i = 0; i < ru.size(); i++) {
modSched_os << ru[i].first << "\t" << ru[i].second;
DEBUG(std::cerr << ru[i].first << "\t" << ru[i].second);
const unsigned resNum = msi.getCPUResourceNum(ru[i].first);
modSched_os << "\t" << resNum << "\n";
DEBUG(std::cerr << "\t" << resNum << "\n");
}
}
@ -1175,7 +1173,7 @@ int ModuloSchedGraph::computeResII(const BasicBlock * bb)
const TargetSchedInfo & msi = target.getSchedInfo();
int ResII;
std::vector<std::pair<int,int>> resourceUsage;
std::vector<std::pair<int,int> > resourceUsage;
//pair<int resourceid, int resourceUsageTimes_in_the_whole_block>
//FIXME: number of functional units the target machine can provide should be
@ -1183,15 +1181,15 @@ int ModuloSchedGraph::computeResII(const BasicBlock * bb)
for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E;
I++) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "machine instruction for llvm instruction( node " <<
getGraphNodeForInst(I)->getNodeId() << ")" << "\n";
modSched_os << "\t" << *I;
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "machine instruction for llvm instruction( node " <<
getGraphNodeForInst(I)->getNodeId() << ")\n");
DEBUG(std::cerr << "\t" << *I);
}
MachineCodeForInstruction & tempMvec =
MachineCodeForInstruction::get(I);
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "size =" << tempMvec.size() << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "size =" << tempMvec.size() << "\n");
for (unsigned i = 0; i < tempMvec.size(); i++) {
MachineInstr *minstr = tempMvec[i];
@ -1201,27 +1199,27 @@ int ModuloSchedGraph::computeResII(const BasicBlock * bb)
msi.getClassRUsage(mii.getSchedClass(minstr->getOpCode()));
unsigned totCycles = classRUsage.totCycles;
std::vector<std::vector<resourceId_t>> resources =rUsage.resourcesByCycle;
std::vector<std::vector<resourceId_t> > resources=rUsage.resourcesByCycle;
assert(totCycles == resources.size());
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "resources Usage for this Instr(totCycles=" <<
totCycles << ",mindLatency=" << mii.minLatency(minstr->
getOpCode()) <<
"): " << *minstr << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "resources Usage for this Instr(totCycles="
<< totCycles << ",mindLatency="
<< mii.minLatency(minstr->getOpCode()) << "): " << *minstr
<< "\n");
for (unsigned j = 0; j < resources.size(); j++) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "cycle " << j << ": ";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "cycle " << j << ": ");
for (unsigned k = 0; k < resources[j].size(); k++) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "\t" << resources[j][k];
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "\t" << resources[j][k]);
addResourceUsage(resourceUsage, resources[j][k]);
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "\n");
}
}
}
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
this->dumpResourceUsage(resourceUsage);
//compute ResII
@ -1240,8 +1238,8 @@ int ModuloSchedGraph::computeResII(const BasicBlock * bb)
return ResII;
}
ModuloSchedGraphSet::ModuloSchedGraphSet(const Function * function,
const TargetMachine & target)
ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *function,
const TargetMachine &target)
: method(function)
{
buildGraphsForMethod(method, target);
@ -1257,20 +1255,20 @@ ModuloSchedGraphSet::~ModuloSchedGraphSet()
void ModuloSchedGraphSet::dump() const
{
modSched_os << " ====== ModuloSched graphs for function `" <<
method->getName() << "' =========\n\n";
DEBUG(std::cerr << " ====== ModuloSched graphs for function `" <<
method->getName() << "' =========\n\n");
for (const_iterator I = begin(); I != end(); ++I)
(*I)->dump();
modSched_os << "\n=========End graphs for funtion` " << method->getName()
<< "' ==========\n\n";
DEBUG(std::cerr << "\n=========End graphs for function `" << method->getName()
<< "' ==========\n\n");
}
void ModuloSchedGraph::dump(const BasicBlock * bb)
{
modSched_os << "dumping basic block:";
modSched_os << (bb->hasName()? bb->getName() : "block")
<< " (" << bb << ")" << "\n";
DEBUG(std::cerr << "dumping basic block:");
DEBUG(std::cerr << (bb->hasName()? bb->getName() : "block")
<< " (" << bb << ")" << "\n");
}
@ -1283,27 +1281,27 @@ void ModuloSchedGraph::dump(const BasicBlock * bb, std::ostream & os)
void ModuloSchedGraph::dump() const
{
modSched_os << " ModuloSchedGraph for basic Blocks:";
DEBUG(std::cerr << " ModuloSchedGraph for basic Blocks:");
for (unsigned i = 0, N = bbVec.size(); i < N; i++) {
modSched_os << (bbVec[i]->hasName()? bbVec[i]->getName() : "block")
<< " (" << bbVec[i] << ")" << ((i == N - 1) ? "" : ", ");
DEBUG(std::cerr << (bbVec[i]->hasName()? bbVec[i]->getName() : "block")
<< " (" << bbVec[i] << ")" << ((i == N - 1) ? "" : ", "));
}
modSched_os << "\n\n Actual Root nodes : ";
DEBUG(std::cerr << "\n\n Actual Root nodes : ");
for (unsigned i = 0, N = graphRoot->outEdges.size(); i < N; i++)
modSched_os << graphRoot->outEdges[i]->getSink()->getNodeId()
<< ((i == N - 1) ? "" : ", ");
DEBUG(std::cerr << graphRoot->outEdges[i]->getSink()->getNodeId()
<< ((i == N - 1) ? "" : ", "));
modSched_os << "\n Graph Nodes:\n";
DEBUG(std::cerr << "\n Graph Nodes:\n");
//for (const_iterator I=begin(); I != end(); ++I)
//modSched_os << "\n" << *I->second;
//DEBUG(std::cerr << "\n" << *I->second;
unsigned numNodes = bbVec[0]->size();
for (unsigned i = 2; i < numNodes + 2; i++) {
ModuloSchedGraphNode *node = getNode(i);
modSched_os << "\n" << *node;
DEBUG(std::cerr << "\n" << *node);
}
modSched_os << "\n";
DEBUG(std::cerr << "\n");
}
void ModuloSchedGraph::dumpNodeProperty() const
@ -1312,13 +1310,12 @@ void ModuloSchedGraph::dumpNodeProperty() const
unsigned numNodes = bb->size();
for (unsigned i = 2; i < numNodes + 2; i++) {
ModuloSchedGraphNode *node = getNode(i);
modSched_os << "NodeId " << node->getNodeId() << "\t";
modSched_os << "ASAP " << node->getASAP() << "\t";
modSched_os << "ALAP " << node->getALAP() << "\t";
modSched_os << "mov " << node->getMov() << "\t";
modSched_os << "depth " << node->getDepth() << "\t";
modSched_os << "height " << node->getHeight() << "\t";
modSched_os << "\n";
DEBUG(std::cerr << "NodeId " << node->getNodeId() << "\t");
DEBUG(std::cerr << "ASAP " << node->getASAP() << "\t");
DEBUG(std::cerr << "ALAP " << node->getALAP() << "\t");
DEBUG(std::cerr << "mov " << node->getMov() << "\t");
DEBUG(std::cerr << "depth " << node->getDepth() << "\t");
DEBUG(std::cerr << "height " << node->getHeight() << "\t\n");
}
}

View File

@ -13,17 +13,10 @@
#include "llvm/Target/TargetInstrInfo.h"
#include "Support/HashExtras.h"
#include "Support/GraphTraits.h"
#include "Support/hash_map"
#include "../InstrSched/SchedGraphCommon.h"
#include <iostream>
//for debug information selecton
enum ModuloSchedDebugLevel_t {
ModuloSched_NoDebugInfo,
ModuloSched_Disable,
ModuloSched_PrintSchedule,
ModuloSched_PrintScheduleProcess,
};
//===----------------------------------------------------------------------===//
// ModuloSchedGraphNode - Implement a data structure based on the
// SchedGraphNodeCommon this class stores informtion needed later to order the
@ -160,20 +153,20 @@ private:
typedef std::vector<ModuloSchedGraphNode*> NodeVec;
//the function to compute properties
void computeNodeASAP(const BasicBlock * bb);
void computeNodeALAP(const BasicBlock * bb);
void computeNodeMov(const BasicBlock * bb);
void computeNodeDepth(const BasicBlock * bb);
void computeNodeHeight(const BasicBlock * bb);
void computeNodeASAP(const BasicBlock *bb);
void computeNodeALAP(const BasicBlock *bb);
void computeNodeMov(const BasicBlock *bb);
void computeNodeDepth(const BasicBlock *bb);
void computeNodeHeight(const BasicBlock *bb);
//the function to compute node property
void computeNodeProperty(const BasicBlock * bb);
void computeNodeProperty(const BasicBlock *bb);
//the function to sort nodes
void orderNodes();
//add the resource usage
void addResourceUsage(std::vector<pair<int,int>>&, int);
void addResourceUsage(std::vector<std::pair<int,int> > &, int);
//debug functions:
//dump circuits
@ -181,7 +174,7 @@ void addResourceUsage(std::vector<pair<int,int>>&, int);
//dump the input set of nodes
void dumpSet(std::vector<ModuloSchedGraphNode*> set);
//dump the input resource usage table
void dumpResourceUsage(std::vector<pair<int,int>> &);
void dumpResourceUsage(std::vector<std::pair<int,int> > &);
public:
//help functions
@ -195,16 +188,16 @@ public:
NodeVec predSet(NodeVec set);
//get the predessor set of the node
NodeVec predSet(ModuloSchedGraphNode * node, unsigned, unsigned);
NodeVec predSet(ModuloSchedGraphNode * node);
NodeVec predSet(ModuloSchedGraphNode *node, unsigned, unsigned);
NodeVec predSet(ModuloSchedGraphNode *node);
//get the successor set of the set
NodeVec succSet(NodeVec set, unsigned, unsigned);
NodeVec succSet(NodeVec set);
//get the succssor set of the node
NodeVec succSet(ModuloSchedGraphNode * node, unsigned, unsigned);
NodeVec succSet(ModuloSchedGraphNode * node);
NodeVec succSet(ModuloSchedGraphNode *node, unsigned, unsigned);
NodeVec succSet(ModuloSchedGraphNode *node);
//return the uniton of the two vectors
NodeVec vectorUnion(NodeVec set1, NodeVec set2);
@ -248,17 +241,22 @@ public:
//return this basibBlock contains a loop
bool isLoop();
//return the node for the input instruction
ModuloSchedGraphNode *getGraphNodeForInst(const Instruction * inst) const {
const_iterator onePair = this->find(inst);
return (onePair != this->end()) ? (*onePair).second : NULL;
}
//Debugging support//dump the graph void dump() const;
//dump the basicBlock
// Debugging support
//dump the graph
void dump() const;
// dump the basicBlock
void dump(const BasicBlock * bb);
//dump the basicBlock into 'os' stream
void dump(const BasicBlock * bb, std::ostream & os);
//dump the node property
void dumpNodeProperty() const;
@ -267,7 +265,8 @@ private:
public:
ModuloSchedGraph(const BasicBlock *bb, const TargetMachine &_target)
:SchedGraphCommon(bb), target(_target) {
:SchedGraphCommon(bb), target(_target)
{
buildGraph(target);
}
@ -276,8 +275,8 @@ public:
delete I->second;
}
//unorder iterators
//return values are pair<const Instruction*, ModuloSchedGraphNode*>
// Unorder iterators
// return values are pair<const Instruction*, ModuloSchedGraphNode*>
using map_base::begin;
using map_base::end;
@ -348,8 +347,8 @@ public:
using baseVector::begin;
using baseVector::end;
// Debugging support
void dump() const;
// Debugging support
void dump() const;
private:
void addGraph(ModuloSchedGraph *graph) {
@ -360,6 +359,6 @@ private:
// Graph builder
void buildGraphsForMethod(const Function *F,
const TargetMachine &target);
}
};
#endif

View File

@ -19,6 +19,7 @@
#include "llvm/Target/TargetSchedInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "Support/CommandLine.h"
#include "Support/Statistic.h"
#include "ModuloSchedGraph.h"
#include "ModuloScheduling.h"
#include <algorithm>
@ -34,29 +35,26 @@
// see ModuloSchedulingPass::runOnFunction()
//************************************************************
ModuloSchedDebugLevel_t ModuloSchedDebugLevel;
static cl::opt<ModuloSchedDebugLevel_t,true>
SDL_opt("modsched", cl::Hidden, cl::location(ModuloSchedDebugLevel),
cl::desc("enable modulo scheduling debugging information"),
cl::values(clEnumValN
(ModuloSched_NoDebugInfo, "n", "disable debug output"),
clEnumValN(ModuloSched_Disable, "off",
"disable modulo scheduling"),
clEnumValN(ModuloSched_PrintSchedule, "psched",
"print original and new schedule"),
clEnumValN(ModuloSched_PrintScheduleProcess, "pschedproc",
"print how the new schdule is produced"), 0));
std::filebuf modSched_fb;
std::ostream modSched_os(&modSched_fb);
namespace {
cl::opt<ModuloScheduling::DebugLevel_t,true>
SDL_opt("modsched", cl::Hidden, cl::location(ModuloScheduling::DebugLevel),
cl::desc("enable modulo scheduling debugging information"),
cl::values(clEnumValN(ModuloScheduling::DebugLevel_NoDebugInfo,
"none", "disable debug output"),
clEnumValN(ModuloScheduling::DebugLevel_PrintSchedule,
"psched", "print original and new schedule"),
clEnumValN(ModuloScheduling::DebugLevel_PrintScheduleProcess,
"pschedproc",
"print how the new schdule is produced"),
0));
}
// Computes the schedule and inserts epilogue and prologue
//
void ModuloScheduling::instrScheduling()
{
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "*************** computing modulo schedule **************\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "************ computing modulo schedule ***********\n");
const TargetSchedInfo & msi = target.getSchedInfo();
@ -74,13 +72,13 @@ void ModuloScheduling::instrScheduling()
if (!success) {
II++;
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "increase II to " << II << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "increase II to " << II << "\n");
}
}
//print the final schedule if necessary
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule)
if (ModuloScheduling::printSchedule())
dumpScheduling();
//the schedule has been computed
@ -90,8 +88,8 @@ void ModuloScheduling::instrScheduling()
BasicBlock *succ_bb = getSuccBB(bb);
//print the original BasicBlock if necessary
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule) {
modSched_os << "dumping the orginal block\n";
if (ModuloScheduling::printSchedule()) {
DEBUG(std::cerr << "dumping the orginal block\n");
graph.dump(bb);
}
//construction of prologue, kernel and epilogue
@ -109,12 +107,12 @@ void ModuloScheduling::instrScheduling()
constructEpilogue(epilogue, succ_bb);
//print the BasicBlocks if necessary
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule) {
modSched_os << "dumping the prologue block:\n";
if (ModuloScheduling::printSchedule()) {
DEBUG(std::cerr << "dumping the prologue block:\n");
graph.dump(prologue);
modSched_os << "dumping the kernel block\n";
DEBUG(std::cerr << "dumping the kernel block\n");
graph.dump(kernel);
modSched_os << "dumping the epilogue block\n";
DEBUG(std::cerr << "dumping the epilogue block\n");
graph.dump(epilogue);
}
}
@ -125,11 +123,10 @@ void ModuloScheduling::clearInitMem(const TargetSchedInfo & msi)
{
unsigned numIssueSlots = msi.maxNumIssueTotal;
// clear nodeScheduled from the last round
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << "***** new round with II= " << II <<
" *******************\n";
modSched_os <<
" ************clear the vector nodeScheduled*************\n";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << "***** new round with II= " << II << " ***********\n");
DEBUG(std::cerr <<
" ************clear the vector nodeScheduled*************\n");
}
nodeScheduled.clear();
@ -158,13 +155,13 @@ void ModuloScheduling::clearInitMem(const TargetSchedInfo & msi)
bool ModuloScheduling::computeSchedule()
{
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "start to compute schedule\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "start to compute schedule\n");
// Loop over the ordered nodes
for (NodeVec::const_iterator I = oNodes.begin(); I != oNodes.end(); ++I) {
// Try to schedule for node I
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
if (ModuloScheduling::printScheduleProcess())
dumpScheduling();
ModuloSchedGraphNode *node = *I;
@ -255,8 +252,8 @@ bool ModuloScheduling::computeSchedule()
endTime = node->getEarlyStart() + II - 1;
}
//try to schedule this node based on the startTime and endTime
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "scheduling the node " << (*I)->getNodeId() << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "scheduling the node " << (*I)->getNodeId() << "\n");
bool success =
this->ScheduleNode(node, startTime, endTime, nodeScheduled);
@ -337,10 +334,9 @@ BasicBlock *ModuloScheduling::getPredBB(BasicBlock *bb)
//
void ModuloScheduling::constructPrologue(BasicBlock *prologue)
{
InstListType & prologue_ist = prologue->getInstList();
vvNodeType & tempSchedule_prologue =
*(new vector < std::vector < ModuloSchedGraphNode * >>(schedule));
*(new std::vector<std::vector<ModuloSchedGraphNode*> >(schedule));
//compute the schedule for prologue
unsigned round = 0;
@ -395,7 +391,6 @@ void ModuloScheduling::constructKernel(BasicBlock *prologue,
BasicBlock *kernel,
BasicBlock *epilogue)
{
//*************fill instructions in the kernel****************
InstListType & kernel_ist = kernel->getInstList();
BranchInst *brchInst;
@ -472,8 +467,8 @@ void ModuloScheduling::constructEpilogue(BasicBlock *epilogue,
{
//compute the schedule for epilogue
vvNodeType & tempSchedule_epilogue =
*(new vector < std::vector < ModuloSchedGraphNode * >>(schedule));
vvNodeType &tempSchedule_epilogue =
*(new std::vector<std::vector<ModuloSchedGraphNode*> >(schedule));
unsigned scheduleSize = schedule.size();
int round = 0;
while (round < ceil(1.0 * scheduleSize / II) - 1) {
@ -626,17 +621,17 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
const TargetSchedInfo & msi = target.getSchedInfo();
unsigned int numIssueSlots = msi.maxNumIssueTotal;
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "startTime= " << start << " endTime= " << end << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "startTime= " << start << " endTime= " << end << "\n");
bool isScheduled = false;
for (unsigned i = start; i <= end; i++) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << " now try cycle " << i << ":" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << " now try cycle " << i << ":" << "\n");
for (unsigned j = 0; j < numIssueSlots; j++) {
unsigned int core_i = i % II;
unsigned int core_j = j;
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << "\t Trying slot " << j << "...........";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << "\t Trying slot " << j << "...........");
//check the resouce table, make sure there is no resource conflicts
const Instruction *instr = node->getInst();
MachineCodeForInstruction & tempMvec =
@ -675,10 +670,9 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
}
}
if (!resourceConflict && !coreSchedule[core_i][core_j]) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess) {
modSched_os << " OK!" << "\n";
modSched_os << "Node " << node->
getNodeId() << " is scheduleed." << "\n";
if (ModuloScheduling::printScheduleProcess()) {
DEBUG(std::cerr << " OK!" << "\n");
DEBUG(std::cerr << "Node " << node->getNodeId() << " scheduled.\n");
}
//schedule[i][j]=node;
while (schedule.size() <= i) {
@ -688,7 +682,7 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
newCycle->push_back(NULL);
schedule.push_back(*newCycle);
}
vector < ModuloSchedGraphNode * >::iterator startIterator;
std::vector<ModuloSchedGraphNode*>::iterator startIterator;
startIterator = schedule[i].begin();
schedule[i].insert(startIterator + j, node);
startIterator = schedule[i].begin();
@ -697,8 +691,8 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
//update coreSchedule
//coreSchedule[core_i][core_j]=node;
while (coreSchedule.size() <= core_i) {
std::vector < ModuloSchedGraphNode * >*newCycle =
new std::vector < ModuloSchedGraphNode * >();
std::vector<ModuloSchedGraphNode*> *newCycle =
new std::vector<ModuloSchedGraphNode*>();
for (unsigned k = 0; k < numIssueSlots; k++)
newCycle->push_back(NULL);
coreSchedule.push_back(*newCycle);
@ -715,11 +709,11 @@ bool ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node,
break;
} else if (coreSchedule[core_i][core_j]) {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << " Slot not available " << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << " Slot not available\n");
} else {
if (ModuloSchedDebugLevel >= ModuloSched_PrintScheduleProcess)
modSched_os << " Resource conflicts" << "\n";
if (ModuloScheduling::printScheduleProcess())
DEBUG(std::cerr << " Resource conflicts\n");
}
}
if (isScheduled)
@ -804,12 +798,12 @@ bool ModuloScheduling::resourceTableNegative()
void ModuloScheduling::dumpResourceUsageTable()
{
modSched_os << "dumping resource usage table" << "\n";
DEBUG(std::cerr << "dumping resource usage table\n");
for (unsigned i = 0; i < resourceTable.size(); i++) {
for (unsigned j = 0; j < resourceTable[i].size(); j++)
modSched_os << resourceTable[i][j].
first << ":" << resourceTable[i][j].second << " ";
modSched_os << "\n";
DEBUG(std::cerr << resourceTable[i][j].first
<< ":" << resourceTable[i][j].second << " ");
DEBUG(std::cerr << "\n");
}
}
@ -825,18 +819,17 @@ void ModuloScheduling::dumpSchedule(vvNodeType thisSchedule)
const TargetSchedInfo & msi = target.getSchedInfo();
unsigned numIssueSlots = msi.maxNumIssueTotal;
for (unsigned i = 0; i < numIssueSlots; i++)
modSched_os << "\t#";
modSched_os << "\n";
DEBUG(std::cerr << "\t#");
DEBUG(std::cerr << "\n");
for (unsigned i = 0; i < thisSchedule.size(); i++) {
modSched_os << "cycle" << i << ": ";
DEBUG(std::cerr << "cycle" << i << ": ");
for (unsigned j = 0; j < thisSchedule[i].size(); j++)
if (thisSchedule[i][j] != NULL)
modSched_os << thisSchedule[i][j]->getNodeId() << "\t";
DEBUG(std::cerr << thisSchedule[i][j]->getNodeId() << "\t");
else
modSched_os << "\t";
modSched_os << "\n";
DEBUG(std::cerr << "\t");
DEBUG(std::cerr << "\n");
}
}
@ -849,34 +842,34 @@ void ModuloScheduling::dumpSchedule(vvNodeType thisSchedule)
void ModuloScheduling::dumpScheduling()
{
modSched_os << "dump schedule:" << "\n";
DEBUG(std::cerr << "dump schedule:" << "\n");
const TargetSchedInfo & msi = target.getSchedInfo();
unsigned numIssueSlots = msi.maxNumIssueTotal;
for (unsigned i = 0; i < numIssueSlots; i++)
modSched_os << "\t#";
modSched_os << "\n";
DEBUG(std::cerr << "\t#");
DEBUG(std::cerr << "\n");
for (unsigned i = 0; i < schedule.size(); i++) {
modSched_os << "cycle" << i << ": ";
DEBUG(std::cerr << "cycle" << i << ": ");
for (unsigned j = 0; j < schedule[i].size(); j++)
if (schedule[i][j] != NULL)
modSched_os << schedule[i][j]->getNodeId() << "\t";
DEBUG(std::cerr << schedule[i][j]->getNodeId() << "\t");
else
modSched_os << "\t";
modSched_os << "\n";
DEBUG(std::cerr << "\t");
DEBUG(std::cerr << "\n");
}
modSched_os << "dump coreSchedule:" << "\n";
DEBUG(std::cerr << "dump coreSchedule:" << "\n");
for (unsigned i = 0; i < numIssueSlots; i++)
modSched_os << "\t#";
modSched_os << "\n";
DEBUG(std::cerr << "\t#");
DEBUG(std::cerr << "\n");
for (unsigned i = 0; i < coreSchedule.size(); i++) {
modSched_os << "cycle" << i << ": ";
DEBUG(std::cerr << "cycle" << i << ": ");
for (unsigned j = 0; j < coreSchedule[i].size(); j++)
if (coreSchedule[i][j] != NULL)
modSched_os << coreSchedule[i][j]->getNodeId() << "\t";
DEBUG(std::cerr << coreSchedule[i][j]->getNodeId() << "\t");
else
modSched_os << "\t";
modSched_os << "\n";
DEBUG(std::cerr << "\t");
DEBUG(std::cerr << "\n");
}
}
@ -893,12 +886,15 @@ void ModuloScheduling::dumpScheduling()
namespace {
class ModuloSchedulingPass:public FunctionPass {
const TargetMachine & target;
const TargetMachine &target;
public:
ModuloSchedulingPass(const TargetMachine &T):target(T) {
} const char *getPassName() const {
ModuloSchedulingPass(const TargetMachine &T):target(T) {}
const char *getPassName() const {
return "Modulo Scheduling";
}
// getAnalysisUsage - We use LiveVarInfo...
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
//AU.addRequired(FunctionLiveVarInfo::ID);
@ -909,24 +905,9 @@ namespace {
bool ModuloSchedulingPass::runOnFunction(Function &F)
{
//if necessary , open the output for debug purpose
if (ModuloSchedDebugLevel == ModuloSched_Disable)
return false;
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule) {
modSched_fb.open("moduloSchedDebugInfo.output", std::ios::out);
modSched_os <<
"******************Modula Scheduling debug information****************"
<< "\n ";
}
ModuloSchedGraphSet *graphSet = new ModuloSchedGraphSet(&F, target);
ModuloSchedulingSet ModuloSchedulingSet(*graphSet);
if (ModuloSchedDebugLevel >= ModuloSched_PrintSchedule)
modSched_fb.close();
return false;
}

View File

@ -60,19 +60,32 @@ public:
~ModuloScheduling() {};
///the method to compute schedule and instert epilogue and prologue
// for debug information selecton
enum DebugLevel_t {
DebugLevel_NoDebugInfo,
DebugLevel_PrintSchedule,
DebugLevel_PrintScheduleProcess,
};
static DebugLevel_t DebugLevel;
static bool printSchedule() { return DebugLevel >= DebugLevel_PrintSchedule; }
static bool printScheduleProcess() {
return DebugLevel >= DebugLevel_PrintScheduleProcess;
}
// The method to compute schedule and instert epilogue and prologue
void instrScheduling();
///debug functions:
///dump the schedule and core schedule
void
dumpScheduling();
// Debug functions:
// Dump the schedule and core schedule
void dumpScheduling();
///dump the input vector of nodes
//sch: the input vector of nodes
void dumpSchedule(std::vector<std::vector<ModuloSchedGraphNode*>> sch);
// Dump the input vector of nodes
// sch: the input vector of nodes
void dumpSchedule(std::vector<std::vector<ModuloSchedGraphNode*> > sch);
///dump the resource usage table
// Dump the resource usage table
void dumpResourceUsageTable();
//*******************internal functions*******************************
@ -94,13 +107,13 @@ private:
// update the resource table at the startCycle
// vec: the resouce usage
// startCycle: the start cycle the resouce usage is
void updateResourceTable(std::vector<std::vector<unsigned int>> vec,
void updateResourceTable(std::vector<std::vector<unsigned> > vec,
int startCycle);
// un-do the update in the resource table in the startCycle
// vec: the resouce usage
// startCycle: the start cycle the resouce usage is
void undoUpdateResourceTable(std::vector<vector<unsigned int>> vec,
void undoUpdateResourceTable(std::vector<std::vector<unsigned> > vec,
int startCycle);
// return whether the resourcetable has negative element