OpenASIP 2.2
Loading...
Searching...
No Matches
BFRenameLiveRange.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 BFRenameLiveRange.cc
27 *
28 * Definition of BFRenameLiveRange class
29 *
30 * Renames a liverange, consisting of one or more writes,
31 * and one or more either register reads or guadrd uses of the register.
32 *
33 * @author Heikki Kultala 2014-2020(heikki.kultala-no.spam-tuni.fi)
34 * @note rating: red
35 */
36
37#include "BFRenameLiveRange.hh"
38
39#include "BF2Scheduler.hh"
40#include "RegisterRenamer.hh"
41#include "RegisterFile.hh"
42#include "LiveRange.hh"
43#include "BasicBlock.hh"
44#include "TerminalRegister.hh"
45#include "Machine.hh"
46#include "BUMoveNodeSelector.hh"
47#include "BF2ScheduleFront.hh"
48#include "MoveGuard.hh"
49#include "Guard.hh"
50
51
53 BF2Scheduler& sched,
54 std::shared_ptr<LiveRange> liveRange,
55 int targetCycle) :
56 BFOptimization(sched), oldReg_(nullptr), liveRange_(liveRange),
57 targetCycle_(targetCycle) {}
58
59
61
62 bb_ = &sched_.renamer()->bb();
63
64 assert(!liveRange_->reads.empty());
65
66 auto rfs = sched_.renamer()->findConnectedRFs(*liveRange_, false);
67
68 bool usedAfter = true;
69 std::set<TCEString> regs;
70
71 if (!ii()) {
72
74 rfs, targetCycle_);
75 }
76
77 if (regs.empty()) {
78 usedAfter = false;
80 }
81
82 if (regs.empty()) {
83 return false;
84 }
85
86 return renameLiveRange(*liveRange_, *regs.begin(), usedAfter);
87}
88
90
91 TCEString rfName = newReg_.substr(0, newReg_.find('.'));
94 int newRegIndex = atoi(newReg_.substr(newReg_.find('.')+1).c_str());
95
96 // for writes.
97 for (auto i: liveRange_->writes) {
98 TTAProgram::Move& move = i->move();
100 *rf->firstWritePort(), newRegIndex));
101 }
102
103 // for reads.
104 for (auto i: liveRange_->reads) {
105 TTAProgram::Move& move = i->move();
107 *rf->firstReadPort(), newRegIndex));
108 }
109
110 // for guards.
111 for (auto i: liveRange_->guards) {
112 TTAProgram::Move& move = i->move();
113 setGuard(move, *rf, newRegIndex);
114 }
115}
116
118 TTAProgram::Move& move, const TTAMachine::RegisterFile& rf, int regIndex){
119
120 const TTAMachine::Guard& guard = move.guard().guard();
121 TTAMachine::Bus* guardBus = guard.parentBus();
122 for (int j = 0 ; j < guardBus->guardCount(); j++) {
123 TTAMachine::Guard *g = guardBus->guard(j);
125 dynamic_cast<TTAMachine::RegisterGuard*>(g);
126 if (rg) {
127 if (rg->registerFile() == &rf &&
128 rg->registerIndex() == regIndex &&
129 rg->isInverted() == guard.isInverted()) {
130 move.setGuard(new TTAProgram::MoveGuard(*g));
131 }
132 }
133 }
134}
135
137
138 // for writes.
139 for (auto i: liveRange_->writes) {
140 TTAProgram::Move& move = i->move();
141 move.setDestination(oldReg_->copy());
142 }
143
144 // for reads.
145 for (auto i: liveRange_->reads) {
146 TTAProgram::Move& move = i->move();
147 move.setSource(oldReg_->copy());
148 }
149
150 // for guards
151 for (auto i: liveRange_->guards) {
152 TTAProgram::Move& move = i->move();
154 }
155
156}
157
159 // restore the DDG stage before the rename
160 for (auto i: undoReadUpdateData_) {
161 ddg().undo(i.second);
162 }
164
166
169
172
174
176
177}
178
180 for (auto e: createdAntidepEdges_) {
181 ddg().removeEdge(*e);
182 }
183 createdAntidepEdges_.clear();
184}
185
187 if (liveRange_->writes.size() != 1 ||
188 !(*liveRange_->writes.begin())->move().isUnconditional()) {
189 return;
190 }
191
195}
201
206
208 if (liveRange_->writes.size() != 1 ||
209 !(*liveRange_->writes.begin())->move().isUnconditional()) {
210 return;
211 }
212
215
217 MoveNodeUse(**liveRange_->writes.begin());
219}
220
221
223 // for writing.
224 for (auto i: liveRange_->writes) {
225 MoveNodeUse mnd(*i);
226 bb_->liveRangeData_->regDefines_[newReg_].insert(mnd);
227 }
228
229 // for reading.
230 for (auto i: liveRange_->reads) {
231 MoveNodeUse mnd(*i);
232 bb_->liveRangeData_->regLastUses_[newReg_].insert(mnd);
233 }
234
235 // for reading.
236 for (auto i: liveRange_->guards) {
237 MoveNodeUse mnd(*i, true);
238 bb_->liveRangeData_->regLastUses_[newReg_].insert(mnd);
239 }
240
241}
242
244 // for writing.
245 for (auto i: liveRange_->writes) {
246 MoveNodeUse mnd(*i);
248 }
249
250 // for reading.
251 for (auto i: liveRange_->reads) {
252 MoveNodeUse mnd(*i);
254 }
255
256 // for reading.
257 for (auto i: liveRange_->guards) {
258 MoveNodeUse mnd(*i, true);
260 }
261}
262
264
265 // for writing.
266 for (auto i: liveRange_->writes) {
267 MoveNodeUse mnd(*i);
269 // TODO: only if intra-bb-antideps enabled?
270// static_cast<DataDependenceGraph*>(ddg().rootGraph())->
271// updateRegWrite(mnd, newReg, *bb_);
272 }
273
274 // for reading.
275 for (auto i: liveRange_->reads) {
276 MoveNodeUse mnd(*i);
278 // no need to create raw deps here
279 }
280
281 // for guards.
282 for (auto i: liveRange_->guards) {
283 MoveNodeUse mnd(*i, true);
285 // no need to create raw deps here
286 }
287}
288
290
291 // for writing.
292 for (auto i: liveRange_->writes) {
293 MoveNodeUse mnd(*i);
295
296
297 // TODO: only if intra-bb-antideps enabled?
298// static_cast<DataDependenceGraph*>(ddg().rootGraph())->
299// updateRegWrite(mnd, newReg, *bb_);
300 }
301
302 // for reading.
303 for (auto i: liveRange_->reads) {
304 MoveNodeUse mnd(*i);
306 }
307
308 // for guards.
309 for (auto i: liveRange_->guards) {
310 MoveNodeUse mnd(*i, true);
312 }
313}
314
315
316
317
318
320 LiveRange& liveRange, const TCEString& newReg, bool usedAfter) {
321
322 bool usedBefore = false;
323
324 newReg_ = newReg;
325 oldReg_ = (*liveRange.writes.begin())->move().destination().copy();
326
327 assert(newReg.length() > 2);
328
329 if (usedAfter) {
330 TCEString rfName = newReg_.substr(0, newReg_.find('.'));
333 int newRegIndex = atoi(newReg_.substr(newReg_.find('.')+1).c_str());
334 DataDependenceGraph::NodeSet firstWrites =
335 ddg().firstScheduledRegisterWrites(*rf, newRegIndex);
336
337 // make sure no circular antidep path
338 for (auto j: firstWrites) {
339 for (auto i: liveRange.reads) {
340 if (ddg().hasPath(*j, *i)) {
341 return false;
342 }
343 }
344
345 for (auto i: liveRange.writes) {
346 if (ddg().hasPath(*j, *i)) {
347 return false;
348 }
349 }
350 }
351
352 // antideps
353 for (auto j: firstWrites) {
354 for (auto i: liveRange.writes) {
355 DataDependenceEdge* newWAW =
359 ddg().connectNodes(*i,*j, *newWAW);
360 createdAntidepEdges_.insert(newWAW);
361 }
362
363 for (auto i: liveRange.reads) {
364 DataDependenceEdge* newWAR =
368 ddg().connectNodes(*i,*j, *newWAR);
369 createdAntidepEdges_.insert(newWAR);
370 }
371 }
372 } else {
375
376
377// TODO
378#if 0
379 // need to create backedges to first if we are loop scheduling.
380 if (loopScheduling) {
381 updateAntiEdgesFromLRTo(liveRange, newReg, bb_, 1);
382 }
383#endif
384 }
385
386 if (usedBefore) {
387 return false;
388 } else {
391 }
392
393 setTerminals();
395
396 // for writes.
397 assert (liveRange_->writes.size() == 1);
398 for (auto i: liveRange_->writes) {
400 }
401
402 // for reads
403 for (auto i: liveRange_->reads) {
405 }
406
407 assert(liveRange_->guards.size() == 0);
408 // for guards
409 for (auto i: liveRange_->guards) {
411 }
412
415 return true;
416}
417
418
420 // then update ddg and notify selector.
421
422 // for writes.
423 for (auto i: liveRange_->writes) {
424 DataDependenceGraph::NodeSet writeSuccessors =
425 ddg().successors(*i);
426 DataDependenceGraph::NodeSet writePredecessors =
427 ddg().predecessors(*i);
428
429 // notify successors of write to prevent orphan nodes.
430 for (auto j: writeSuccessors) {
432 }
433
434 // notify successors of write to prevent orphan nodes.
435 for (auto j: writePredecessors) {
437 }
438
439 }
440
441 // for reads
442 for (auto i: liveRange_->reads) {
444 ddg().successors(*i);
445 DataDependenceGraph::NodeSet predecessors =
446 ddg().predecessors(*i);
447
448 // notify successors to prevent orphan nodes.
449 for (auto j: successors) {
451 }
452
453 // notify successors to prevent orphan nodes.
454 for (auto j: predecessors) {
456 }
457 }
458
459 // for guards
460 for (auto i: liveRange_->guards) {
462 ddg().successors(*i);
463 DataDependenceGraph::NodeSet predecessors =
464 ddg().predecessors(*i);
465
466 // notify successors to prevent orphan nodes.
467 for (auto j: successors) {
469 }
470
471 // notify successors to prevent orphan nodes.
472 for (auto j: predecessors) {
474 }
475 }
476}
477
#define assert(condition)
void mightBeReady(MoveNode &n) override
RegisterRenamer * renamer()
BF2ScheduleFront * currentFront()
unsigned int ii() const
BF2Scheduler & sched_
DataDependenceGraph & ddg()
const TTAMachine::Machine & targetMachine() const
virtual void undoOnlyMe() override
DataDependenceGraph::EdgeSet createdAntidepEdges_
virtual bool operator()()
BFRenameLiveRange(BF2Scheduler &sched, std::shared_ptr< LiveRange > liveRange, int targetCycle)
TTAProgram::BasicBlock * bb_
LiveRangeData::MoveNodeUseSet oldRegFirstUses_
LiveRangeData::MoveNodeUseSet oldRegDefines_
void setGuard(TTAProgram::Move &move, const TTAMachine::RegisterFile &rf, int regIndex)
LiveRangeData::MoveNodeUseSet oldRegFirstDefines_
class TTAProgram::Terminal * oldReg_
std::map< const MoveNode *, DataDependenceGraph::UndoData, MoveNode::Comparator > undoReadUpdateData_
DataDependenceGraph::UndoData undoWriteUpdateData_
std::shared_ptr< LiveRange > liveRange_
bool renameLiveRange(class LiveRange &liveRange, const class TCEString &reg, bool usedAfter)
virtual void removeEdge(Edge &e)
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
bool hasPath(GraphNode &src, const GraphNode &dest) const
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
DataDependenceGraph::UndoData sourceRenamed(MoveNode &mn)
NodeSet firstScheduledRegisterWrites(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
DataDependenceGraph::UndoData guardRenamed(MoveNode &mn)
DataDependenceGraph::UndoData destRenamed(MoveNode &mn)
void undo(UndoData &undoData)
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
Definition Graph.hh:53
void revertedRenameToRegister(const TCEString &reg)
TTAProgram::BasicBlock & bb()
std::set< TCEString > findFreeRegistersInRF(const RegisterFileSet &rfs) const
std::set< TCEString > findPartiallyUsedRegistersInRFAfterCycle(const RegisterFileSet &rfs, int latestCycle) const
void renamedToRegister(const TCEString &newReg)
RegisterFileSet findConnectedRFs(LiveRange &lr, bool allowLimm)
Guard * guard(int index) const
Definition Bus.cc:456
int guardCount() const
Definition Bus.cc:441
virtual bool isInverted() const
virtual Bus * parentBus() const
ComponentType * item(int index) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
Port * firstReadPort() const
Port * firstWritePort() const
const RegisterFile * registerFile() const
LiveRangeData * liveRangeData_
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
void setSource(Terminal *src)
Definition Move.cc:312
MoveGuard & guard() const
Definition Move.cc:345
void setGuard(MoveGuard *guard)
Definition Move.cc:360
void setDestination(Terminal *dst)
Definition Move.cc:333
virtual int index() const
Definition Terminal.cc:274
virtual Terminal * copy() const =0
virtual const TTAMachine::RegisterFile & registerFile() const
Definition Terminal.cc:225
MoveNodeUseMapSet regFirstUses_
MoveNodeUseMapSet regLastUses_
MoveNodeUseMapSet regFirstDefines_
MoveNodeUseMapPair regKills_
MoveNodeUseMapPair regLastKills_
MoveNodeUseMapSet regDefines_
DataDependenceGraph::NodeSet reads
Definition LiveRange.hh:40
DataDependenceGraph::NodeSet writes
Definition LiveRange.hh:39