OpenASIP  2.0
OutputPSocketResource.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2011 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 OutputPSocketResource.cc
26  *
27  * Implementation of OutputPSocketResource class.
28  *
29  * @author Vladimir Guzma 2006 (vladimir.guzma-no.spam-tut.fi)
30  * @author Pekka Jääskeläinen 2011
31  * @note rating: red
32  */
33 #include <iostream>
34 #include "OutputPSocketResource.hh"
35 #include "MapTools.hh"
36 #include "Move.hh"
37 #include "MoveNode.hh"
38 #include "MoveGuard.hh"
39 #include "Guard.hh"
40 #include "Terminal.hh"
41 #include "Port.hh"
42 
43 /**
44  * Constructor.
45  *
46  * @param name Name of resource.
47  */
48 OutputPSocketResource::OutputPSocketResource(const std::string& name, unsigned int initiationInterval) :
49  PSocketResource(name, initiationInterval), activeCycle_(-1) {}
50 
51 /**
52  * Destructor.
53  */
55 
56 /**
57  * Test if resource OutputPSocketResource is available.
58  *
59  * @param cycle Cycle which to test.
60  * @return Always true, multiple reads are possible.
61  */
62 bool
64  return true;
65 }
66 
67 /**
68  * Return true always.
69  *
70  * @return True always.
71  */
72 bool
74  return true;
75 }
76 /**
77  * Assign resource to given node for given cycle.
78  *
79  * @param cycle Cycle to assign
80  * @param node MoveNode to assign
81  */
82 void
83 OutputPSocketResource::assign(const int cycle, MoveNode& node)
84 {
85  PSocketResource::assign(cycle, node);
86  auto i = storedPorts_.find(instructionIndex(cycle));
87  if (i == storedPorts_.end()) {
88  const TTAMachine::Port* newPort = &node.move().source().port();
90  std::make_pair(newPort,1);
91  } else {
92  i->second.second++;
93  }
94 }
95 
96 /**
97  * Unassign resource from given node for given cycle.
98  *
99  * @param cycle Cycle to remove assignment from
100  * @param node MoveNode to remove assignment from
101  */
102 void
104 {
105  PSocketResource::unassign(cycle, node);
106  auto i = storedPorts_.find(instructionIndex(cycle));
107  if (i != storedPorts_.end()) {
108  if (i->second.second == 1) {
109  storedPorts_.erase(i);
110  } else {
111  i->second.second--;
112  }
113  }
114 }
115 
116 /**
117  * Return true if resource can be assigned for given resource in given cycle.
118  *
119  * @param cycle Cycle to test
120  * @param node MoveNode to test
121  * @return true if node can be assigned to cycle
122  */
123 bool
124 OutputPSocketResource::canAssign(const int cycle, const MoveNode& node)
125  const {
126  MoveNode& mNode = const_cast<MoveNode&>(node);
127  auto i = storedPorts_.find(instructionIndex(cycle));
128  if (mNode.move().source().isFUPort()) {
129  if (i != storedPorts_.end()) {
130  const TTAMachine::Port* storedP = i->second.first;
131  if (&mNode.move().source().port() != storedP) {
132  return false;
133  }
134  }
135  }
136  if (mNode.move().source().isImmediateRegister()) {
137  if (i != storedPorts_.end()) {
138  return false;
139  }
140  }
141  if (node.move().source().isGPR()) {
142  if (i != storedPorts_.end()) {
143  const TTAMachine::Port* storedP =
144  i->second.first;
145  if (mNode.move().source().port().parentUnit() !=
146  storedP->parentUnit()) {
147  return false;
148  }
149  }
150 
151  ResourceRecordType::const_iterator iter = resourceRecord_.find(cycle);
152  if (iter != resourceRecord_.end()) {
153  std::set<MoveNode*> movesInCycle = iter->second;
154  for (std::set<MoveNode*>::iterator it = movesInCycle.begin();
155  it != movesInCycle.end(); it++) {
156 #ifdef NO_OVERCOMMIT
157  return false;
158 #else
159  MoveNode* mn = *it;
160  if (node.move().isUnconditional() ||
161  mn->move().isUnconditional()) {
162  if (node.move().source().port().parentUnit() !=
163  mn->move().source().port().parentUnit() ||
164  node.move().source().index() !=
165  mn->move().source().index()) {
166  return false;
167  } else {
168  continue;
169  }
170 
171  }
172  if (!node.move().guard().guard().isOpposite(
173  mn->move().guard().guard())) {
174  if (!node.move().source().equals(
175  mn->move().source())) {
176  return false;
177  }
178  }
179 #endif
180  }
181  }
182  }
183  activeCycle_ = cycle;
184  return true;
185 }
186 
187 /**
188  * Tests if all referred resources in dependent groups are of
189  * proper types.
190  *
191  * @return True if all dependent groups are empty.
192  */
193 bool
195  for (int i = 0; i < dependentResourceGroupCount(); i++) {
196  if (dependentResourceCount(i) > 0) {
197  return false;
198  }
199  }
200  return true;
201 }
202 
203 /**
204  * Tests if all referred resources in related groups are of
205  * proper types.
206  *
207  * @return True if all resources in related groups are Segment or OutputFU
208  * or IU resources.
209  */
210 bool
212  for (int i = 0; i < relatedResourceGroupCount(); i++) {
213  for (int j = 0, count = relatedResourceCount(i); j < count; j++) {
214  if (!(relatedResource(i, j).isOutputFUResource() ||
215  relatedResource(i, j).isBusResource() ||
216  relatedResource(i, j).isIUResource())) {
217  return false;
218  }
219  }
220  }
221  return true;
222 }
223 
224 /**
225  * Comparison operator.
226  *
227  * Favours sockets which have less connections.
228  *
229  * TODO: precalc/cache these to optimize scheduling time?
230  */
231 bool
233  const OutputPSocketResource *opsr =
234  dynamic_cast<const OutputPSocketResource*>(&other);
235  if (opsr == NULL) {
236  return false;
237  }
238 
239  // first priority is to put reads from same source to same psocket.
240  // so favour the one with most moves in current cycle.
241  int myCount = 0;
242  int otherCount = 0;
243  ResourceRecordType::const_iterator myIter = resourceRecord_.find(activeCycle_);
244  if (myIter != resourceRecord_.end()) {
245  myCount = myIter->second.size();
246  }
247 
248  ResourceRecordType::const_iterator otherIter = opsr->resourceRecord_.find(opsr->activeCycle_);
249  if (otherIter != opsr->resourceRecord_.end()) {
250  otherCount = otherIter->second.size();
251  }
252  if (myCount < otherCount) {
253  return false;
254  } else if (myCount > otherCount) {
255  return true;
256  }
257 
258  // favour sockets which have connections to busses with fewest connections
259  // calculate the connections..
260  int connCount = 0;
261  int connCount2 = 0;
262 
263  int rrCount2 = relatedResourceCount(2);
264  for (int i = 0; i < rrCount2; i++) {
266  connCount += r.relatedResourceCount(0);
267  }
268 
269  int oRRCount2 = other.relatedResourceCount(2);
270 
271  for (int i = 0; i < oRRCount2; i++) {
272  SchedulingResource& r = other.relatedResource(2,i);
273  connCount2 += r.relatedResourceCount(0);
274  }
275 
276  // then the comparison.
277  if (connCount < connCount2) {
278  return true;
279  }
280 
281  if (connCount > connCount2) {
282  return false;
283  }
284 
285  // favour sockets with less buses.
286  if (rrCount2 < oRRCount2) {
287  return true;
288  }
289  if (rrCount2 > oRRCount2) {
290  return false;
291  }
292 
293  // then use the default use count, name comparison,
294  // but in opposite direction, facouring already used
295  return other.SchedulingResource::operator<(*this);
296 }
297 
298 /**
299  * Clears bookkeeping of the scheduling resource.
300  *
301  * After this call the state of the resource should be identical to a
302  * newly-created and initialized resource.
303  */
304 void
307  storedPorts_.clear();
308 }
TTAProgram::Terminal::isFUPort
virtual bool isFUPort() const
Definition: Terminal.cc:118
SchedulingResource::dependentResourceGroupCount
virtual int dependentResourceGroupCount() const
Definition: SchedulingResource.cc:71
OutputPSocketResource::clear
void clear() override
Definition: OutputPSocketResource.cc:305
OutputPSocketResource::activeCycle_
int activeCycle_
Definition: OutputPSocketResource.hh:69
OutputPSocketResource.hh
TTAProgram::Terminal::index
virtual int index() const
Definition: Terminal.cc:274
PSocketResource::assign
virtual void assign(const int cycle, MoveNode &node) override
Definition: PSocketResource.cc:105
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
MapTools.hh
PSocketResource
Definition: PSocketResource.hh:48
OutputPSocketResource::OutputPSocketResource
OutputPSocketResource(const std::string &name, unsigned int initiationInterval=0)
Definition: OutputPSocketResource.cc:48
MoveNode
Definition: MoveNode.hh:65
Terminal.hh
OutputPSocketResource::operator<
virtual bool operator<(const SchedulingResource &other) const override
Definition: OutputPSocketResource.cc:232
SchedulingResource::isOutputFUResource
virtual bool isOutputFUResource() const
PSocketResource::unassign
virtual void unassign(const int cycle, MoveNode &node) override
Definition: PSocketResource.cc:120
OutputPSocketResource::validateRelatedGroups
virtual bool validateRelatedGroups() override
Definition: OutputPSocketResource.cc:211
SchedulingResource::dependentResourceCount
int dependentResourceCount(const int group) const
OutputPSocketResource::canAssign
virtual bool canAssign(const int cycle, const MoveNode &node) const override
Definition: OutputPSocketResource.cc:124
Port.hh
TTAProgram::Terminal::isImmediateRegister
virtual bool isImmediateRegister() const
Definition: Terminal.cc:97
OutputPSocketResource::~OutputPSocketResource
virtual ~OutputPSocketResource()
Definition: OutputPSocketResource.cc:54
SchedulingResource::relatedResource
virtual SchedulingResource & relatedResource(const int group, const int index) const
Definition: SchedulingResource.cc:120
SchedulingResource::isBusResource
virtual bool isBusResource() const
OutputPSocketResource::unassign
virtual void unassign(const int cycle, MoveNode &node) override
Definition: OutputPSocketResource.cc:103
OutputPSocketResource
Definition: OutputPSocketResource.hh:52
SchedulingResource
Definition: SchedulingResource.hh:52
TTAMachine::Port
Definition: Port.hh:54
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
OutputPSocketResource::storedPorts_
std::map< int, std::pair< const TTAMachine::Port *, int > > storedPorts_
Definition: OutputPSocketResource.hh:75
TTAProgram::Terminal::isGPR
virtual bool isGPR() const
Definition: Terminal.cc:107
Guard.hh
OutputPSocketResource::assign
virtual void assign(const int cycle, MoveNode &node) override
Definition: OutputPSocketResource.cc:83
SchedulingResource::instructionIndex
int instructionIndex(int cycle) const
PSocketResource::clear
void clear() override
Definition: PSocketResource.cc:171
SchedulingResource::relatedResourceCount
int relatedResourceCount(const int group) const
TTAMachine::Guard::isOpposite
virtual bool isOpposite(const Guard &guard) const =0
SchedulingResource::isIUResource
virtual bool isIUResource() const
MoveNode::move
TTAProgram::Move & move()
OutputPSocketResource::validateDependentGroups
virtual bool validateDependentGroups() override
Definition: OutputPSocketResource.cc:194
TTAProgram::Terminal::equals
virtual bool equals(const Terminal &other) const =0
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAProgram::Terminal::port
virtual const TTAMachine::Port & port() const
Definition: Terminal.cc:378
TTAProgram::MoveGuard::guard
const TTAMachine::Guard & guard() const
Definition: MoveGuard.cc:86
SchedulingResource::relatedResourceGroupCount
virtual int relatedResourceGroupCount() const
Definition: SchedulingResource.cc:61
Move.hh
MoveNode.hh
PSocketResource::resourceRecord_
ResourceRecordType resourceRecord_
Definition: PSocketResource.hh:63
OutputPSocketResource::isAvailable
virtual bool isAvailable(const int cycle) const override
Definition: OutputPSocketResource.cc:63
OutputPSocketResource::isOutputPSocketResource
virtual bool isOutputPSocketResource() const override
Definition: OutputPSocketResource.cc:73
MoveGuard.hh
TTAMachine::Port::parentUnit
Unit * parentUnit() const