OpenASIP  2.0
BFMergeAndKeepUser.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2020 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  * @file BFMergeAndKeepUser.cc
26  *
27  * Definition of scheduler operation which performs a bypass, including the
28  * ddg updates.
29  *
30  * @author Heikki Kultala 2020 (hkultala-no.spam-tuni.fi)
31  * @note rating: red
32  */
33 
34 #include "BFMergeAndKeepUser.hh"
35 #include "BFConnectNodes.hh"
36 #include "BFRemoveEdge.hh"
37 #include "ProgramOperation.hh"
38 #include "DataDependenceEdge.hh"
39 #include "DataDependenceGraph.hh"
40 #include "Move.hh"
41 #include "Terminal.hh"
42 #include "MoveNodeDuplicator.hh"
43 
44 #include "BFUpdateMoveOnBypass.hh"
45 
46 bool
48  MoveNode* src, MoveNode* dst, bool loopBypass, bool pre) {
49 
50  bool sourceIsRegToItselfCopy = false;
51 
52  if (src != nullptr && dst != nullptr &&
53  ddg().rootGraph()->hasNode(*dst) &
54  ddg().rootGraph()->hasNode(*src)) {
55  bool removedRawEdge = false;
56  auto edges = ddg().rootGraph()->connectingEdges(*src, *dst);
57  for (auto e: edges) {
58  if (e->isRAW()) {
59  removedRawEdge = true;
60  runChild(new BFRemoveEdge(sched_, *src, *dst, *e), pre);
61  reg_ = e->data();
62  }
63  }
64  if (!removedRawEdge) {
65  undo();
66  return false;
67  }
68 
69  TTAProgram::Move& sm = src->move();
70  sourceIsRegToItselfCopy = sm.source().equals(sm.destination());
71 
72  // if we are bypassing from a register-to-register copy, we'll have to
73  // copy incoming raw edges also in rootgraph level to preserve inter-bb
74  // -dependencies.
75  for (int i = 0; i < ddg().rootGraphInDegree(*src); i++) {
76  DataDependenceEdge& edge = ddg().rootGraphInEdge(*src,i);
77 
78  // skip antidependencies due bypassed register.. these are no more
80  edge.data() == reg_) {
83  continue;
84  }
85  }
86 
87  // do not copy guard use edges - the user already ahs them.
88  // copying them leads to exponential increase in guard ege counts.
89  if (edge.guardUse()) {
90  continue;
91  }
92 
93  // copy other edges.
94  MoveNode& source = ddg().rootGraph()->tailNode(edge);
95  DataDependenceEdge* newEdge =
96  new DataDependenceEdge(edge, loopBypass);
97  runChild(new BFConnectNodes(sched_, source, *dst, newEdge), pre);
98  }
99 
100  if (src->isSourceVariable() || src->isSourceRA()) {
101  // if bypassing reg-to-reg this copy anti edges resulting from the
102  // read of the other register.
103  for (int i = 0; i < ddg().rootGraphOutDegree(*src); i++) {
104  DataDependenceEdge& edge = ddg().rootGraphOutEdge(*src,i);
108  !edge.tailPseudo()) {
109 
110  MoveNode& target = ddg().rootGraph()->headNode(edge);
111 
112  if (!(static_cast<DataDependenceGraph*>(ddg().rootGraph()))
113  ->exclusingGuards(*dst, target) &&
114  dst != &target) {
115 
116  DataDependenceEdge* newEdge =
117  new DataDependenceEdge(edge, loopBypass);
118  // TODO: loop here!
120  sched_, *dst, target, newEdge), pre);
121  }
122  }
123  }
124  }
125  }
126 
127 
128  if (dst != nullptr && ddg().rootGraph()->hasNode(*dst)) {
129  // fix WAR antidependencies to WaW
130  for (int i = 0; i < ddg().rootGraphOutDegree(*dst); i++) {
131  DataDependenceEdge& edge = ddg().rootGraphOutEdge(*dst,i);
134  edge.data() == reg_) {
135  // if stupid reg to itself copy, keep to in edges..
136  if (!sourceIsRegToItselfCopy) {
137  runChild(
138  new BFRemoveEdge(
139  sched_, *dst,
140  ddg().rootGraph()->headNode(edge), edge), pre);
141  i--; // don't skip one edge here!
142  }
143  }
144  }
145  }
146  return true;
147 }
148 
149 bool
151 
152 
153  if (!ddg().mergeAndKeepAllowed(src_, dst_)) {
154  if (!force_) {
155  return false;
156  }
157  }
158 
159  bool loopBypass = ddg().isLoopBypass(src_, dst_);
160 
161  // Cannot bypass over multiple loop iterations. even with force flag.
162  if (loopBypass) {
163  for (int i = 0; i < ddg().inDegree(src_); i++) {
164  DataDependenceEdge& edge = ddg().inEdge(src_,i);
165  if (!edge.isFalseDep() && edge.isBackEdge()) {
166  return false;
167  }
168  }
169  }
171 
172  if (!updateEdges(&src_, &dst_, loopBypass, true)) {
173  return false;
174  }
175 
176 
177  if (ii() && updatePrologMove_) {
178  MoveNode* prologMove = duplicator().getMoveNode(dst_);
179  if (prologMove != nullptr) {
180  auto prologSrcMove =
181  duplicator().duplicateMoveNode(src_,true, false);
182  duplicatedSrc_ = prologSrcMove.second;
183 
184  runPostChild(
186  sched_, *prologSrcMove.first, *prologMove));
187 
188  updateEdges(
189  prologSrcMove.first, prologMove, loopBypass, false);
190 
191  }
192  }
193  return true;
194 
195 }
196 
198  if (duplicatedSrc_) {
199  duplicator().disposeMoveNode(duplicator().getMoveNode(src_));
200  }
201 }
BFMergeAndKeepUser.hh
BFUpdateMoveOnBypass.hh
DataDependenceGraph::isLoopBypass
bool isLoopBypass(MoveNode &sourceNode, MoveNode &userNode)
Definition: DataDependenceGraph.cc:1916
BoostGraph::tailNode
virtual Node & tailNode(const Edge &edge) const
BFOptimization::duplicator
MoveNodeDuplicator & duplicator() const
Definition: BFOptimization.cc:87
BoostGraph::headNode
virtual Node & headNode(const Edge &edge) const
DataDependenceEdge::isBackEdge
bool isBackEdge() const
Definition: DataDependenceEdge.hh:118
BoostGraph::rootGraphInDegree
virtual int rootGraphInDegree(const Node &node) const
BFOptimization::ii
unsigned int ii() const
Definition: BFOptimization.cc:85
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
DataDependenceEdge::isFalseDep
bool isFalseDep() const
Definition: DataDependenceEdge.hh:95
DataDependenceGraph.hh
MoveNode
Definition: MoveNode.hh:65
BoostGraph::rootGraphOutEdge
virtual Edge & rootGraphOutEdge(const Node &node, const int index) const
BoostGraph::rootGraphOutDegree
virtual int rootGraphOutDegree(const Node &node) const
Terminal.hh
DataDependenceEdge::EDGE_REGISTER
@ EDGE_REGISTER
Definition: DataDependenceEdge.hh:53
DataDependenceEdge::dependenceType
DependenceType dependenceType() const
Definition: DataDependenceEdge.hh:88
DataDependenceEdge::tailPseudo
bool tailPseudo() const
Definition: DataDependenceEdge.hh:109
DataDependenceEdge.hh
MoveNode::isSourceRA
bool isSourceRA() const
Definition: MoveNode.cc:210
BFOptimization::sched_
BF2Scheduler & sched_
Definition: BFOptimization.hh:103
BFConnectNodes
Definition: BFConnectNodes.hh:38
BFMergeAndKeepUser::reg_
TCEString reg_
Definition: BFMergeAndKeepUser.hh:63
MoveNodeDuplicator::duplicateMoveNode
std::pair< MoveNode *, bool > duplicateMoveNode(MoveNode &mn, bool addToDDG, bool ignoreSameBBBackEdges)
Definition: MoveNodeDuplicator.cc:106
BoostGraph::rootGraphInEdge
virtual Edge & rootGraphInEdge(const Node &node, const int index) const
BFRemoveEdge.hh
BFMergeAndKeepUser::force_
bool force_
Definition: BFMergeAndKeepUser.hh:62
BFRemoveEdge
Definition: BFRemoveEdge.hh:40
BoostGraph::rootGraph
BoostGraph * rootGraph()
BoostGraph::inEdge
virtual Edge & inEdge(const Node &node, const int index) const
MoveNodeDuplicator::disposeMoveNode
void disposeMoveNode(MoveNode *newMN)
Definition: MoveNodeDuplicator.cc:53
Reversible::undo
virtual void undo()
Definition: Reversible.cc:69
BFOptimization::ddg
DataDependenceGraph & ddg()
Definition: BFOptimization.cc:70
TTAProgram::Move
Definition: Move.hh:55
BFMergeAndKeepUser::updateEdges
bool updateEdges(MoveNode *src, MoveNode *dst, bool loopBypass, bool pre)
Definition: BFMergeAndKeepUser.cc:47
BoostGraph::inDegree
virtual int inDegree(const Node &node) const
DataDependenceEdge::data
const TCEString data() const
Definition: DataDependenceEdge.hh:142
DataDependenceEdge::DEP_WAW
@ DEP_WAW
Definition: DataDependenceEdge.hh:49
BFMergeAndKeepUser::undoOnlyMe
void undoOnlyMe() override
Definition: BFMergeAndKeepUser.cc:197
MoveNodeDuplicator.hh
BoostGraph::connectingEdges
EdgeSet connectingEdges(const Node &nTail, const Node &nHead) const
ProgramOperation.hh
MoveNodeDuplicator::getMoveNode
MoveNode * getMoveNode(MoveNode &mn)
Definition: MoveNodeDuplicator.cc:85
MoveNode::isSourceVariable
bool isSourceVariable() const
Definition: MoveNode.cc:196
DataDependenceEdge::guardUse
bool guardUse() const
Definition: DataDependenceEdge.hh:100
MoveNode::move
TTAProgram::Move & move()
Reversible::runChild
bool runChild(std::stack< Reversible * > &children, Reversible *child)
Definition: Reversible.cc:109
Reversible::runPreChild
bool runPreChild(Reversible *preChild)
Definition: Reversible.cc:127
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
TTAProgram::Terminal::equals
virtual bool equals(const Terminal &other) const =0
DataDependenceEdge
Definition: DataDependenceEdge.hh:43
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
BFMergeAndKeepUser::dst_
MoveNode & dst_
Definition: BFMergeAndKeepUser.hh:61
BFConnectNodes.hh
Move.hh
DataDependenceEdge::DEP_WAR
@ DEP_WAR
Definition: DataDependenceEdge.hh:48
Reversible::runPostChild
bool runPostChild(Reversible *preChild)
Definition: Reversible.cc:139
DataDependenceEdge::EDGE_RA
@ EDGE_RA
Definition: DataDependenceEdge.hh:57
BFUpdateMoveOnBypass
Definition: BFUpdateMoveOnBypass.hh:41
BFMergeAndKeepUser::updatePrologMove_
bool updatePrologMove_
Definition: BFMergeAndKeepUser.hh:64
BFMergeAndKeepUser::duplicatedSrc_
bool duplicatedSrc_
Definition: BFMergeAndKeepUser.hh:65
BFMergeAndKeepUser::src_
MoveNode & src_
Definition: BFMergeAndKeepUser.hh:60
DataDependenceEdge::edgeReason
EdgeReason edgeReason() const
Definition: DataDependenceEdge.hh:91
BFMergeAndKeepUser::operator()
bool operator()() override
Definition: BFMergeAndKeepUser.cc:150