Go to the documentation of this file.
65 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
67 #define DEBUG_LOOP_SCHEDULER
109 int prologImmWriteCycle,
114 bool createdPrologCopy =
false;
115 #ifdef DEBUG_LOOP_SCHEDULER
117 std::cerr <<
"\t\t\t\tAssigning in loop sched: " << mn.
toString()
118 <<
" to cycle: " << cycle <<
" imm write cycle: "
119 << immWriteCycle << std::endl;
122 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
123 std::cerr <<
"\t\t\t\t\tAssigning mn: " << mn.
toString()
124 <<
" imm write cycle: " << immWriteCycle << std::endl;
132 prologEpilogMN = a.first;
133 createdPrologCopy = a.second;
138 std::cerr <<
"Adding jump guard failed for node: "
144 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
146 cycle, mn, bus, srcFU, dstFU, immWriteCycle, immu, immRegIndex)) {
147 std::cerr <<
"cannot assign move in assign: " << mn.
toString()
148 <<
" cycle: " << cycle << std::endl;
150 std::cerr <<
"set bus: " << m.
bus().
name() << std::endl;
152 std::cerr <<
"bus: " << bus->
name() << std::endl;
155 std::cerr <<
"src FU: " << srcFU->
name() << std::endl;
158 std::cerr <<
"dst FU: " << dstFU->
name() << std::endl;
161 std::cerr <<
"annotations:" << std::endl;
164 std::cerr <<
"\thas anno, id: " << anno.
id()
172 std::cerr <<
"Destination op: "
181 cycle, mn, bus, srcFU, dstFU, immWriteCycle, immu, immRegIndex);
182 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
183 std::cerr <<
"\t\t\t\t\tAssigned mn: " << mn.
toString() << std::endl;
188 prologImmWriteCycle);
189 #ifdef CHECK_PROLOG_DDG
193 return createdPrologCopy;
197 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
198 std::cerr <<
"\t\t\t\t\tUnassigning mn: " << mn.
toString()
199 <<
"dispose: " << disposePrologCopy << std::endl;
201 int cycle = mn.
cycle();
208 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
209 std::cerr <<
"\t\t\t\t\tUnassignined mn: " << mn.
toString() << std::endl;
219 int prologImmWriteCycle,
222 #ifdef DEBUG_LOOP_SCHEDULER
224 std::cerr <<
"\t\t\t\t\tbfopt::rmec called, cycle: " << cycle
230 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
231 std::cerr <<
"\t\t\t\t\tCalling rmec for: " << mn.
toString()
232 <<
" cycle: " << cycle <<
"dispose: "
233 << disposePrologCopy << std::endl;
238 cycle, mn, bus, srcFU, dstFU, immWriteCycle, immu, immRegIndex);
246 bool createdCopy =
false;
251 createdCopy = a.second;
254 bool setGuard =
false;
256 cycle, mn, bus, srcFU, dstFU, immWriteCycle, immu, immRegIndex);
257 if (ec == INT_MAX || ec == -1) {
258 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
259 std::cerr <<
"\t\t\t\t\trmec over with -1" << std::endl;
267 while (ec < (
signed)(2*
ii())) {
290 ec, mn, bus, srcFU, dstFU, immWriteCycle, immu, immRegIndex);
296 ec, mn, bus, srcFU, dstFU, immWriteCycle);
299 ec = std::min(newEC, (
signed)(
ii()));
313 bool assignedMN =
false;
314 auto mySrcFU = srcFU;
315 auto myDstFU = dstFU;
317 auto myImmReg = immRegIndex;
319 rm().
assign(ec, mn, bus, srcFU, dstFU, immWriteCycle, immu,
331 mySrcFU, myDstFU, prologImmWriteCycle, myImmu, myImmReg);
357 #ifdef DEBUG_LOOP_SCHEDULER
358 std::cerr <<
"\t\t\t\t\trmec over" << std::endl;
369 int prologImmWriteCycle,
372 #ifdef DEBUG_LOOP_SCHEDULER
374 std::cerr <<
"\t\t\t\t\tbfopt::rmlc called, cycle: " << cycle
375 <<
" mn: " << mn.
toString() << std::endl;
378 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
379 std::cerr <<
"\t\t\t\t\tbfopt::rmlc called, cycle: " << cycle
380 <<
" mn: " << mn.
toString() << std::endl;
384 bool setGuard =
false;
386 bool createdCopy =
false;
391 createdCopy = a.second;
395 lc =
rm().
latestCycle(lc,mn, bus, srcFU, dstFU, immWriteCycle);
396 #ifdef DEBUG_LOOP_SCHEDULER
398 std::cerr <<
"\t\t\t\t\tgot lc from rm: " << lc << std::endl;
401 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
402 std::cerr <<
"\t\t\t\t\tgot lc from rm: " << lc << std::endl;
409 #ifdef DEBUG_LOOP_SCHEDULER
410 std::cerr <<
"\t\t\t\t\tNeed jump guard for mn: "
411 << mn.
toString() <<
" cycle: " << lc << std::endl;
414 #ifdef DEBUG_LOOP_SCHEDULER
415 std::cerr <<
"\t\t\t\t\tjump guard not yet available so "
416 <<
"cannot schedule this ever" << std::endl;
443 bool assignedMN =
false;
444 auto mySrcFU = srcFU;
445 auto myDstFU = dstFU;
447 auto myImmReg = immRegIndex;
450 rm().
assign(lc, mn, bus, srcFU, dstFU, immWriteCycle);
461 mySrcFU, myDstFU, prologImmWriteCycle, myImmu, myImmReg);
466 #ifdef DEBUG_LOOP_SCHEDULER
467 std::cerr <<
"prolog RM cannot assign to cycle: "
469 std::cerr <<
"instr in prolog rm: " <<
501 int prologImmWriteCycle,
504 bool ignoreGuardWriteNode) {
505 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
507 std::cerr <<
"\t\t\t\t\tCalling BFOpt::canassign for: "
508 << mn.
toString() <<
" cycle: " << cycle << std::endl;
510 std::cerr <<
"\t\t\t\t\tCalling BFOpt::canassign for: "
511 << mn.
toString() <<
" cycle: " << cycle << std::endl;
514 std::cerr <<
"\t\t\t\t\t\tBus: " << bus->
name() << std::endl;
517 std::cerr <<
"\t\t\t\t\t\tProlog bus: " << prologBus->
name()
521 std::cerr <<
"\t\t\t\t\t\tSrc FU: " << srcFU->
name() << std::endl;
524 std::cerr <<
"\t\t\t\t\t\tDst FU: " << dstFU->
name() << std::endl;
527 std::cerr <<
"\t\t\t\t\t\tDst po: "
533 #ifdef DEBUG_LOOP_SCHEDULER
534 std::cerr <<
"\t\t\t\t\t\tNeed jump guard, cycle: " << cycle
535 <<
"ii: " <<
ii() << std::endl;
539 #ifdef DEBUG_LOOP_SCHEDULER
540 std::cerr <<
"\t\t\t\t\tcanassin over with uncond" << std::endl;
545 #ifdef DEBUG_LOOP_SCHEDULER
546 std::cerr <<
"\t\t\t\t\tjump guard not yet available so"
547 <<
" cannot scheudle this." << std::endl;
548 std::cerr <<
"\t\t\t\t\t\tAvailable on cycle: "
556 cycle, mn, bus, srcFU, dstFU, immWriteCycle, immu, immRegIndex);
557 #ifdef DEBUG_LOOP_SCHEDULER
559 std::cerr <<
"\t\t\t\t\t for this: " << ok <<
" , what about prolog?"
566 if (ok && usePrologMN) {
572 #ifdef DEBUG_LOOP_SCHEDULER
573 std::cerr <<
"\t\t\t\t\t\tProlog mn: " << prologMN->
toString()
576 bool assignedMN =
false;
578 rm().
assign(cycle, mn, bus, srcFU, dstFU, immWriteCycle, immu,
590 srcFU, dstFU, prologImmWriteCycle, immu, immRegIndex);
600 #ifdef DEBUG_LOOP_SCHEDULER
602 std::cerr <<
"\t\t\t\t\tcanassin over:" << ok << std::endl;
605 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
606 std::cerr <<
"\t\t\t\t\tcanassin over:" << ok << std::endl;
613 #ifdef DEBUG_LOOP_SCHEDULER
614 std::cerr <<
"\t\t\t\t\tsetting jump guard to: " << mn.
toString()
619 std::cerr <<
"Cannot set jump guard because already conditional: "
656 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
657 std::cerr <<
"\t\t\t\t\tset jump guard: " << mn.
toString() << std::endl;
663 #ifdef DEBUG_LOOP_SCHEDULER
664 std::cerr <<
"\t\t\t\t\tunsetting jump guard from: "
669 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
670 std::cerr <<
"\t\t\t\t\tunset jump guard: " << mn.
toString() << std::endl;
690 #ifdef DEBUG_LOOP_SCHEDULER
691 std::cerr <<
"\t\tSetting src Fu anno, loop MN: "
692 << loopMN.
toString() <<
" prolog MN: "
693 << prologMN.
toString() << std::endl;
712 #ifdef DEBUG_LOOP_SCHEDULER
713 std::cerr <<
"\t\tSetting dst Fu anno, loop MN: "
714 << loopMN.
toString() <<
" prolog MN: "
715 << prologMN.
toString() << std::endl;
750 int prologImmWriteCycle) {
753 int immRegIndex = -1;
759 #ifdef DEBUG_LOOP_SCHEDULER
760 std::cerr <<
"\t\t\t\t\tAssigning copy to prolog: " << cycle
768 immu, immRegIndex)) {
771 std::cerr << std::endl <<
"Cannot assign move to prolog! "
772 << prologMN.
toString() << std::endl << std::endl;
773 std::cerr <<
"Preassigned bus: " << m.
bus().
name() << std::endl;
774 if (prologBus !=
nullptr) {
775 std::cerr <<
"prolog bus: " << prologBus->
name() << std::endl;
777 std::cerr <<
"Cycle: " << cycle <<
" prolog cycle: "
781 std::cerr <<
"destpo: "
790 for (
int i = sc; i <= lc; i++) {
791 std::cerr <<
"\t" << i <<
"\t"
795 assert(
false &&
"Cannot asign copy to prolog");
803 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
804 std::cerr <<
"\t\tAassigned copy to prolog, original mn: "
806 <<
" copy: " << prologMN.
toString() << std::endl;
811 MoveNode& mn,
bool disposePrologCopy) {
812 #ifdef DEBUG_LOOP_SCHEDULER
813 std::cerr <<
"\t\tUnassigning copy from prolog, original mn: "
815 << disposePrologCopy << std::endl;
821 #ifdef DEBUG_LOOP_SCHEDULER
822 std::cerr <<
"\t\t\tcopy after unassign: " << copy->
toString()
825 if (disposePrologCopy) {
829 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
831 std::cerr <<
"\t\t\tCopy not found." << std::endl;
834 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
835 std::cerr <<
"\t\tUnassigned copy from prolog, original mn: "
841 std::map<MoveNode*, MoveNode*, MoveNode::Comparator>
871 if (&mn != trig && trig != NULL) {
879 if (cycle >= (
int)(
ii())) {
890 bool ignoreGuardWriteCycle) {
893 #ifdef DEBUG_LOOP_SCHEDULER
894 std::cerr <<
"jump guard available at "
896 <<
" , not in cycle: " << cycle << std::endl;
901 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
902 std::cerr <<
"Cannot add guard to already-conditional move "
921 #ifdef DEBUG_LOOP_SCHEDULER
922 std::cerr <<
"jump node is null or guard operation!" << std::endl;
927 #ifdef DEBUG_LOOP_SCHEDULER
928 std::cerr <<
"Guard write node not known!" << std::endl;
933 #ifdef DEBUG_LOOP_SCHEDULER
934 std::cerr <<
"I AM guard write node!" << std::endl << std::endl;
939 #ifdef DEBUG_LOOP_SCHEDULER
940 std::cerr <<
"guardwrite node is null or not sched:"
981 auto& move = mn.
move();
982 if (!move.source().isImmediate()) {
996 auto& inputMove = input.
move();
1000 auto port = hwop->
port(move.destination().operationIndex());
1001 if (!port->noRegister()) {
1004 if (inputMove.source().isImmediate()) {
1007 if (inputMove.source().isImmediateRegister()) {
1011 if (simmCount + limmCount < 1) {
1015 if (limmCount < 1 &&
1018 move.source()), *port,
1019 move.isUnconditional()
1021 : &move.guard().guard())) {
1032 auto& move = mn.
move();
1033 if (!move.source().isGPR()) {
1047 auto& inputMove = input.
move();
1051 auto port = hwop->
port(move.destination().operationIndex());
1052 if (!port->noRegister()) {
1055 if (inputMove.source().isGPR() &&
1056 &inputMove.source().registerFile() == &rf) {
1058 if (freeRFPorts < 1) {
1083 for (
auto e: oEdges) {
1092 std::cerr <<
"Illegal assign of: " << prologEpilogMN.
toString()
1098 for (
auto e: iEdges) {
1107 std::cerr <<
"Illegal assign(2) of: " << prologEpilogMN.
toString()
1114 #ifdef CHECK_DDG_EQUALITY
1115 void BFOptimization::getDDGSnapshot() {
1116 if (
id() < CHECK_DDG_EQUALITY) {
1133 void BFOptimization::checkDDGEquality() {
1135 if (
id() < CHECK_DDG_EQUALITY) {
1140 if (ddgECount != ddgECount_ ) {
1141 std::cerr <<
"ddg changed! id:" <<
id() << std::endl;
1143 std::ofstream output(
"before.dot");
1144 output << ddgString_;
1150 if (prologDDGString_ !=
"") {
1151 if (
prologDDG()->edgeCount() != prologDDGECount_ ||
1152 prologDDG()->nodeCount() != prologDDGNCount_) {
1154 std::cerr <<
"prolog ddg changed! id: " <<
id() << std::endl;
1156 std::ofstream output(
"before.dot");
1157 output << prologDDGString_;
const Operation & operation() const
virtual bool isFUPort() const
virtual void unassign(MoveNode &mn, bool disposePrologCopy=true)
const TTAMachine::FunctionUnit * sourceFU(const MoveNode &mn)
void removeIncomingGuardEdges(MoveNode &node)
virtual bool canAssign(int cycle, MoveNode &node, const TTAMachine::Bus *bus=NULL, const TTAMachine::FunctionUnit *srcFU=NULL, const TTAMachine::FunctionUnit *dstFU=NULL, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const override
virtual bool assign(int cycle, MoveNode &, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU_=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, const TTAMachine::Bus *prologBus=nullptr, int immWriteCycle=-1, int prologImmWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1, bool ignoreGuardWriteCycle=false)
virtual Node & tailNode(const Edge &edge) const
virtual TCEString name() const
virtual int largestCycle() const override
MoveNodeDuplicator & duplicator() const
std::string toString() const
virtual bool hasSideEffects() const
virtual int index() const
TTAMachine::Machine * machine
the architecture definition of the estimated processor
virtual Node & headNode(const Edge &edge) const
virtual const TTAMachine::RegisterFile & registerFile() const
const TTAMachine::RegisterFile * RFReadPortCountPreventsScheduling(const MoveNode &mn)
bool isDestinationOperation() const
void unsetJumpGuardIfNeeded(MoveNode &mn, int cycle)
virtual int smallestCycle() const override
bool isUnconditional() const
static bool canTransportImmediate(const TTAProgram::TerminalImmediate &immediate, const TTAMachine::BaseRegisterFile &destRF, const TTAMachine::Guard *guard=NULL)
std::string stringValue() const
bool needJumpGuard(const MoveNode &mn, int cycle)
void setPrologFUAnnos(MoveNode &prologMN, MoveNode &loopMN)
void setAnnotation(const ProgramAnnotation &annotation)
const TTAMachine::Machine & targetMachine() const
Terminal & destination() const
DataDependenceGraph & ddg()
DataDependenceGraph * prologDDG()
std::string toString() const
const TTAMachine::Bus & bus() const
static MoveNode * getSisterTrigger(const MoveNode &mn, const TTAMachine::Machine &mach)
void setGuard(MoveGuard *guard)
bool isSourceConstant() const
bool hasAmbiguousResources(MoveNode &mn) const
static bool canTransportMove(const MoveNode &moveNode, const TTAMachine::Machine &machine, bool ignoreGuard=false)
virtual void assign(int cycle, MoveNode &node, const TTAMachine::Bus *bus=NULL, const TTAMachine::FunctionUnit *srcFU=NULL, const TTAMachine::FunctionUnit *dstFU=NULL, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) override
virtual int rmEC(int cycle, MoveNode &mn, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, const TTAMachine::Bus *prologBus=nullptr, int immWriteCycle=-1, int prologImmWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1)
virtual TCEString name() const
virtual void unassign(MoveNode &node) override
void checkPrologDDG(MoveNode &prologEpilogMN)
const TTAMachine::FunctionUnit * fuOfTerminal(const TTAProgram::Terminal &t)
const TTAMachine::Machine & targetMachine() const
MoveNodeDuplicator & duplicator()
bool canBeSpeculated(const Operation &op)
bool isSourceImmediateRegister() const
std::pair< MoveNode *, bool > duplicateMoveNode(MoveNode &mn, bool addToDDG, bool ignoreSameBBBackEdges)
static MoveNode * findTrigger(const ProgramOperation &po, const TTAMachine::Machine &mach)
ProgramOperation & sourceOperation() const
#define assert(condition)
virtual FUPort * port(int operand) const
@ ANN_ALLOWED_UNIT_SRC
Candidate units can be passed for resource manager for choosing the source/destination unit of the mo...
bool usePrologMove(const MoveNode &mn)
ProgramAnnotation::Id id() const
bool isGuardOperation() const
@ ANN_CONN_CANDIDATE_UNIT_SRC
Src. unit candidate.
virtual TCEString dotString() const
Dot printing related methods.
virtual ControlUnit * controlUnit() const
virtual int maxReads() const
SimpleResourceManager * prologRM() const
bool isControlFlowMove() const
DataDependenceGraph * prologDDG()
void disposeMoveNode(MoveNode *newMN)
void mightBeReady(MoveNode &n) override
TTAProgram::MoveGuard * jumpGuard()
void assignCopyToPrologEpilog(int cycle, MoveNode &mn, MoveNode &loopMN, const TTAMachine::Bus *prologBus, int prologImmWriteCycle)
void setPrologSrcFUAnno(MoveNode &prologMN, MoveNode &loopMN)
DataDependenceGraph * rootDDG()
std::pair< MoveNode *, bool > createCopyForPrologEpilog(MoveNode &mn)
BUMoveNodeSelector & selector()
static int maxSIMMCount(const TTAMachine::Machine &targetMachine)
virtual int earliestCycle(MoveNode &node, const TTAMachine::Bus *bus=NULL, const TTAMachine::FunctionUnit *srcFU=NULL, const TTAMachine::FunctionUnit *dstFU=NULL, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const override
bool isSourceOperation() const
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
void setPrologDstFUAnno(MoveNode &prologMN, MoveNode &loopMN)
DataDependenceGraph & ddg()
static std::map< MoveNode *, MoveNode *, MoveNode::Comparator > prologMoves_
const TTAMachine::FunctionUnit * destinationFU(const MoveNode &mn)
int jumpGuardAvailableCycle(const MoveNode &mn)
bool canBeScheduled(const MoveNode &mn)
SimpleResourceManager & rm() const
int inputMoveCount() const
virtual EdgeSet inEdges(const Node &node) const
void setJumpGuard(MoveNode &mn)
virtual void writeToDotFile(const TCEString &fileName) const
SimpleResourceManager * prologRM()
static const int PROLOG_CYCLE_BIAS
virtual const TTAMachine::FunctionUnit & functionUnit() const
virtual bool usesMemory() const
virtual EdgeSet outEdges(const Node &node) const
ProgramOperation & destinationOperation(unsigned int index=0) const
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
static void clearPrologMoves()
TTAProgram::Move & move()
std::string toString() const
static std::string disassemble(const TTAProgram::Move &move)
bool addJumpGuardIfNeeded(MoveNode &mn, int cycle, bool ignoreGuardWriteCycle=false)
SimpleResourceManager & rm()
BF2ScheduleFront * currentFront()
void unassignCopyFromPrologEpilog(MoveNode &mh, bool disposePrologCopy=true)
virtual int rmLC(int cycle, MoveNode &mn, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, const TTAMachine::Bus *prologBus=nullptr, int immWriteCycle=-1, int prologImmWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1)
virtual int latestCycle(MoveNode &node, const TTAMachine::Bus *bus=NULL, const TTAMachine::FunctionUnit *srcFU=NULL, const TTAMachine::FunctionUnit *dstFU=NULL, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const override
BUMoveNodeSelector & selector()
void unsetJumpGuard(MoveNode &mn)
Terminal & source() const
bool immCountPreventsScheduling(const MoveNode &mn)
virtual HWOperation * operation(const std::string &name) const
MoveNode * guardWriteNode()
const TTAMachine::Guard & guard() const
void removeAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID)
int globalGuardLatency() const
virtual int affectsCount() const
virtual bool canAssign(int cycle, MoveNode &mn, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, const TTAMachine::Bus *prologBus=nullptr, int immWriteCycle=-1, int prologImmWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1, bool ignoreGWN=false)
virtual void mightBeReady(MoveNode &mn)
MoveNode & inputMove(int index) const
virtual bool isControlFlowOperation() const
int annotationCount(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
virtual TTAProgram::Instruction * instruction(int cycle) const override
@ ANN_CONN_CANDIDATE_UNIT_DST
Dst. unit candidate.
static int maxLIMMCount(const TTAMachine::Machine &targetMachine)