OpenASIP 2.2
Loading...
Searching...
No Matches
MinimalOpSetCheck.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2010 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 MinimalOpSetCheck.cc
26 *
27 * Implementation of MinimalOpSetCheck class.
28 *
29 * @author Esa Määttä 2008 (esa.maatta-no.spam-tut.fi)
30 * @author Pekka Jääskeläinen 2010
31 * @note rating: red
32 */
33
34#include <set>
35#include <vector>
36#include <string>
37
38#include "MinimalOpSetCheck.hh"
39#include "FunctionUnit.hh"
40#include "Machine.hh"
41#include "Environment.hh"
43#include "CIStringSet.hh"
45
47 MachineCheck("Common helper functionality for minimal opset checks.") {
49}
50
53
54/**
55 * Checks if machine has all operations in minimal opset.
56 *
57 * @param machine Machine to be checked against minimal opset.
58 * @return True if minimal operation set was met, false otherwise.
59 */
60bool
65 // construct the opset list
66 for (int i = 0; i < fuNav.count(); i++) {
67 TTAMachine::FunctionUnit* fu = fuNav.item(i);
68 fu->operationNames(opSet);
69 }
70
71 // if machines opset is smaller than required opset
72 if (opSet.size() < minimalOpSet_.size()) {
73 return false;
74 }
75
76 TCETools::CIStringSet::const_iterator first1 = minimalOpSet_.begin();
77 TCETools::CIStringSet::const_iterator last1 = minimalOpSet_.end();
78
79 TCETools::CIStringSet::iterator first2 = opSet.begin();
80 TCETools::CIStringSet::iterator last2 = opSet.end();
81
82 // return false if missing operation was found
83 while (first1 != last1 && first2 != last2) {
84 if (*first1 < *first2) {
85 return false;
86 } else if (*first2 < *first1) {
87 ++first2;
88 } else {
89 ++first1;
90 ++first2;
91 }
92 }
93 if (first1 != last1) {
94 return false;
95 }
96 return true;
97}
98
99
100/**
101 * Checks the machine if it misses operations from the minimal op set.
102 *
103 * @param results Results of the validation are added to the given instance.
104 */
105bool
108 MachineCheckResults& results) const {
109
110 // construct the opset list
114 for (int i = 0; i < fuNav.count(); i++) {
115 TTAMachine::FunctionUnit* fu = fuNav.item(i);
116 fu->operationNames(opSet);
117 }
118
119 TCETools::CIStringSet::iterator first1 = minimalOpSet_.begin();
120 TCETools::CIStringSet::iterator last1 = minimalOpSet_.end();
121
122 TCETools::CIStringSet::iterator first2 = opSet.begin();
123 TCETools::CIStringSet::iterator last2 = opSet.end();
124
125 std::string eMsg = "Operation missing from the minimal operation set: ";
126
127 bool errorsAdded = false;
128 // missing opset is the difference towards minimalOpSet_
129 while (first1 != last1 && first2 != last2) {
130 if (*first1 < *first2) {
131 results.addError(*this, eMsg.append(*first1++));
132 errorsAdded = true;
133 } else if (*first2 < *first1) {
134 ++first2;
135 } else {
136 ++first1;
137 ++first2;
138 }
139 }
140 while (first1 != last1) {
141 results.addError(*this, eMsg.append(*first1++));
142 errorsAdded = true;
143 }
144 return !errorsAdded;
145}
146
147
148/**
149 * Checks if machine has all operations in minimal opset.
150 *
151 * Ignores fus with specified names from the check. This is useful with
152 * testing if minimal opset requirement breaks if a certain FUs are removed.
153 *
154 * @param machine Machine to be checked against minimal opset.
155 * @param ignoreFUs Names of the fus to be ignored regarding the check.
156 * @return True if minimal operation set was met, false otherwise.
157 */
158bool
161 const std::set<std::string>& ignoreFUName) const {
162
166 // construct the opset list
167 for (int i = 0; i < fuNav.count(); i++) {
168 TTAMachine::FunctionUnit* fu = fuNav.item(i);
169 if (ignoreFUName.find(fu->name()) == ignoreFUName.end()) {
170 fu->operationNames(opSet);
171 }
172 }
173
174 // if machines opset is smaller than required opset
175 if (opSet.size() < minimalOpSet_.size()) {
176 return false;
177 }
178
179 TCETools::CIStringSet::const_iterator first1 = minimalOpSet_.begin();
180 TCETools::CIStringSet::const_iterator last1 = minimalOpSet_.end();
181
182 TCETools::CIStringSet::iterator first2 = opSet.begin();
183 TCETools::CIStringSet::iterator last2 = opSet.end();
184
185 // return false if missing operation was found
186 while (first1 != last1 && first2 != last2) {
187 if (*first1 < *first2) {
188 return false;
189 } else if (*first2 < *first1) {
190 ++first2;
191 } else {
192 ++first1;
193 ++first2;
194 }
195 }
196 if (first1 != last1) {
197 return false;
198 }
199 return true;
200}
201
202
203/**
204 * Return operations that are missing from a machine.
205 *
206 * Returns operations that are missing from a machine compared to the minimal
207 * operation set.
208 *
209 * @param machine Machine to be checked against minimal opset.
210 * @param missingOps Vector where missing operation names are to be stored.
211 */
212void
215 std::vector<std::string>& missingOps) const {
216
217 // construct the opset list
221 for (int i = 0; i < fuNav.count(); i++) {
222 TTAMachine::FunctionUnit* fu = fuNav.item(i);
223 fu->operationNames(opSet);
224 }
225
226 TCETools::CIStringSet::const_iterator first1 = minimalOpSet_.begin();
227 TCETools::CIStringSet::const_iterator last1 = minimalOpSet_.end();
228
229 TCETools::CIStringSet::iterator first2 = opSet.begin();
230 TCETools::CIStringSet::iterator last2 = opSet.end();
231
232 // missing opset is the difference towards minimalOpSet_
233 while (first1 != last1 && first2 != last2) {
234 if (*first1 < *first2) {
235 missingOps.push_back(*first1++);
236 } else if (*first2 < *first1) {
237 ++first2;
238 } else {
239 ++first1;
240 ++first2;
241 }
242 }
243 while (first1 != last1) {
244 missingOps.push_back(*first1++);
245 }
246}
247
248
249/**
250 * Constructs a minimal opset from a given machine.
251 *
252 * @param machine Machine that is used as reference for minimal opset.
253 */
254void
256 bool deleteMach = false;
257 if (machine == NULL) {
259 deleteMach = true;
260 }
261
264 // construct the opset list
265 for (int i = 0; i < fuNav.count(); i++) {
266 TTAMachine::FunctionUnit* fu = fuNav.item(i);
268 }
269
270 if (deleteMach) {
271 delete machine;
272 machine = NULL;
273 }
274}
275
276
277/**
278 * Returns constructed minimal opset.
279 *
280 * @return Minimal opset as strings in a set.
281 */
286
287
288/**
289 * Adds FUs to the machine so that it doesn't miss operations anymore.
290 *
291 * Check is done against minimal opset.
292 *
293 * @param machine Machine to be checked against minimal opset and where FUs
294 * are inserted so that minimal opset is fulfilled.
295 * @return A short description what was done.
296 */
297std::string
299 std::vector<std::string> missingOps;
300 missingOperations(mach, missingOps);
301
302 if (missingOps.size() < 1) {
303 const std::string errorMessage = "No missing operations found.";
304 throw InvalidData(
305 __FILE__, __LINE__, __func__, errorMessage);
306 }
307
308 // go through minimal adf and add FUs that include missing ops
311
313 minMach->functionUnitNavigator();
314 std::set<std::string> fuAdded;
316
317 for (unsigned int moi = 0; moi < missingOps.size(); ++moi) {
318 for (int fui = 0; fui < fuNav.count(); ++fui) {
319 TTAMachine::FunctionUnit* fu = fuNav.item(fui);
320 if (fu->hasOperation(missingOps.at(moi))) {
321 if (fuAdded.end() != fuAdded.find(fu->name())) {
322 break;
323 }
324 fuAdded.insert(fu->name());
325 fu->unsetMachine();
326 mach.addFunctionUnit(*fu);
327 // connect the fu
328 for (int op = 0; op < fu->operationPortCount(); ++op) {
329 conCheck.connectFUPort(*fu->operationPort(op));
330 }
331 break;
332 }
333 }
334 }
335 delete minMach;
336 return "Operations were added to fulfill minimal opset requirements.";
337}
338
339/**
340 * Returns true if the checker can automatically fix the machine to pass
341 * the check.
342 *
343 * @return True, minimal opset can be always added to the machine.
344 */
345bool
347 return true;
348}
#define __func__
TTAMachine::Machine * machine
the architecture definition of the estimated processor
static std::string minimalADF()
void connectFUPort(TTAMachine::FUPort &port) const
void addError(const MachineCheck &check, const std::string &errorMsg)
virtual std::string fix(TTAMachine::Machine &machine) const
void missingOperations(const TTAMachine::Machine &machine, std::vector< std::string > &missingOps) const
virtual bool check(const TTAMachine::Machine &machine, MachineCheckResults &results) const
TCETools::CIStringSet minimalOpSet() const
TCETools::CIStringSet minimalOpSet_
virtual bool canFix(const TTAMachine::Machine &mach) const
void buildMinimalOpSet(const TTAMachine::Machine *machine=NULL)
bool checkWithIgnore(const TTAMachine::Machine &machine, const std::set< std::string > &ignoreFUName) const
virtual TCEString name() const
virtual void operationNames(TCETools::CIStringSet &opNames) const
virtual FUPort * operationPort(const std::string &name) const
virtual void unsetMachine()
virtual bool hasOperation(const std::string &name) const
virtual int operationPortCount() const
ComponentType * item(int index) const
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual void addFunctionUnit(FunctionUnit &unit)
Definition Machine.cc:202
static Machine * loadFromADF(const std::string &adfFileName)
Definition Machine.cc:899
std::set< TCEString, CaseInsensitiveCmp > CIStringSet