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: "
841std::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
1115void BFOptimization::getDDGSnapshot() {
1116 if (
id() < CHECK_DDG_EQUALITY) {
1133void 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_;
#define assert(condition)
TTAMachine::Machine * machine
the architecture definition of the estimated processor
void mightBeReady(MoveNode &n) override
SimpleResourceManager & rm()
DataDependenceGraph & ddg()
TTAProgram::MoveGuard * jumpGuard()
BUMoveNodeSelector & selector()
MoveNodeDuplicator & duplicator()
static const int PROLOG_CYCLE_BIAS
const TTAMachine::Machine & targetMachine() const
DataDependenceGraph * prologDDG()
MoveNode * guardWriteNode()
SimpleResourceManager * prologRM()
BF2ScheduleFront * currentFront()
bool usePrologMove(const MoveNode &mn)
void assignCopyToPrologEpilog(int cycle, MoveNode &mn, MoveNode &loopMN, const TTAMachine::Bus *prologBus, int prologImmWriteCycle)
bool needJumpGuard(const MoveNode &mn, int cycle)
DataDependenceGraph * prologDDG()
virtual void mightBeReady(MoveNode &mn)
const TTAMachine::FunctionUnit * sourceFU(const MoveNode &mn)
bool addJumpGuardIfNeeded(MoveNode &mn, int cycle, bool ignoreGuardWriteCycle=false)
const TTAMachine::FunctionUnit * destinationFU(const MoveNode &mn)
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)
void setJumpGuard(MoveNode &mn)
const TTAMachine::FunctionUnit * fuOfTerminal(const TTAProgram::Terminal &t)
void setPrologFUAnnos(MoveNode &prologMN, MoveNode &loopMN)
void unassignCopyFromPrologEpilog(MoveNode &mh, bool disposePrologCopy=true)
void setPrologSrcFUAnno(MoveNode &prologMN, MoveNode &loopMN)
static MoveNode * getSisterTrigger(const MoveNode &mn, const TTAMachine::Machine &mach)
void checkPrologDDG(MoveNode &prologEpilogMN)
SimpleResourceManager * prologRM() const
bool hasAmbiguousResources(MoveNode &mn) const
std::pair< MoveNode *, bool > createCopyForPrologEpilog(MoveNode &mn)
void setPrologDstFUAnno(MoveNode &prologMN, MoveNode &loopMN)
BUMoveNodeSelector & selector()
DataDependenceGraph & ddg()
const TTAMachine::RegisterFile * RFReadPortCountPreventsScheduling(const MoveNode &mn)
virtual void unassign(MoveNode &mn, bool disposePrologCopy=true)
DataDependenceGraph * rootDDG()
bool immCountPreventsScheduling(const MoveNode &mn)
int jumpGuardAvailableCycle(const MoveNode &mn)
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)
const TTAMachine::Machine & targetMachine() const
bool canBeScheduled(const MoveNode &mn)
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)
static void clearPrologMoves()
MoveNodeDuplicator & duplicator() const
SimpleResourceManager & rm() const
static std::map< MoveNode *, MoveNode *, MoveNode::Comparator > prologMoves_
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)
void unsetJumpGuard(MoveNode &mn)
bool canBeSpeculated(const Operation &op)
void unsetJumpGuardIfNeeded(MoveNode &mn, int cycle)
static MoveNode * findTrigger(const ProgramOperation &po, const TTAMachine::Machine &mach)
virtual Node & headNode(const Edge &edge) const
virtual EdgeSet outEdges(const Node &node) const
virtual Node & tailNode(const Edge &edge) const
virtual EdgeSet inEdges(const Node &node) const
virtual TCEString dotString() const
Dot printing related methods.
void removeIncomingGuardEdges(MoveNode &node)
virtual void writeToDotFile(const TCEString &fileName) const
static bool canTransportMove(const MoveNode &moveNode, const TTAMachine::Machine &machine, bool ignoreGuard=false)
static int maxLIMMCount(const TTAMachine::Machine &targetMachine)
static bool canTransportImmediate(const TTAProgram::TerminalImmediate &immediate, const TTAMachine::BaseRegisterFile &destRF, const TTAMachine::Guard *guard=NULL)
static int maxSIMMCount(const TTAMachine::Machine &targetMachine)
void disposeMoveNode(MoveNode *newMN)
std::pair< MoveNode *, bool > duplicateMoveNode(MoveNode &mn, bool addToDDG, bool ignoreSameBBBackEdges)
bool isGuardOperation() const
ProgramOperation & sourceOperation() const
bool isDestinationOperation() const
std::string toString() const
TTAProgram::Move & move()
bool isSourceOperation() const
bool isSourceImmediateRegister() const
bool isSourceConstant() const
ProgramOperation & destinationOperation(unsigned int index=0) const
virtual TCEString name() const
virtual bool usesMemory() const
virtual bool isControlFlowOperation() const
virtual bool hasSideEffects() const
virtual int affectsCount() const
static std::string disassemble(const TTAProgram::Move &move)
const Operation & operation() const
int inputMoveCount() const
std::string toString() const
MoveNode & inputMove(int index) const
virtual int smallestCycle() const override
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 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
virtual void unassign(MoveNode &node) override
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 TTAProgram::Instruction * instruction(int cycle) const override
virtual int largestCycle() const override
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
virtual TCEString name() const
int globalGuardLatency() const
virtual HWOperation * operation(const std::string &name) const
virtual FUPort * port(int operand) const
virtual ControlUnit * controlUnit() const
virtual int maxReads() const
void removeAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID)
int annotationCount(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
void setAnnotation(const ProgramAnnotation &annotation)
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
std::string toString() const
const TTAMachine::Guard & guard() const
bool isControlFlowMove() const
bool isUnconditional() const
Terminal & source() const
void setGuard(MoveGuard *guard)
Terminal & destination() const
const TTAMachine::Bus & bus() const
ProgramAnnotation::Id id() const
@ ANN_CONN_CANDIDATE_UNIT_DST
Dst. unit candidate.
@ ANN_CONN_CANDIDATE_UNIT_SRC
Src. unit candidate.
@ ANN_ALLOWED_UNIT_SRC
Candidate units can be passed for resource manager for choosing the source/destination unit of the mo...
std::string stringValue() const
virtual const TTAMachine::FunctionUnit & functionUnit() const
virtual int index() const
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
virtual const TTAMachine::RegisterFile & registerFile() const
virtual bool isFUPort() const