116 killDeadResults_(false), renameRegisters_(false) {
197 std::cerr <<
"Individual move: " << firstMove.
toString()
203 std::string message =
" Move(s) did not get scheduled: ";
204 for (
int i = 0; i < moves.
nodeCount(); i++) {
216 debugLog(
"All moves in the DDG didn't get scheduled.");
222 std::string wtf =
"0";
233 #ifdef DEBUG_REG_COPY_ADDER 234 static int graphCount = 0;
250 std::cerr <<
"ScheduleOperation from selector: " << moves.
toString()
253 for (
int i = 0; i < moves.
nodeCount(); i++) {
257 "Scheduling failed for opsched, operation: " 266 for (
int lastCycle =
endCycle_; lastCycle > 0; lastCycle--) {
273 std::cerr <<
"Trying to schedule op again with smaller cycle" 281 "Scheduling failed for unknown reason!, operation: " 293 return "Bypassing recursive Bottom-up list scheduler with a basic block scope.";
307 "Bottom-up list basic block scheduler that first tries to bypass" 308 " and only then assign moves,and recursively schedules bypass sources";
314 for (std::map<MoveNode*, MoveNode*, MoveNode::Comparator>::iterator i =
325 for (std::set<MoveNode*, MoveNode::Comparator>::iterator i =
332 copyDepsOver(*node,
true,
true);
334 std::cerr <<
"DRE killing node: " << (**i).toString() << std::endl;
338 for (DataDependenceGraph::NodeSet::iterator i =
339 preds.begin(); i != preds.end(); i++) {
345 for (std::set<MoveNode*, MoveNode::Comparator>::iterator i =
348 assert((**i).isScheduled());
367 int lc = latestCycle;
368 std::cerr <<
"Scheduling operation: " << po.
toString()
369 <<
" lc: " << latestCycle << std::endl;
373 "po already scheduled!" +
377 std::cerr <<
"results fail for: " << po.
toString() << std::endl;
386 if (mn.
cycle() > lastRes) {
387 lastRes = mn.
cycle();
397 std::cerr <<
"Last result cycle: " << lastRes << std::endl;
398 assert(lastRes <= latestCycle);
399 latestCycle = lastRes;
407 if (trigger == NULL) {
408 std::cerr <<
"Trigger was null for: " << po.
toString() << std::endl;
414 std::cerr <<
"trigger bypass or shed fail for: " <<
429 std::cerr <<
"Unscheduled trigger fail:" << trigger->
toString()
438 latestCycle = trigger->
cycle();
443 std::cerr <<
"Operands scheduling fail for: " <<
448 std::cerr <<
"Operation scheduled ok!" << po.
toString() << std::endl;
472 mn, cycleLimits.first, std::min(
473 cycleLimits.second, latestCycle),
497 std::cerr <<
"This node is to be DRE'd: " << mn.
toString()
546 MoveNode& mn,
int earliestCycle,
int latestCycle) {
547 std::cerr <<
"\t\tSchedulign moveUB: " << mn.
toString() <<
548 " Cycle limits: " << earliestCycle <<
" , " << latestCycle
577 latestCycle = std::min(latestCycle, (
int)
endCycle_);
578 std::cerr <<
"\t\tlc: " << latestCycle << std::endl;
580 latestCycle = std::min(latestCycle, ddgLC);
581 std::cerr <<
"\t\tddglc: " << latestCycle << std::endl;
583 std::cerr <<
"\t\tddgec: " << ddgEC << std::endl;
584 if (ddgEC == -1 || ddgEC == INT_MAX) {
587 int minCycle = std::max(earliestCycle, ddgEC);
588 std::cerr <<
"\t\tmincycle: " << minCycle << std::endl;
590 std::cerr <<
"\t\trmcycle: " << rmCycle << std::endl;
591 if (rmCycle != -1 && rmCycle <= latestCycle) {
595 std::cerr <<
"\t\tScheduled to cycle: " << rmCycle << std::endl;
616 MoveNode& mn,
int earliestCycle,
int latestCycle,
620 std::cerr <<
"\t\tSchedulign moveBU: " << mn.
toString() <<
621 " Cycle limits: " << earliestCycle <<
" , " << latestCycle
632 if (regCopyAfter != NULL &&
636 std::cerr <<
"\t\t\tScheduling regcopyafter: " <<
637 regCopyAfter->
toString() << std::endl;
639 *regCopyAfter, 0, latestCycle, t))) {
640 std::cerr <<
"\t\t\t\tRegcopyafter scheduling failed" << std::endl;
649 std::cerr <<
"\t\t\tSchedulemoveBU cannot transport move" << std::endl;
661 if (reg2RegCopy == NULL) {
664 std::cerr <<
"\t\t\tCreated regcopy: " << reg2RegCopy->
toString()
669 std::cerr <<
"Existing regcopy before: " << oldRC->
toString()
670 <<
" setting it as regcopy of regcopy" 675 std::cerr <<
"\t\t\t\tRegcopybefore added." << std::endl;
683 std::cerr <<
"Existing regcopy after: "<<oldRC->
toString()
684 <<
" setting it as regcopy of regcopy" 704 std::cerr <<
"\t\t\tRenamed source to get connectivity: " <<
708 std::cerr <<
"\t\t\tCantransportmove ok for: " << mn.
toString() << std::endl;
711 latestCycle = std::min(latestCycle, endCycle);
713 if (ddgCycle == -1) {
714 std::cerr <<
"ddg cycle -1, ddg prevents scheduling!" << std::endl;
717 int maxCycle = std::min(latestCycle, ddgCycle);
718 std::cerr <<
"\t\t\tmaxCycle after ddg: " << maxCycle << std::endl;
720 std::cerr <<
"\t\t\trmCycle: " << rmCycle << std::endl;
721 if (rmCycle != -1 && rmCycle >= earliestCycle) {
724 std::cerr <<
"\t\tScheduled to cycle: " << rmCycle << std::endl;
729 if (regCopyBefore != NULL &&
733 std::cerr <<
"scheduling regcopybefore: " <<
734 regCopyBefore->
toString() << std::endl;
736 *regCopyBefore, 0, rmCycle-1, t))) {
737 std::cerr <<
"regcopybefore scheduling failed" <<
747 std::cerr <<
"\t\t\trmcycle is -1, cannot schedule move" << std::endl;
762 std::cerr <<
"\t\tIncoming hopcount: " << maxHopCount << std::endl;
763 std::pair<MoveNode*,int> bypassSource =
765 if (bypassSource.second == 0) {
766 std::cerr <<
"\t\thopcount 0" << std::endl;
771 if (bypassSource.first->isScheduled()) {
772 std::cerr <<
"\t\tbypassource scheduled" << std::endl;
784 std::cerr <<
"\t\tguardsnotallowbypass" << std::endl;
792 std::cerr <<
"Merge fail." << std::endl;
796 std::cerr <<
"Merged." << std::endl;
803 std::cerr <<
"Could remove source:" <<
804 bypassSource.first->toString() << std::endl;
810 if (rgBefore != NULL) {
816 return bypassSource.second;
826 std::pair<MoveNode*, int>
829 std::set<const TTAMachine::Port*>
837 for (
int i = 0; i < maxHopCount; i++) {
839 if (rrSource == NULL) {
844 *n, destinationPorts)) {
849 return std::pair<MoveNode*,int>(okSource, hops);
859 int bypassHopCount = 1;
860 while (bypassHopCount >= 0) {
861 bypassHopCount =
bypassNode(node, bypassHopCount);
862 if (bypassHopCount > 0) {
863 std::cerr <<
"\tBypassed node: " << node.
toString() << std::endl;
867 int lc = latestCycle;
881 node, trigger, latestCycle, allowRegCopies)) {
884 std::cerr <<
"Bypassed operand failed.. trying smaller " 897 std::cerr <<
"\tDid not bypass: " << node.
toString() << std::endl;
899 node, trigger, latestCycle, allowRegCopies)) {
916 bool allowRegCopies) {
920 if (trigger != &operand) {
922 operand, trigger, latestCycle, allowRegCopies)) {
923 for (; i >= 0; i++) {
941 bool allowRegCopies) {
942 std::pair<int,int> cycleLimits =
946 std::min(latestCycle,cycleLimits.second),
963 if (po.areOutputsAssigned()) {
968 if (po.isAnyInputAssigned()) {
970 if (trigger == NULL) {
973 if (trigger != NULL) {
974 if (trigger == &mn) {
980 maxx = trigger->
cycle();
985 return std::pair<int,int>(INT_MAX, -1);
988 return std::pair<int,int>(minn, maxx);
1003 if (mn.
cycle() > res) {
1016 std::cerr <<
"\tundoing bypass: " << mn.
toString() << std::endl;
1018 if (source != NULL) {
1020 std::cerr <<
"undid dre: " << source->
toString()
1032 std::cerr <<
"\tundid bypass: " << mn.
toString() << std::endl;
1070 std::cerr <<
"UnScheduling: " << mn.
toString() << std::endl;
1072 if (regcopy != NULL) {
1085 if (regcopy != NULL) {
1098 std::cerr <<
"\tUnschedulign results" << std::endl;
1134 for (DataDependenceGraph::NodeSet::iterator i =
removedNodes_.begin();
1137 if ((**i).isScheduled()) {
1138 std::cerr <<
"DRE'd move: " << (**i).toString() <<
1139 " is Scheduled! " << std::endl;
1141 assert(!(**i).isScheduled());
1157 MoveNode& moveNode,
int latestCycle) {
1164 moveNode,
false,
false,
false, latestCycle)) {
1181 std::cerr <<
"Could not find liverange for:" << moveNode.
toString() << std::endl;
1186 if (!(lr->
writes.size() == 1 && lr->
reads.size() > 0)) {
1187 std::cerr <<
"Liverange too complex to rename: " << lr->
toString()
1188 <<
" for: " << moveNode.
toString() << std::endl;
1192 std::cerr <<
"(Not really yeat)Trying to rename lr: " << lr->
toString() << std::endl;
1223 std::set<TTAMachine::RegisterFile*, TTAMachine::MachinePart::Comparator>
1228 int lastRegisterIndex = rf->
size()-1;
1248 std::cerr <<
"Creating temp move after: " << mn.
toString() <<
" ";
1252 *
ddg_, mn, &mn, copyNode, rf, lastRegisterIndex, bbn,
true);
1253 std::cerr <<
" Moves after split: " << mn.
toString() <<
" and " <<
1258 std::cerr <<
"Creating temp move before: " << mn.
toString();
1263 *
ddg_, mn, copyNode, &mn, rf, lastRegisterIndex, bbn,
true);
1265 std::cerr <<
"Moves after split: " << copyMove->
toString()
1266 <<
" and "<< mn.
toString() << std::endl;
1287 for (std::map<MoveNode*, MoveNode*, MoveNode::Comparator>::iterator i =
1290 if (!i->first->isScheduled() && i->first != &mn) {
1291 if (i->first->isSourceVariable()) {
1293 i->first->move().source());
1318 std::set<TTAMachine::RegisterFile*, TTAMachine::MachinePart::Comparator>
1320 const MoveNode& mn,
bool tempRegAfter) {
1322 std::set<TTAMachine::RegisterFile*, TTAMachine::MachinePart::Comparator>
1325 std::map<int, int> rfDistanceFromSource;
1326 std::map<int, int> rfDistanceFromDestination;
1329 std::vector<std::pair<TTAMachine::RegisterFile*, int> > >
1332 std::string srDatumName =
"SCRATCH_REGISTERS";
1334 (dynamic_cast<TempRegData&>(
1338 "No scratch registers available for temporary moves.");
1340 const TempRegData& tempRegs =
1341 dynamic_cast<TempRegData&
>(
1345 for (
unsigned int i = 0; i < tempRegs.size(); i++) {
1346 rfDistanceFromSource[i] = INT_MAX;
1347 rfDistanceFromDestination[i] = INT_MAX;
1351 for (
unsigned int i = 0; i < tempRegs.size(); i++) {
1353 std::set<const TTAMachine::Port*> readPorts =
1355 std::set<const TTAMachine::Port*> writePorts =
1360 rfDistanceFromSource[i] = 1;
1366 rfDistanceFromDestination[i] = 1;
1375 bool modified =
true;
1376 if (!tempRegAfter) {
1377 while (result.empty() && modified) {
1378 int shortest = INT_MAX;
1380 for (
unsigned int i = 0; i < tempRegs.size(); i++) {
1381 int srcDist = rfDistanceFromSource[i];
1382 if (srcDist != INT_MAX) {
1384 for (
unsigned int j = 0; j < tempRegs.size(); j++) {
1385 if (rfDistanceFromSource[j] > srcDist + 1) {
1392 rfDistanceFromSource[j] = srcDist + 1;
1394 if (rfDistanceFromDestination[j] == 1) {
1395 int dist = srcDist + 2;
1396 if (dist < shortest) {
1400 if (dist == shortest) {
1401 result.insert(rfDest);
1412 while (result.empty() && modified) {
1413 int shortest = INT_MAX;
1415 for (
unsigned int i = 0; i < tempRegs.size(); i++) {
1416 int dstDist = rfDistanceFromDestination[i];
1417 if (dstDist != INT_MAX) {
1419 for (
unsigned int j = 0; j < tempRegs.size(); j++) {
1420 if (rfDistanceFromDestination[j] > dstDist + 1) {
1426 rfDistanceFromDestination[j] = dstDist + 1;
1428 if (rfDistanceFromSource[j] == 1) {
1429 int dst = dstDist + 2;
1430 if (dst < shortest) {
1434 if (dst == shortest) {
1435 result.insert(rfSrc);
bool successorsReady(MoveNode &node) const
DataDependenceGraph * ddg_
DDG of the currently scheduled BB.
void setAnnotation(const ProgramAnnotation &annotation)
bool scheduleOperandOrTrigger(MoveNode &operand, MoveNode *trigger, int latestCycle, bool allowRegCopies)
RegisterRenamer * renamer_
bool scheduleResults(ProgramOperation &po, int latestCycle, bool allowTempRegCopies)
void scheduleOperation(MoveNodeGroup &mng, MoveNodeSelector &selector)
int lastOperandCycle(const ProgramOperation &po)
bool guardsAllowBypass(const MoveNode &defNode, const MoveNode &useNode)
void setDestination(Terminal *dst)
void setMaxCycle(unsigned int maxCycle)
bool isOperationMove() const
static bool isConnected(const TTAMachine::Port &sourcePort, const TTAMachine::Port &destinationPort, TTAMachine::Guard *guard=NULL)
const TTAMachine::Machine * targetMachine_
The target machine we are scheduling the program against.
virtual void handleDDG(DataDependenceGraph &ddg, SimpleResourceManager &rm, const TTAMachine::Machine &targetMachine)
InterPassDatum & datum(const std::string &key)
void finalizeOperation(MoveNodeSelector &selector)
int inputMoveCount() const
bool isUnconditional() const
int outputMoveCount() const
TCEString toString() const
int latestTriggerWriteCycle() const
std::string toString() const
bool scheduleMoveUB(MoveNode &mn, int earlistCycle, int latestCycle)
Terminal & source() const
void createAntidepsFromUnscheduledRegCopies(MoveNode ©Node, MoveNode &mn, TTAProgram::Terminal &terminalRegister)
virtual bool dumpDDGsXML() const
bool connectOrDeleteEdge(const MoveNode &tailNode, const MoveNode &headNode, DataDependenceEdge *edge)
bool isSourceOperation() const
void unscheduleOperands(ProgramOperation &po)
MoveNode * onlyRegisterRawSource(const MoveNode &mn) const
int bypassNode(MoveNode &node, int maxHopCount)
virtual bool killDeadResults() const
std::pair< int, int > operandCycleLimits(MoveNode &mn, MoveNode *trigger)
static std::set< const TTAMachine::Port * > findReadPorts(TTAMachine::Unit &rf)
virtual bool dumpDDGsDot() const
void writeToXMLFile(std::string fileName) const
const BasicBlockNode & getBasicBlockNode(const MoveNode &mn) const
bool mergeAndKeep(MoveNode &resultNode, MoveNode &userNode)
Node & node(const int index) const
int scheduledNodeCount() const
virtual void assign(int cycle, MoveNode &node)
void unscheduleResults(ProgramOperation &po)
virtual TCEString name() const
static std::set< const TTAMachine::Port * > findWritePorts(TTAMachine::Unit &rf)
virtual void writeToDotFile(const TCEString &fileName) const
void addNode(MoveNode &moveNode)
virtual int latestCycle(MoveNode &node) const
virtual ControlUnit * controlUnit() const
static CmdLineOptions * cmdLineOptions()
void unschedule(MoveNode &mn)
ProgramOperation & destinationOperation(unsigned int index=0) const
std::string toString() const
virtual int operationIndex() const
MoveNode & outputMove(int index) const
BypassingBUBasicBlockScheduler(InterPassData &data, SoftwareBypasser *bypasser=NULL, CopyingDelaySlotFiller *delaySlotFiller=NULL, RegisterRenamer *registerRenamer=NULL)
bool isControlFlowMove() const
bool renameLiveRange(LiveRange &liveRange, const TCEString &newReg, bool usedBefore, bool usedAfter, bool loopScheduling)
std::set< MoveNode *, MoveNode::Comparator > removedNodes_
static bool canAnyPortWriteToDestination(std::set< const TTAMachine::Port *> &ports, const MoveNode &dest)
static int canSourceWriteToAnyDestinationPort(const MoveNode &src, std::set< const TTAMachine::Port *> &ports)
InterPassData & interPassData()
const Operation & operation() const
Unit * parentUnit() const
virtual std::string longDescription() const
virtual void notifyScheduled(MoveNode &node)=0
static void fixDDGEdgesInTempReg(DataDependenceGraph &ddg, MoveNode &originalMove, MoveNode *firstMove, MoveNode *lastMove, const TTAMachine::RegisterFile *lastRF, int lastRegisterIndex, BasicBlockNode ¤tBBNode, bool bottomUpScheduling)
MoveNode & inputMove(int index) const
TTAMachine::Guard & guard() const
bool isDestinationOperation() const
virtual void unassign(MoveNode &node)
void undoBypass(MoveNode &mn)
DataDependenceGraph::NodeSet writes
std::string toString() const
virtual ~BypassingBUBasicBlockScheduler()
virtual void removeNode(Node &node)
std::pair< MoveNode *, int > findBypassSource(MoveNode &node, int maxHopCount)
virtual HWOperation * operation(const std::string &name) const
std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
bool bypassAndScheduleNode(MoveNode &node, MoveNode *trigger, int latestCycle, bool allowRegCopies)
void ddgSnapshot(DataDependenceGraph &ddg, const std::string &name, DataDependenceGraph::DumpFileFormat format, bool final, bool resetCounter=false) const
static void findTempRegisters(const TTAMachine::Machine &machine, InterPassData &ipd)
std::map< MoveNode *, MoveNode *, MoveNode::Comparator > bypassSources_
bool bypassAndScheduleOperands(ProgramOperation &po, MoveNode *trigger, int latestCycle, bool allowRegCopies)
bool renameSourceRegister(MoveNode &node, bool loopScheduling, bool allowSameRf, bool differentRfOnlyDirectlyReachable, int latestCycle=INT_MAX)
virtual std::string shortDescription() const
ProgramOperation & sourceOperation() const
SimpleResourceManager * rm_
Resource Manager of the currently scheduled BB.
void setSelector(MoveNodeSelector *selector)
LiveRange * findLiveRange(MoveNode &lrNode, bool writingNode=true) const
LLVMTCECmdLineOptions * options_
void unscheduleOperation(ProgramOperation &po)
virtual MoveNodeGroup candidates()
std::map< MoveNode *, MoveNode *, MoveNode::Comparator > regCopiesAfter_
bool renameRegisters() const
virtual int earliestCycle(MoveNode &node) const
static std::set< const TTAMachine::Port * > findPossibleDestinationPorts(const TTAMachine::Machine &mach, const MoveNode &node)
int earliestCycle(const MoveNode &moveNode, unsigned int ii=UINT_MAX, bool ignoreRegWaRs=false, bool ignoreRegWaWs=false, bool ignoreGuards=false, bool ignoreFUDeps=false, bool ignoreSameOperationEdges=false) const
void initialize(DataDependenceGraph &ddg)
MoveNode * createTempRegCopy(MoveNode &mn, bool after)
MoveGuard & guard() const
static bool canTransportMove(MoveNode &moveNode, const TTAMachine::Machine &machine)
virtual void dropNode(Node &node)
MoveNode * findTrigger(ProgramOperation &po)
std::set< MoveNode *, MoveNode::Comparator > scheduledMoves_
#define abortWithError(message)
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
MoveNode & node(int index) const
void undoBypassAndUnschedule(MoveNode &mn)
void addAnnotation(const ProgramAnnotation &annotation)
void unMerge(MoveNode &resultNode, MoveNode &mergedNode)
A reg to reg move that was added because of missing connectivity between the original target and dest...
std::string toString() const
virtual const TTAMachine::Port & port() const
bool renameSourceIfNotConnected(MoveNode &moveNode, int latestCycle)
DataDependenceGraph::NodeSet reads
std::map< MoveNode *, MoveNode *, MoveNode::Comparator > regCopiesBefore_
int latestCycle(const MoveNode &moveNode, unsigned int ii=UINT_MAX, bool ignoreRegAntideps=false, bool ignoreUnscheduledSuccessors=true) const
#define assert(condition)
TTAProgram::Move & move()
bool scheduleMoveBU(MoveNode &mn, int earlistCycle, int latestCycle, TempRegCopyLocation t)
std::set< MoveNode *, MoveNode::Comparator > pendingBypassSources_
std::set< TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > possibleTempRegRFs(const MoveNode &mn, bool tempRegAfter)
void setSource(Terminal *src)
virtual void mightBeReady(MoveNode &node)=0
static TCEString registerName(const TTAMachine::RegisterFile &rf, int index, char delim='.')
bool resultUsed(MoveNode &resultNode)