OpenASIP 2.2
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Types | Private Attributes | List of all members
MoveNodeGroupBuilder Class Reference

#include <MoveNodeGroupBuilder.hh>

Collaboration diagram for MoveNodeGroupBuilder:
Collaboration graph

Public Types

typedef std::list< MoveNodeGroup * > MoveNodeGroupList
 

Public Member Functions

 MoveNodeGroupBuilder ()
 
virtual ~MoveNodeGroupBuilder ()
 
MoveNodeGroupListbuild (TTAProgram::BasicBlock &bb)
 

Private Types

typedef std::list< ProgramOperation * > ProgramOperationList
 

Private Attributes

ProgramOperationList programOperations_
 

Detailed Description

Builds a list of MoveNodeGroups (MNG) from the input basic block.

Also builds MoveNodes and ProgramOperations and ensures the produced MNG list is in the input sequential order and that each MNG contains either one MoveNode or a set of MoveNodes consisting a ProgramOperation.

Definition at line 52 of file MoveNodeGroupBuilder.hh.

Member Typedef Documentation

◆ MoveNodeGroupList

Definition at line 54 of file MoveNodeGroupBuilder.hh.

◆ ProgramOperationList

Definition at line 63 of file MoveNodeGroupBuilder.hh.

Constructor & Destructor Documentation

◆ MoveNodeGroupBuilder()

MoveNodeGroupBuilder::MoveNodeGroupBuilder ( )
inline

Definition at line 56 of file MoveNodeGroupBuilder.hh.

56{}

◆ ~MoveNodeGroupBuilder()

virtual MoveNodeGroupBuilder::~MoveNodeGroupBuilder ( )
inlinevirtual

Definition at line 57 of file MoveNodeGroupBuilder.hh.

57{}

Member Function Documentation

◆ build()

MoveNodeGroupBuilder::MoveNodeGroupList * MoveNodeGroupBuilder::build ( TTAProgram::BasicBlock bb)

Creates movenodes and programoperations from the given BB.

Also builds MoveNodes and ProgramOperations and ensures the produced MNG list is in the input sequential order and that each MNG contains either one MoveNode or a set of MoveNodes consisting a ProgramOperation. The returned objects become owned by the caller. This supports also input that is already bypassed.

Definition at line 57 of file MoveNodeGroupBuilder.cc.

57 {
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
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

References abortWithError, MoveNode::addDestinationOperationPtr(), MoveNodeGroup::addNode(), assert, TTAProgram::Move::destination(), TTAProgram::Terminal::functionUnit(), TTAProgram::Terminal::hintOperation(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Terminal::isFUPort(), TTAProgram::Terminal::isOpcodeSetting(), TTAProgram::Terminal::isTriggering(), Application::logStream(), TTAProgram::Instruction::moveCount(), TTAProgram::Instruction::movePtr(), TTAMachine::Component::name(), MoveNodeGroup::nodeCount(), TTAProgram::Terminal::operation(), TTAProgram::Terminal::port(), programOperations_, MoveNodeGroup::setProgramOperationPtr(), MoveNode::setSourceOperationPtr(), TTAProgram::Move::source(), MoveNodeGroup::toString(), TTAProgram::Move::toString(), MoveNode::toString(), and ProgramOperation::toString().

Referenced by LLVMTCEDataDependenceGraphBuilder::buildLocalDDG(), and SequentialMoveNodeSelector::SequentialMoveNodeSelector().

Here is the call graph for this function:

Member Data Documentation

◆ programOperations_

ProgramOperationList MoveNodeGroupBuilder::programOperations_
private

Definition at line 64 of file MoveNodeGroupBuilder.hh.

Referenced by build().


The documentation for this class was generated from the following files: