OpenASIP  2.0
MoveNodeGroupBuilder.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 /**
26  * @file MoveNodeGroupBuilder.cc
27  *
28  * @author Pekka Jääskeläinen 2010-2011 (pjaaskel)
29  */
30 #include <map>
31 
32 #include "MoveNodeGroupBuilder.hh"
33 #include "ProgramOperation.hh"
34 #include "MoveNode.hh"
35 #include "BasicBlock.hh"
36 #include "MoveNodeGroup.hh"
37 #include "Machine.hh"
38 #include "FunctionUnit.hh"
39 #include "TCEString.hh"
40 #include "SpecialRegisterPort.hh"
41 #include "Terminal.hh"
42 #include "Instruction.hh"
43 #include "Move.hh"
44 
45 //#define DEBUG_MNGBUILDER
46 
47 /**
48  * Creates movenodes and programoperations from the given BB.
49  *
50  * Also builds MoveNodes and ProgramOperations and ensures the produced
51  * MNG list is in the input sequential order and that each MNG contains
52  * either one MoveNode or a set of MoveNodes consisting a ProgramOperation.
53  * The returned objects become owned by the caller.
54  * This supports also input that is already bypassed.
55  */
58 
59  /*
60  Process each input move from the sequential unscheduled stream.
61  Input moves can be already bypassed and operand shared.
62 
63  In case the move
64  a) is a reg/imm -> FU.in:
65 
66  And if the 'in' is a non-triggering input move,
67  add the move to a PO that has not been triggered yet in the FU.
68 
69  If it's a trigger move, set the PO to "triggered" state. The previous
70  PO in "triggered" state can be set to "finished" state as there cannot
71  be no more bypassed reads from the previous one as the new PO
72  is overwriting its results and the input sequential code is not cycle
73  accurately scheduled.
74  b) is an FU.out -> reg:
75  add it to an PO that has been triggered in the FU.
76  c) is a FUA.out -> FUB.in: find the last PO started in FUA, add it there
77  as an output move. Find the unstarted PO in FUB, add it there as
78  an input move.
79  d) reg/imm -> reg:
80  just create the MNG
81 
82  Thus, there are two types of POs during the algorithm execution:
83  1) untriggered: POs with operand moves still coming in, trigger not
84  encountered.
85  2) triggered: POs which are "on flight", thus the POs of which results
86  can be still read to the upcoming POs.
87  3) finished: these POs are just in the finished PO list
88 
89  There can be only one unstarted and only one started PO per FU in the
90  sequential input, thus the indices are be per FU.
91 
92  The same input move can belong to multiple POs (operand sharing).
93  How to treat those?
94 
95  At the moment an operation is moved to "started", check if all its
96  input operand moves are found. If not, find the PO which had the
97  original OperandMove (TODO: how?) and add them as inputs.
98 
99  */
100 
101  typedef std::map<TCEString, ProgramOperationPtr>
102  FUProgramOperationIndex;
103 
104  FUProgramOperationIndex untriggered, triggered;
105  // programOperations_ is the finished set
106 
107  MoveNodeGroupList* mngs = new MoveNodeGroupList();
108  MoveNodeGroup* mng = NULL;
109  // PO which is being constructed.
111  for (int i = 0; i < bb.instructionCount(); i++) {
113  for (int j = 0; j < ins.moveCount(); j++) {
114  // handle one move
115  auto movePtr = ins.movePtr(j);
116  TTAProgram::Move& move = *movePtr;
117  MoveNode* moveNode = new MoveNode(movePtr);
118  TTAProgram::Terminal& source = move.source();
119  TTAProgram::Terminal& dest = move.destination();
120 
121  if (mng == NULL)
122  mng = new MoveNodeGroup();
123 
124  bool sourceIsFU =
125  (source.isFUPort() &&
126  !(dynamic_cast<const TTAMachine::SpecialRegisterPort*>(
127  &source.port())));
128 
129  bool destIsFU = (dest.isFUPort() &&
130  !(dynamic_cast<const TTAMachine::SpecialRegisterPort*>(
131  &dest.port())));
132 
133 #ifdef DEBUG_MNGBUILDER
135  << "processing move: " << move.toString() << " "
136  << sourceIsFU << " " << destIsFU;
137  Application::logStream() << std::endl;
138 #endif
139  if (!sourceIsFU && destIsFU) {
140  po = untriggered[dest.functionUnit().name()];
141  if (po == NULL) {
142  Operation* op;
143  if (dest.isOpcodeSetting()) {
144  op = &dest.operation();
145  } else {
146  op = &dest.hintOperation();
147  }
148  po = ProgramOperationPtr(new ProgramOperation(*op));
149  untriggered[dest.functionUnit().name()] = po;
150 
151  if (mng->nodeCount() > 0) {
152  // start a new move node group as it has to be
153  // a new operation as no previous untriggered
154  // operation was found for this FU
155  mngs->push_back(mng);
156  mng = new MoveNodeGroup();
157  }
158  mng->setProgramOperationPtr(po);
159  }
160  po->addInputNode(*moveNode);
161  moveNode->addDestinationOperationPtr(po);
162  mng->addNode(*moveNode);
163  if (dest.isTriggering()) {
164  untriggered[dest.functionUnit().name()] = ProgramOperationPtr();
165  triggered[dest.functionUnit().name()] = po;
166  }
167  } else if (sourceIsFU && !destIsFU) {
168  po = triggered[source.functionUnit().name()];
169  assert(
170  po != NULL &&
171  "Encountered an FU read without a triggered operation.");
172 
173  po->addOutputNode(*moveNode);
174  moveNode->setSourceOperationPtr(po);
175  mng->addNode(*moveNode);
176  } else if (sourceIsFU && destIsFU) {
177  po = triggered[source.functionUnit().name()];
178  assert(
179  po != NULL &&
180  "Encountered an FU read without a triggered operation.");
181  po->addOutputNode(*moveNode);
182  moveNode->setSourceOperationPtr(po);
183  po = untriggered[dest.functionUnit().name()];
184  if (po == NULL) { /* The 1st operand move? */
185  Operation* op;
186  if (dest.isOpcodeSetting()) {
187  op = &dest.operation();
188  } else {
189  op = &dest.hintOperation();
190  }
191  po = ProgramOperationPtr(new ProgramOperation(*op));
192  untriggered[dest.functionUnit().name()] = po;
193  // define the first operand move to start an operation
194  // always, thus split MNG at this point
195  mngs->push_back(mng);
196  mng = new MoveNodeGroup();
197  mng->setProgramOperationPtr(po);
198  }
199  mng->addNode(*moveNode);
200  po->addInputNode(*moveNode);
201  moveNode->addDestinationOperationPtr(po);
202  if (dest.isTriggering()) {
203  untriggered[dest.functionUnit().name()] = ProgramOperationPtr();
204  triggered[dest.functionUnit().name()] = po;
205  }
206  } else if (!sourceIsFU && !destIsFU) {
207 
208  if (mng->nodeCount() > 0)
209  mngs->push_back(mng);
210 
211  // reg copies are always scheduled independently
212  mng = new MoveNodeGroup();
213  mng->addNode(*moveNode);
214  mngs->push_back(mng);
215 
216  mng = new MoveNodeGroup();
217  } else {
218  abortWithError(moveNode->toString() + " is not implemented.");
219  }
220  }
221  }
222 
223  if (mng != NULL && mng->nodeCount() > 0) {
224  mngs->push_back(mng);
225  }
226  // untriggered POs are considered errors at this point as no
227  // BB-crossing operations are supported in the sequential code
228  for (FUProgramOperationIndex::const_iterator i = untriggered.begin();
229  i != untriggered.end(); ++i) {
230  ProgramOperationPtr po = (*i).second;
231  if (po != NULL && po->inputMoveCount() > 0) {
233  TCEString(
234  "Encountered an untriggered&unfinished "
235  "ProgramOperation\nat the end of the BB. "
236  "BB-crossing operations are not\nsupported "
237  "at this point." + po->toString()));
238  }
239  }
240 
241 #ifdef DEBUG_MNGBUILDER
242  int count = 0;
243  Application::logStream() << "### ProgramOperations built:" << std::endl;
244  for (ProgramOperationList::const_iterator i = programOperations_.begin();
245  i != programOperations_.end(); ++i, ++count) {
246  ProgramOperation* po = *i;
247  Application::logStream() << count << " " <<po->toString() << std::endl;
248  }
249 
250  Application::logStream() << "### MoveNodeGroups built:" << std::endl;
251  count = 0;
252  for (MoveNodeGroupList::const_iterator i = mngs->begin();
253  i != mngs->end(); ++i, ++count) {
254  MoveNodeGroup* mng = *i;
256  << count << ": " << mng->toString() << std::endl;
257  }
258 
259 #endif
260  return mngs;
261 }
MoveNodeGroupBuilder.hh
TTAProgram::Terminal::isFUPort
virtual bool isFUPort() const
Definition: Terminal.cc:118
TTAProgram::Terminal::isTriggering
virtual bool isTriggering() const
Definition: Terminal.cc:298
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
MoveNodeGroupBuilder::programOperations_
ProgramOperationList programOperations_
Definition: MoveNodeGroupBuilder.hh:64
MoveNodeGroup.hh
TTAProgram::Instruction
Definition: Instruction.hh:57
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
TTAProgram::Terminal::hintOperation
virtual Operation & hintOperation() const
Definition: Terminal.cc:341
ProgramOperation
Definition: ProgramOperation.hh:70
TTAProgram::Move::toString
std::string toString() const
Definition: Move.cc:436
MoveNode
Definition: MoveNode.hh:65
MoveNodeGroup::setProgramOperationPtr
void setProgramOperationPtr(ProgramOperationPtr op)
in case this MNG contains strictly the nodes of a single operation, it can be set and queried with th...
Definition: MoveNodeGroup.hh:73
Terminal.hh
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
MoveNodeGroup::nodeCount
int nodeCount() const
Definition: MoveNodeGroup.cc:140
ProgramOperationPtr
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition: MoveNode.hh:52
TTAProgram::Terminal::operation
virtual Operation & operation() const
Definition: Terminal.cc:319
TCEString.hh
MoveNode::setSourceOperationPtr
void setSourceOperationPtr(ProgramOperationPtr po)
Definition: MoveNode.cc:541
assert
#define assert(condition)
Definition: Application.hh:86
MoveNodeGroupBuilder::build
MoveNodeGroupList * build(TTAProgram::BasicBlock &bb)
Definition: MoveNodeGroupBuilder.cc:57
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
TTAMachine::SpecialRegisterPort
Definition: SpecialRegisterPort.hh:48
Instruction.hh
MoveNode::addDestinationOperationPtr
void addDestinationOperationPtr(ProgramOperationPtr po)
Definition: MoveNode.cc:533
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
TTAProgram::Move
Definition: Move.hh:55
Machine.hh
Operation
Definition: Operation.hh:59
TTAProgram::Terminal::isOpcodeSetting
virtual bool isOpcodeSetting() const
Definition: Terminal.cc:285
MoveNodeGroup::toString
std::string toString() const
Definition: MoveNodeGroup.cc:248
ProgramOperation.hh
MoveNodeGroup::addNode
void addNode(MoveNode &node)
Definition: MoveNodeGroup.cc:70
TTAProgram::Terminal::functionUnit
virtual const TTAMachine::FunctionUnit & functionUnit() const
Definition: Terminal.cc:251
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
ProgramOperation::toString
std::string toString() const
Definition: ProgramOperation.cc:746
TCEString
Definition: TCEString.hh:53
BasicBlock.hh
SpecialRegisterPort.hh
TTAProgram::Terminal
Definition: Terminal.hh:60
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAProgram::Terminal::port
virtual const TTAMachine::Port & port() const
Definition: Terminal.cc:378
MoveNodeGroup
Definition: MoveNodeGroup.hh:48
TTAProgram::Instruction::movePtr
std::shared_ptr< Move > movePtr(int i) const
Definition: Instruction.cc:216
Move.hh
MoveNode.hh
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176
MoveNodeGroupBuilder::MoveNodeGroupList
std::list< MoveNodeGroup * > MoveNodeGroupList
Definition: MoveNodeGroupBuilder.hh:54
FunctionUnit.hh