OpenASIP 2.2
Loading...
Searching...
No Matches
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"
39#include "BFPushDepsUp.hh"
40#include "Move.hh"
41#include "BF2Scheduler.hh"
42#include "Terminal.hh"
43
44//#define DEBUG_BUBBLEFISH_SCHEDULER
45
46bool
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
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;
156#ifdef DEBUG_BUBBLEFISH_SCHEDULER
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
180#ifdef DEBUG_BUBBLEFISH_SCHEDULER
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;
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;
274#endif
275 return true;
276}
#define assert(condition)
MoveNode * guardWriteNode()
unsigned int ii() const
BF2Scheduler & sched_
DataDependenceGraph & ddg()
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 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)
bool operator()()
std::stack< Reversible * > midChildren_
static int recurseCounter_
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
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
virtual void writeToDotFile(const TCEString &fileName) const
int nodeID() const
int cycle() const
Definition MoveNode.cc:421
bool isDestinationOperation() const
std::string toString() const
Definition MoveNode.cc:576
TTAProgram::Move & move()
bool isScheduled() const
Definition MoveNode.cc:409
ProgramOperation & destinationOperation(unsigned int index=0) const
int inputMoveCount() const
MoveNode & inputMove(int index) const
std::stack< Reversible * > preChildren_
Definition Reversible.hh:57
void undoAndRemoveChildren(std::stack< Reversible * > &children)
Definition Reversible.cc:55
bool runPreChild(Reversible *preChild)
bool isControlFlowMove() const
Definition Move.cc:233
Terminal & destination() const
Definition Move.cc:323
virtual bool isTriggering() const
Definition Terminal.cc:298