llvm-project/llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h

174 lines
5.2 KiB
C++

// ModuloScheduling.h -------------------------------------------*- C++ -*-===//
//
// This header defines the the classes ModuloScheduling and
// ModuloSchedulingSet's structure
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MODULOSCHEDULING_H
#define LLVM_CODEGEN_MODULOSCHEDULING_H
#include "ModuloSchedGraph.h"
#include <iostream>
#include <vector>
class ModuloScheduling: NonCopyable {
private:
typedef std::vector<ModuloSchedGraphNode*> NodeVec;
typedef std::vector<std::vector<unsigned> > Resources;
// The graph to feed in
ModuloSchedGraph &graph;
const TargetMachine &target;
// The BasicBlock to be scheduled
BasicBlock *bb;
// Iteration Interval
// FIXME: II may be a better name for its meaning
unsigned II;
// The vector containing the nodes which have been scheduled
NodeVec nodeScheduled;
// The remaining unscheduled nodes
const NodeVec &oNodes;
// The machine resource table
std::vector<std::vector<std::pair<int,int> > > resourceTable;
///the schedule( with many schedule stage)
std::vector<std::vector<ModuloSchedGraphNode*> > schedule;
///the kernel(core) schedule(length = II)
std::vector<std::vector<ModuloSchedGraphNode*> > coreSchedule;
typedef BasicBlock::InstListType InstListType;
typedef std::vector<std::vector<ModuloSchedGraphNode*> > vvNodeType;
public:
ModuloScheduling(ModuloSchedGraph & _graph):
graph(_graph), target(graph.getTarget()), oNodes(graph.getONodes())
{
II = graph.getMII();
bb = (BasicBlock *) graph.getBasicBlocks()[0];
instrScheduling();
};
~ModuloScheduling() {};
// 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();
// 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
void dumpResourceUsageTable();
//*******************internal functions*******************************
private:
//clear memory from the last round and initialize if necessary
void clearInitMem(const TargetSchedInfo&);
//compute schedule and coreSchedule with the current II
bool computeSchedule();
BasicBlock *getSuccBB(BasicBlock *);
BasicBlock *getPredBB(BasicBlock *);
void constructPrologue(BasicBlock *prologue);
void constructKernel(BasicBlock *prologue,
BasicBlock *kernel,
BasicBlock *epilogue);
void constructEpilogue(BasicBlock *epilogue, BasicBlock *succ_bb);
// 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> > 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<std::vector<unsigned> > vec,
int startCycle);
// return whether the resourcetable has negative element
// this function is called after updateResouceTable() to determine whether a
// node can be scheduled at certain cycle
bool resourceTableNegative();
// try to Schedule the node starting from start to end cycle(inclusive)
// if it can be scheduled, put it in the schedule and update nodeScheduled
// node: the node to be scheduled
// start: start cycle
// end : end cycle
// nodeScheduled: a vector storing nodes which has been scheduled
bool ScheduleNode(ModuloSchedGraphNode * node, unsigned start,
unsigned end, NodeVec &nodeScheduled);
//each instruction has a memory of the latest clone instruction
//the clone instruction can be get using getClone()
//this function clears the memory, i.e. getClone() after calling this function
//returns null
void clearCloneMemory();
//this fuction make a clone of this input Instruction and update the clone
//memory
//inst: the instrution to be cloned
Instruction *cloneInstSetMemory(Instruction *inst);
//this function update each instrutions which uses ist as its operand
//after update, each instruction will use ist's clone as its operand
void updateUseWithClone(Instruction * ist);
};
class ModuloSchedulingSet:
NonCopyable {
private:
//the graphSet to feed in
ModuloSchedGraphSet & graphSet;
public:
//constructor
//Scheduling graph one by one
ModuloSchedulingSet(ModuloSchedGraphSet _graphSet): graphSet(_graphSet) {
for (unsigned i = 0; i < graphSet.size(); i++) {
ModuloSchedGraph & graph = *(graphSet[i]);
if (graph.isLoop())
ModuloScheduling ModuloScheduling(graph);
}
};
~ModuloSchedulingSet() {};
};
#endif