OpenASIP 2.2
Loading...
Searching...
No Matches
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
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"
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
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 }
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 }
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}
#define abortWithError(message)
#define assert(condition)
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition MoveNode.hh:53
static std::ostream & logStream()
std::list< MoveNodeGroup * > MoveNodeGroupList
MoveNodeGroupList * build(TTAProgram::BasicBlock &bb)
ProgramOperationList programOperations_
int nodeCount() const
void addNode(MoveNode &node)
void setProgramOperationPtr(ProgramOperationPtr op)
in case this MNG contains strictly the nodes of a single operation, it can be set and queried with th...
std::string toString() const
void setSourceOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:541
std::string toString() const
Definition MoveNode.cc:576
void addDestinationOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:533
std::string toString() const
virtual TCEString name() const
virtual int instructionCount() const
virtual Instruction & instructionAtIndex(int index) const
std::shared_ptr< Move > movePtr(int i) const
std::string toString() const
Definition Move.cc:436
Terminal & source() const
Definition Move.cc:302
Terminal & destination() const
Definition Move.cc:323
virtual bool isTriggering() const
Definition Terminal.cc:298
virtual Operation & hintOperation() const
Definition Terminal.cc:341
virtual const TTAMachine::FunctionUnit & functionUnit() const
Definition Terminal.cc:251
virtual bool isOpcodeSetting() const
Definition Terminal.cc:285
virtual Operation & operation() const
Definition Terminal.cc:319
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
virtual bool isFUPort() const
Definition Terminal.cc:118