//===- ModuloSchedGraph.cpp - Modulo Scheduling Graph and Set -*- C++ -*---===// // // Description here //===----------------------------------------------------------------------===// #include "ModuloSchedGraph.h" #include "llvm/Type.h" ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned id, int index, const Instruction *inst, const TargetMachine &targ) : SchedGraphNodeCommon(id, index), Inst(inst), Target(targ) { } void ModuloSchedGraphNode::print(std::ostream &os) const { os << "Modulo Scheduling Node\n"; } ModuloSchedGraph::ModuloSchedGraph(const BasicBlock *bb, const TargetMachine &targ) : SchedGraphCommon(), BB(bb), Target(targ) { assert(BB != NULL && "Basic Block is null"); //Builds nodes from each instruction in the basic block buildNodesForBB(); } void ModuloSchedGraph::buildNodesForBB() { int count = 0; for (BasicBlock::const_iterator i = BB->begin(), e = BB->end(); i != e; ++i) { addNode(i,new ModuloSchedGraphNode(size(), count, i, Target)); count++; } //Get machine instruction(s) for the llvm instruction //MachineCodeForInstruction &MC = MachineCodeForInstruction::get(Node->first); } void ModuloSchedGraph::addNode(const Instruction *I, ModuloSchedGraphNode *node) { assert(node!= NULL && "New ModuloSchedGraphNode is null"); GraphMap[I] = node; } void ModuloSchedGraph::addDepEdges() { //Get Machine target information for calculating delay const TargetInstrInfo &MTI = Target.getInstrInfo(); //Loop over instruction in BB and gather dependencies for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { //Ignore instructions of the void type if(I->getType() != Type::VoidTy) { //Iterate over def-use chain and add true dependencies for (Value::use_const_iterator U = I->use_begin(), e = I->use_end(); U != e; ++U) { if (Instruction *Inst = dyn_cast(*U)) { //Check if a node already exists for this instruction ModuloSchedGraph::iterator Sink = find(Inst); //If the instruction is in our graph, add appropriate edges if(Sink->second != NULL) { //assert if self loop assert(&*I == Sink->first && "Use edge to itself!"); //Create edge and set delay equal to node latency //FIXME: Is it safe to do this? ModuloSchedGraph::iterator Src = find(I); SchedGraphEdge *trueDep = new SchedGraphEdge(&*Src->second ,&*Sink->second, &*I, SchedGraphEdge::TrueDep, Src->second->getLatency()); //Determine the iteration difference //FIXME: Will this ever happen? } } } } } } void ModuloSchedGraph::ASAP() { } void ModuloSchedGraph::ALAP() { } void ModuloSchedGraph::MOB() { } void ModuloSchedGraph::ComputeDepth() { } void ModuloSchedGraph::ComputeHeight() { } void ModuloSchedGraphSet::addGraph(ModuloSchedGraph *graph) { assert(graph!=NULL && "Graph for BasicBlock is null"); Graphs.push_back(graph); } ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *F, const TargetMachine &targ) : function(F) { //Create graph for each BB in this function for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI) addGraph(new ModuloSchedGraph(BI, targ)); } ModuloSchedGraphSet::~ModuloSchedGraphSet(){ //delete all the graphs }