OpenASIP  2.0
BFPushMoveUp.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2014 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 
25 /**
26  * @file BFPushMoveUp.cc
27  *
28  * Definition of BFPushMoveUp class
29  *
30  * Tries to (recursively) reschedule move (and it's predecessors)
31  * into earlier cycle.
32  *
33  * @author Heikki Kultala 2014-2020(heikki.kultala-no.spam-tuni.fi)
34  * @note rating: red
35  */
36 
37 #include "BFPushMoveUp.hh"
38 #include "DataDependenceGraph.hh"
39 #include "BFPushDepsUp.hh"
40 #include "Move.hh"
41 #include "BF2Scheduler.hh"
42 #include "Terminal.hh"
43 
44 //#define DEBUG_BUBBLEFISH_SCHEDULER
45 
46 bool
48 
49 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
50  static int dotCount = 0;
51 #endif
52  bool isTrigger = mn_.isDestinationOperation() &&
54 
55  if (lc_ == -1) {
56  std::cerr << "incoming lc -1 on pushmoveup!" << std::endl;
57  assert(false);
58  }
59  if (mn_.move().isControlFlowMove()) {
60 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
61  std::cerr << "\t\t|TCannot reschedule control flow move!" << std::endl;
62 #endif
63  return false;
64  }
65 
66  if (&mn_ == sched_.guardWriteNode()) {
67 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
68  std::cerr << "\t\t|TCannot reschedule guard write move!" << std::endl;
69 #endif
70  return false;
71  }
72 
73 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
75 
76  for (int i = 0; i < recurseCounter_*2; i++)
77  std::cerr << "\t";
78 
79  std::cerr << "\t\tPushing move up: " << mn_.toString() << " to cycle: "
80  << lc_ << std::endl;
81 #endif
82 
83  // first push operands if I'm trigger?
84  if (isTrigger && mn_.destinationOperation().inputMoveCount() > 1) {
86  for (int i = 0; i < dstPO.inputMoveCount(); i++) {
87  MoveNode& input = dstPO.inputMove(i);
88  if (input.isScheduled() &&
89  !input.move().destination().isTriggering()) {
90  if (input.cycle() > lc_) {
91  // TODO: what if this fails??
92  runPreChild(new BFPushMoveUp(sched_, input, lc_));
93  }
94  }
95  }
96  }
98 
99  int ddgLC = ddg().latestCycle(mn_,ii());
100  int ddgEC = ddg().earliestCycle(mn_,ii());
101 
102  if (ddgLC == -1) {
103 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
104  std::cerr << "ddg latest cycle -1 in pushmoveup of:"
105  << mn_.toString() << std::endl;
106 #endif
107  returnOriginal();
108  return false;
109  }
110 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
111  for (int i = 0; i < recurseCounter_*2; i++)
112  std::cerr << "\t";
113 
114  std::cerr << "\t\tPushing move: " << mn_.toString()
115  << " up, ddgLC now: " << ddgLC << std::endl;
116 #endif
117  int lc = std::min(lc_, ddgLC);
118  int rmlc = rmLC(lc, mn_);
119 
120  if (ddgEC > lc) {
121 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
122  for (int i = 0; i < recurseCounter_*2; i++)
123  std::cerr << "\t";
124 
125  std::cerr << "\t\tMay need to push predecessors.." << std::endl;
126 #endif
127  BFPushDepsUp* pusher = new BFPushDepsUp(sched_, mn_, lc);
128  if ((*pusher)()) {
129  midChildren_.push(pusher);
130  ddgEC = ddg().earliestCycle(mn_, ii());
131  if (ddgEC > lc) {
132  std::cerr << "\t\tDDG earliest cycle still too early: "
133  << ddgEC << std::endl;
134  ddg().writeToDotFile("ec_still_early.dot");
135  assert(false);
136  }
137 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
138  for (int i = 0; i < recurseCounter_*2; i++)
139  std::cerr << "\t";
140 
141  std::cerr << "\t\tPredecessors pushed ok!" << std::endl;
142 #endif
143 // assert(ddg().earliestCycle(mn_) <= lc);
144  } else {
145 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
146 
147  for (int i = 0; i < recurseCounter_*2; i++)
148  std::cerr << "\t";
149 
150  std::cerr << "\t\tDDG ec too late, Need to recursively push more,"
151  << " which failed" << std::endl;
152 #endif
153  delete pusher;
154  returnOriginal();
156 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
157  recurseCounter_--;
158 #endif
159  return false;
160  }
161  // TODO: this is buggy. should have back edge
162  ddgLC = ddg().latestCycle(mn_,ii());
163 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
164  for (int i = 0; i < recurseCounter_*2; i++)
165  std::cerr << "\t";
166 
167  std::cerr << "\t\tddgLC of " << mn_.toString()
168  << " after pushing preds: " << ddgLC << std::endl;
169 #endif
170  rmlc = rmLC(std::min(lc_, ddgLC), mn_);
171  }
172  if (rmlc == -1 || rmlc < ddgEC) {
173  if (lc < 1) {
174 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
175  std::cerr << "\t\tlc too small, cannot push again" << std::endl;
176 #endif
178  returnOriginal();
180 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
181  recurseCounter_--;
182 #endif
183  return false;
184  }
185 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
186  for (int i = 0; i < recurseCounter_*2; i++)
187  std::cerr << "\t";
188 
189  std::cerr << "\t\trmlc problem: " <<rmlc
190  << "ddgec: " << ddgEC << std::endl;
191  TCEString dotName("rm_-1_pushup");
192  dotName << mn_.nodeID() << "_" << ii() << "_" << dotCount++ << ".dot";
193  std::cerr << "Writing dot: " << dotName << std::endl;
194  ddg().writeToDotFile(dotName);
195 
196  for (int i = 0; i < recurseCounter_*2; i++)
197  std::cerr << "\t";
198 
199  std::cerr << "\t\tRM lc -1 when pushing move up, failing:"
200  << mn_.toString() << " target cycle: " << lc_ << std::endl;
201 
202  for (int i = 0; i < recurseCounter_*2; i++)
203  std::cerr << "\t";
204 
205  std::cerr << "\t\tddgLC is: " << ddgLC << std::endl;
206 // assert(false);
207 
208  std::cerr << "Trying to push preds one more up." << std::endl;
209 
210 #endif
211  BFPushDepsUp* pusher2 = new BFPushDepsUp(sched_, mn_, lc-1);
212  bool fail = false;
213 
214  if ((*pusher2)()) {
215  midChildren_.push(pusher2);
216  ddgEC = ddg().earliestCycle(mn_, ii());
217  if (ddgEC > lc) {
218  std::cerr << "\t\tDDG earliest cycle STILL too early: "
219  << ddgEC << std::endl;
220  ddg().writeToDotFile("ec_still_early.dot");
221  assert(false);
222  }
223  ddgLC = ddg().latestCycle(mn_,ii());
224  rmlc = rmLC(std::min(lc_, ddgLC), mn_);
225  if (rmlc == -1 || rmlc < ddgEC) {
226 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
227  std::cerr << "still failing, now giving up" << std::endl;
228 #endif
229  fail = true;
230  }
231  } else {
232  delete pusher2;
233  fail = true;
234  }
235 
236  if (fail) {
237  for (int i = 0; i < recurseCounter_*2; i++)
238  std::cerr << "\t";
239 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
240  std::cerr << "\t\tUndoing recursive pushs of predecessors"
241  << std::endl;
242 #endif
244 
245 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
246  for (int i = 0; i < recurseCounter_*2; i++)
247  std::cerr << "\t";
248 
249  std::cerr << "\t\tReturning the original" << std::endl;
250 #endif
253 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
254 
255  for (int i = 0; i < recurseCounter_*2; i++)
256  std::cerr << "\t";
257 
258  std::cerr << "\t\treturned original: "<<mn_.toString()
259  << std::endl;
260  recurseCounter_--;
261 #endif
262  return false;
263  }
264  }
265 
266  assign(rmlc, mn_);
267 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
268  for (int i = 0; i < recurseCounter_*2; i++)
269  std::cerr << "\t";
270 
271  std::cerr << "\tPushed move successfully: " << mn_.toString()
272  << std::endl;
273  recurseCounter_--;
274 #endif
275  return true;
276 }
BFPushDepsUp
Definition: BFPushDepsUp.hh:43
TTAProgram::Terminal::isTriggering
virtual bool isTriggering() const
Definition: Terminal.cc:298
BFOptimization::assign
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)
Definition: BFOptimization.cc:103
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
Reversible::undoAndRemoveChildren
void undoAndRemoveChildren(std::stack< Reversible * > &children)
Definition: Reversible.cc:55
MoveNode::isDestinationOperation
bool isDestinationOperation() const
BFOptimization::ii
unsigned int ii() const
Definition: BFOptimization.cc:85
BFUnscheduleMove::returnOriginal
void returnOriginal()
Definition: BFUnscheduleMove.cc:107
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
GraphNode::nodeID
int nodeID() const
BFPushMoveUp.hh
DataDependenceGraph.hh
ProgramOperation
Definition: ProgramOperation.hh:70
MoveNode
Definition: MoveNode.hh:65
Terminal.hh
Reversible::preChildren_
std::stack< Reversible * > preChildren_
Definition: Reversible.hh:57
BFPushMoveUp::lc_
int lc_
Definition: BFPushMoveUp.hh:55
BFOptimization::sched_
BF2Scheduler & sched_
Definition: BFOptimization.hh:103
BFUnscheduleMove::mn_
MoveNode & mn_
Definition: BFUnscheduleMove.hh:61
assert
#define assert(condition)
Definition: Application.hh:86
MoveNode::cycle
int cycle() const
Definition: MoveNode.cc:421
BF2Scheduler.hh
TTAProgram::Move::isControlFlowMove
bool isControlFlowMove() const
Definition: Move.cc:233
BFUnscheduleMove::recurseCounter_
static int recurseCounter_
Definition: BFUnscheduleMove.hh:71
BFRescheduleMove::midChildren_
std::stack< Reversible * > midChildren_
Definition: BFRescheduleMove.hh:55
BFPushMoveUp::BFPushMoveUp
BFPushMoveUp(BF2Scheduler &sched, MoveNode &mn, int lc)
Definition: BFPushMoveUp.hh:50
BFOptimization::ddg
DataDependenceGraph & ddg()
Definition: BFOptimization.cc:70
BFPushMoveUp::operator()
bool operator()()
Definition: BFPushMoveUp.cc:47
ProgramOperation::inputMoveCount
int inputMoveCount() const
Definition: ProgramOperation.cc:600
GraphBase::writeToDotFile
virtual void writeToDotFile(const TCEString &fileName) const
DataDependenceGraph::earliestCycle
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, bool assumeBypassing=false) const
Definition: DataDependenceGraph.cc:388
MoveNode::destinationOperation
ProgramOperation & destinationOperation(unsigned int index=0) const
BFUnscheduleMove::unscheduleOriginal
void unscheduleOriginal()
Definition: BFUnscheduleMove.cc:47
MoveNode::move
TTAProgram::Move & move()
BFOptimization::rmLC
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)
Definition: BFOptimization.cc:363
Reversible::runPreChild
bool runPreChild(Reversible *preChild)
Definition: Reversible.cc:127
TCEString
Definition: TCEString.hh:53
BFPushDepsUp.hh
MoveNode::isScheduled
bool isScheduled() const
Definition: MoveNode.cc:409
BF2Scheduler::guardWriteNode
MoveNode * guardWriteNode()
Definition: BF2Scheduler.hh:191
Move.hh
ProgramOperation::inputMove
MoveNode & inputMove(int index) const
Definition: ProgramOperation.cc:621
DataDependenceGraph::latestCycle
int latestCycle(const MoveNode &moveNode, unsigned int ii=UINT_MAX, bool ignoreRegAntideps=false, bool ignoreUnscheduledSuccessors=true, bool ignoreGuards=false, bool ignoreFUDeps=false, bool ignoreSameOperationEdges=false) const
Definition: DataDependenceGraph.cc:543