OpenASIP  2.0
OperationDAGConverter.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 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 OperationDAGConverter.cc
26  *
27  * Implementation of OperationDAGConverter class.
28  *
29  * @author Mikael Lepistö 2007 (tmlepist-no.spam-cs.tut.fi)
30  * @note rating: red
31  */
32 
33 #include "OperationDAGConverter.hh"
34 #include "OperationDAGBuilder.hh"
36 
37 #include "CompilerWarnings.hh"
38 IGNORE_CLANG_WARNING("-Wunused-local-typedef")
39 #include <boost/algorithm/string.hpp>
40 #include <boost/algorithm/string/trim.hpp>
42 
43 #include "OperationPool.hh"
44 #include "OperationNode.hh"
45 #include "OperationDAGEdge.hh"
46 #include "TerminalNode.hh"
47 #include "ConstantNode.hh"
48 #include "Operation.hh"
49 #include "TCEString.hh"
50 #include "OperationDAG.hh"
51 #include "OperationPimpl.hh"
52 
53 /**
54  * Creates OperationDAG out of OSAL DAG language source code.
55  *
56  * @param sourceCode OSAL DAG Language source code.
57  * @return Dynamically allocated OperationDAG instance.
58  * @exception IllegalParameters There was an error during parsing.
59  */
61 OperationDAGConverter::createDAG(const OperationPimpl& operation, std::string sourceCode) {
63  skip_grammar skip;
64 
65  // lets add semicolon to end of file to make boost 1.34 happy
66  sourceCode += "\n;";
67 
68  const char *orig = sourceCode.c_str();
69 
70  //std::cerr << "source code" << std::endl << sourceCode << std::endl;
71 
72  parse_info<const char*> result =
73  parse(orig, g, skip);
74 
75  if (result.full) {
77  OperationDAG* retVal = new OperationDAG(operation);
78  OperationDAGBuilder builder(operation, *retVal, *root);
79 
80  // std::cerr << g.tokenData_.tokenTree()->toStr() << std::endl;
81 
82  builder.parse();
83  return retVal;
84 
85  } else {
86  for (unsigned int i = 0; i < skip.strippedParts.size(); i++) {
87  skip.strippedParts[i].second -=
88  reinterpret_cast<long int>(skip.strippedParts[i].first);
89 
90  skip.strippedParts[i].first -= reinterpret_cast<long int>(orig);
91 
92  //std::cerr << "Skipped " << int(skip.strippedParts[i].second)
93  //<< " chars at pos " << int(skip.strippedParts[i].first)
94  //<< " line: \""
95  //<< sourceCode.substr(int(skip.strippedParts[i].first),
96  //int(skip.strippedParts[i].second)) << "\"" << std::endl;
97  }
98 
99  // find character count in original code
100  unsigned int charsToPos = 0;
101  for (unsigned int i = 0; i < result.length ; i++) {
102 
103  for (unsigned int j = 0; j < skip.strippedParts.size(); j++) {
104  if ((unsigned long int)skip.strippedParts[j].first
105  == charsToPos) {
106  charsToPos +=
107  reinterpret_cast<long int>(skip.strippedParts[j].second);
108 
109  //std::cerr << std::endl << "Added at position: "
110  //<< int(skip.strippedParts[j].first)
111  //<< " to char length: "
112  //<< int(skip.strippedParts[j].second);
113  }
114  }
115 
116  charsToPos++;
117  }
118 
119  // find line number
120  int lineNumber = 1;
121  for (unsigned int i = 0; i < charsToPos; i++) {
122  if (sourceCode.at(i) == '\n') {
123  lineNumber++;
124  }
125  }
126 
127  // get logical line
128  int lineStart = sourceCode.rfind(';', charsToPos);
129  int lineEnd = sourceCode.find(';', charsToPos);
130 
131  std::string errorLine =
132  boost::algorithm::trim_copy(
133  sourceCode.substr(lineStart + 1, lineEnd - lineStart));
134 
135  // std::cerr << "result.stop: " << result.stop << std::endl
136  // << "result.hit: " << result.hit << std::endl
137  // << "result.full: " << result.full << std::endl
138  // << "result.length: " << result.length << std::endl;
139 
140  std::string message = "Parsing failed at the position " +
141  Conversion::toString(result.length) + " in the code.\n" +
142  "line " + Conversion::toString(lineNumber) + ": " + errorLine;
143 
144  //std::cerr << message << std::endl;
145 
146  throw IllegalParameters(__FILE__, __LINE__, __func__, message);
147  }
148  return NULL;
149 }
150 
151 
152 /**
153  * Writes node and all the nodes connected as osal code.
154  *
155  * @param retVal String where to code is written.
156  * @param dag Dag that contains the nodes.
157  * @param node Currently written node.
158  * @param varBindings Names of variables that are bound for TerminalNodes and
159  * OperandNode outputs.
160  * @param alreadyHandled If node is included to this ser if it is
161  * already fully written and all its operands are handled.
162  * @param tempVarCount Number of variables created.
163  * @param currentlyHandling Node is in this set if it's currently handled in
164  * some recursion level.
165  * @param opReplace Map of operation names and C operators that can simulate them.
166  * @return false If node is already in middle of handling.
167  */
168 #define DEBUG_CODE(x)
169 
170 bool
172  std::string& retVal,
173  const OperationDAG& dag,
174  const OperationDAGNode& node,
175  std::map<VariableKey, std::string>& varBindings,
176  std::set<const OperationDAGNode*>& alreadyHandled,
177  int& tempVarCount,
178  std::set<const OperationDAGNode*>& currentlyHandling,
179  std::map<std::string, std::string>* opReplace,
180  std::vector<std::string>* varReplacements) {
181 
182  static int tmpCounter = 0;
183 
184  DEBUG_CODE(static std::string recursion_level = ""; recursion_level += "----";);
185 
186  int currentStepsToRoot = dag.stepsToRoot(node);
187 
188  if (currentlyHandling.find(&node) != currentlyHandling.end()) {
189  DEBUG_CODE(recursion_level = recursion_level.erase(0,4););
190  return false;
191  }
192 
193  if (alreadyHandled.find(&node) == alreadyHandled.end()) {
194 
195  currentlyHandling.insert(&node);
196 
197  const TerminalNode* termNode =
198  dynamic_cast<const TerminalNode*>(&node);
199  const ConstantNode* constNode =
200  dynamic_cast<const ConstantNode*>(&node);
201 
202  if (constNode != NULL) {
203  currentlyHandling.erase(constNode);
204  alreadyHandled.insert(constNode);
205  VariableKey termKey(constNode, 0);
206  varBindings[termKey] = constNode->toString();
207  return true;
208  } else if (termNode != NULL) {
209  // Node is input or output terminal or a const. Either set
210  // variablename e.g. IO(1) to node to varBindings or
211  // write variable
212  // value to output node e.g. "IO(4) = tmp12;\n"
213 
214  std::string ioName = "";
215  if (!varReplacements ||
216  (termNode->operandIndex() - 1) > (int)varReplacements->size()) {
217  ioName = "IO(" +
218  Conversion::toString(termNode->operandIndex()) + ")";
219  } else {
220  ioName = varReplacements->at(termNode->operandIndex() - 1);
221  }
222 
223  VariableKey termKey(termNode, termNode->operandIndex());
224 
225  DEBUG_CODE(std::cerr << recursion_level
226  << "**** Started handling term node " << long(&node)
227  << ":" << currentStepsToRoot << ":" + ioName + "\n";);
228 
229  const bool inputTerminalNode = dag.inDegree(*termNode) == 0;
230  if (inputTerminalNode) {
231  // TODO: should only do extension here if different bit widths
232  TCEString tmpName = "inTmp_"; tmpName << tmpCounter++;
233  retVal += "SimValue " + tmpName + ";\n";
234  retVal += tmpName + " = " +
235  castedVar(ioName, dag.operation().operand(
236  termNode->operandIndex()).type()) + ";\n";
237 
238  // set veriable binding for reading (the extended) terminal value
239  varBindings[termKey] = tmpName;
240  DEBUG_CODE(std::cerr << recursion_level
241  << "Added input terminal: " + ioName + "\n";);
242 
243  } else {
244 
245  assert(dag.outDegree(*termNode) == 0);
246 
247  OperationDAGEdge& srcEdge = dag.inEdge(*termNode, 0);
248  OperationDAGNode& tail = dag.tailNode(srcEdge);
249 
250  DEBUG_CODE(std::cerr << recursion_level
251  << "** Read input of terminal " << ioName << "\n";);
252 
253  writeNode(
254  retVal, dag, tail, varBindings, alreadyHandled,
255  tempVarCount, currentlyHandling, opReplace, varReplacements);
256  DEBUG_CODE(std::cerr << recursion_level
257  << "** Ready reading input of terminal " << ioName << "\n";);
258  VariableKey srcKey(&tail, srcEdge.srcOperand());
259 
260  // write result to output terminal
261  retVal += ioName + " = " + varBindings[srcKey] + ";\n";
262  }
263 
264  DEBUG_CODE(std::cerr << recursion_level
265  << "added terminal " << long (&node)
266  << "to already handled nodes\n";);
267 
268  currentlyHandling.erase(termNode);
269  alreadyHandled.insert(termNode);
270 
271  } else {
272  // Node is operation node. Read inputs and create destination
273  // variables for outputs. In the end write EXEC_OPERATION
274  // line to code.
275 
276  const OperationNode* opNode =
277  dynamic_cast<const OperationNode*>(&node);
278 
279  if (opNode == NULL) {
281  (boost::format(
282  "Must be either OperationNode or Terminal Node. "
283  "Got: %s.") % node.toString()).str());
284  }
285 
286  Operation &refOp = opNode->referencedOperation();
287 
288  DEBUG_CODE(std::cerr << recursion_level
289  << "Started handling opnode " << long(&node) << ":"
290  << currentStepsToRoot << ": " + refOp.name() + "\n";);
291 
292  // go through in edges, copy bindings and create input string for
293  // EXEC_OPERATION
294 
295  std::vector<std::string> operandVec(
296  refOp.numberOfInputs() + refOp.numberOfOutputs());
297 
298  // kludge: this vector has 'true' in the operand's
299  // position only if the operand is a constant and
300  // thus needs not to be casted to IntWord with
301  // castedVar later when generating the operation
302  // parameters
303  std::vector<bool> isConstOperand(
304  refOp.numberOfInputs() + refOp.numberOfOutputs());
305 
306  // input parameters
307  for (int i = 0; i < dag.inDegree(node); i++) {
308  OperationDAGEdge& edge = dag.inEdge(node, i);
309  OperationDAGNode& tail = dag.tailNode(edge);
310 
311  const TerminalNode* termTail =
312  dynamic_cast<const TerminalNode*>(&tail);
313 
314  int srcOperand;
315  if (termTail != 0) {
316  srcOperand = termTail->operandIndex();
317  } else {
318  srcOperand = edge.srcOperand();
319  }
320 
321  VariableKey sourceKey;
322  if (dynamic_cast<const ConstantNode*>(&tail) != NULL) {
323  sourceKey = VariableKey(&tail, 0);
324  isConstOperand[edge.dstOperand()-1] = true;
325  } else {
326  sourceKey = VariableKey(&tail, srcOperand);
327  isConstOperand[edge.dstOperand()-1] = false;
328  }
329 
330  // if input not already handled, treat it first.
331  DEBUG_CODE(std::cerr << recursion_level
332  << "** Read input op: " << refOp.name() << ":" << i << "\n";);
333 
334  if (!writeNode(retVal, dag, tail, varBindings,
335  alreadyHandled, tempVarCount, currentlyHandling, opReplace, varReplacements)) {
336 
337  DEBUG_CODE(std::cerr << recursion_level
338  << "Input can't be read yet: " << refOp.name() << ":" << i << "\n";);
339 
340  currentlyHandling.erase(&node);
341 
342  DEBUG_CODE(recursion_level = recursion_level.erase(0,4););
343  return false;
344  }
345 
346  DEBUG_CODE(std::cerr << recursion_level
347  << "** Ready reading input of op: " << refOp.name() << ":" << i << "\n";);
348 
349  // add input to correct place in EXEC_OPERATION parameter list
350  if (varBindings[sourceKey].empty()) {
351  throw IllegalParameters(
352  __FILE__, __LINE__, __func__,
353  std::string(
354  "DAG cannot be written to OSAL code, because illegal output edge. "
355  "Edge srcOperand: ") + Conversion::toString(srcOperand));
356  }
357 
358  operandVec[edge.dstOperand()-1] = varBindings[sourceKey];
359 
360  DEBUG_CODE(std::cerr << recursion_level
361  << "Added operand: " << varBindings[sourceKey]
362  << " key: (" << sourceKey.first << ":" << sourceKey.second << ")"
363  << " to " << refOp.name() << " paramer vector index: "
364  << edge.dstOperand() - 1 << std::endl;);
365  }
366 
367  // and outputs
368  for (int i = 0; i < refOp.numberOfOutputs(); i++) {
369  int opNumber = i + refOp.numberOfInputs() + 1;
370  VariableKey operandKey(&node, opNumber);
371  tempVarCount++;
372  std::string tempVarName = "tmp" +
373  Conversion::toString(tempVarCount);
374  retVal = "SimValue " + tempVarName + ";\n" + retVal;
375  varBindings[operandKey] = tempVarName;
376 
377  DEBUG_CODE(std::cerr << recursion_level
378  << "Created variable: " << tempVarName
379  << " key: (" << operandKey.first << ":" << operandKey.second << ")"
380  << " for " << refOp.name() << ":" << opNumber << std::endl;);
381 
382  // add output to EXEC_OPERATION parameter list
383  operandVec[opNumber-1] = varBindings[operandKey];
384  DEBUG_CODE(std::cerr << recursion_level
385  << "Added operand: " << varBindings[operandKey]
386  << " to " << refOp.name() << " paramer vector index: "
387  << opNumber -1 << std::endl;);
388  }
389 
390  // this node is processed.
391  DEBUG_CODE(std::cerr << recursion_level << "added node "
392  << long (&node) << "to already handled nodes\n" ;);
393 
394  currentlyHandling.erase(&node);
395  alreadyHandled.insert(&node);
396 
397  // Write the execute operation code
398  if (opReplace != NULL &&
399  opReplace->find(refOp.name()) != opReplace->end()) {
400  std::string simOp = (*opReplace)[refOp.name()];
401 
402  std::string rightSide = "";
403  if (isConstOperand[0]) {
404  // the consts need not to be casted
405  rightSide = operandVec[0];
406  } else {
407  rightSide = castedVar(operandVec[0], refOp.operand(1).type());
408  }
409 
410  // if unary operator
411  if (refOp.numberOfInputs() == 1) {
412  rightSide = simOp + rightSide;
413  } else {
414  for (int i = 1; i < refOp.numberOfInputs(); i++) {
415  if (isConstOperand[i]) {
416  rightSide +=
417  " " + simOp + " " + operandVec[i];
418  } else {
419  rightSide +=
420  " " + simOp + " " +
421  castedVar(
422  operandVec[i],
423  refOp.operand(i+1).type());
424  }
425  }
426  }
427 
428  assert(refOp.numberOfOutputs() == 1 &&
429  "Cant write simulation replacement code only"
430  "for singleoutput operations.");
431 
432  // assing right side to first outputoperand.
433  retVal += operandVec[refOp.numberOfInputs()] +
434  " = " + rightSide + ";\n";
435 
436  } else {
437  retVal += "{ EXEC_OPERATION(" + std::string(refOp.name());
438  for (unsigned int i = 0; i < operandVec.size(); i++) {
439  retVal += ", " + operandVec[i];
440  }
441  retVal += "); } \n";
442 
443  DEBUG_CODE(std::cerr << recursion_level
444  << "Added EXEC: " + refOp.name() << std::endl;);
445  }
446 
447  // write outgoing nodes
448  for (int i = 0; i < dag.outDegree(node); i++) {
449  OperationDAGNode& headNode =
450  dag.headNode(dag.outEdge(node,i));
451 
452  // handle only those nodes, which are one step away from
453  // curren node.
454  if (dag.stepsToRoot(headNode) == currentStepsToRoot + 1) {
455  DEBUG_CODE(std::cerr << recursion_level
456  << "** Goto output op: " << refOp.name()
457  << ":" << i << "\n";);
458 
459  writeNode(retVal, dag, headNode, varBindings,
460  alreadyHandled, tempVarCount, currentlyHandling, opReplace, varReplacements);
461 
462  DEBUG_CODE(std::cerr << recursion_level
463  << recursion_level
464  << "** Ready going output op: " << refOp.name()
465  << ":" << i << "\n";);
466  }
467  }
468  }
469  }
470 
471  DEBUG_CODE(recursion_level = recursion_level.erase(0,4););
472  return true;
473 }
474 
475 /**
476  * Cast variable to be correct type.
477  */
478 std::string
480  std::string var, Operand::OperandType type) {
481 
482  switch (type) {
483  case Operand::SINT_WORD:
484  return var + ".sIntWordValue()";
485  case Operand::UINT_WORD:
486  return var + ".uIntWordValue()";
487  case Operand::FLOAT_WORD:
488  return var + ".floatWordValue()";
490  return var + ".halfFloatWordValue()";
492  return var + ".doubleWordValue()";
493  case Operand::ULONG_WORD:
494  return var + ".uLongWordValue()";
495  case Operand::SLONG_WORD:
496  return var + ".sLongWordValue()";
497  default:
498  return var;
499  }
500 }
501 
502 
503 /**
504  * Write OSAL DAG code for graph.
505  *
506  * @param dag Graph to write as OSAL code (basically C subset)
507  */
508 std::string
510  std::string retVal;
511  std::map<VariableKey, std::string> varBindings;
512  std::set<const OperationDAGNode*> alreadyHandled;
513  std::set<const OperationDAGNode*> currentlyHandling;
514  int tempVarCount = 0;
515 
516  if (dag.nodeCount() == 0) {
517  return retVal;
518  }
519 
520  // Writes recursively all the DAG from node(0)
521  writeNode(retVal, dag, dag.node(0), varBindings,
522  alreadyHandled, tempVarCount, currentlyHandling);
523 
524  return retVal;
525 }
526 
527 /**
528  * Optimizations, when compiled simulation code is created from DAG.
529  *
530  * OSAL implementations of operantions will not be called for calculating
531  * basic C operations.
532  */
533 std::string
535  const OperationDAG& dag,
536  std::vector<std::string>* varReplacements) {
537  std::string retVal;
538  std::map<VariableKey, std::string> varBindings;
539  std::set<const OperationDAGNode*> alreadyHandled;
540  std::set<const OperationDAGNode*> currentlyHandling;
541  int tempVarCount = 0;
542  std::map<std::string, std::string> opReplacements;
543 
544  opReplacements["ADD"] = "+";
545  opReplacements["SUB"] = "-";
546  opReplacements["MUL"] = "*";
547  opReplacements["DIV"] = "/";
548  opReplacements["DIVU"] = "/";
549  opReplacements["EQ"] = "==";
550  opReplacements["GT"] = ">";
551  opReplacements["GTU"] = ">";
552  opReplacements["SHL"] = "<<";
553  opReplacements["SHR"] = ">>";
554  opReplacements["SHRU"] = ">>";
555  opReplacements["AND"] = "&";
556  opReplacements["IOR"] = "|";
557  opReplacements["XOR"] = "^";
558  opReplacements["NEG"] = "-";
559  opReplacements["NEGF"] = "-";
560  opReplacements["ADDF"] = "+";
561  opReplacements["SUBF"] = "-";
562  opReplacements["MULF"] = "*";
563  opReplacements["DIVF"] = "/";
564  opReplacements["EQF"] = "==";
565  opReplacements["GTF"] = ">";
566  opReplacements["CFI"] = "(UIntWord)";
567  opReplacements["CIF"] = "(FloatWord)";
568  opReplacements["CFD"] = "(DoubleWord)";
569  opReplacements["CDF"] = "(FloatWord)";
570  opReplacements["MOD"] = "%";
571  opReplacements["MODU"] = "%";
572  opReplacements["MULH"] = "*";
573 
574  opReplacements["ADD64"] = "+";
575  opReplacements["SUB64"] = "-";
576  opReplacements["MUL64"] = "*";
577  opReplacements["DIV64"] = "/";
578  opReplacements["DIVU64"] = "/";
579  opReplacements["EQ64"] = "==";
580  opReplacements["GT64"] = ">";
581  opReplacements["GTU64"] = ">";
582  opReplacements["SHL64"] = "<<";
583  opReplacements["SHR64"] = ">>";
584  opReplacements["SHRU64"] = ">>";
585  opReplacements["AND64"] = "&";
586  opReplacements["IOR64"] = "|";
587  opReplacements["XOR64"] = "^";
588  opReplacements["NEG64"] = "-";
589  opReplacements["NEGF64"] = "-";
590  opReplacements["ADDF64"] = "+";
591  opReplacements["SUBF64"] = "-";
592  opReplacements["MULF64"] = "*";
593  opReplacements["DIVF64"] = "/";
594  opReplacements["EQF64"] = "==";
595  opReplacements["GTF64"] = ">";
596  opReplacements["CFI64"] = "(UIntWord)";
597  opReplacements["CIF64"] = "(FloatWord)";
598  opReplacements["CFD64"] = "(DoubleWord)";
599  opReplacements["CDF64"] = "(FloatWord)";
600  opReplacements["MOD64"] = "%";
601  opReplacements["MODU64"] = "%";
602 
603  // Writes recursively all the DAG from node(0)
604  // But this recursion does not work so added the loop
605  // to make sure all nodes get processed.
606  OperationDAGNode* node;
607  for (int i = 0; i < dag.nodeCount(); i++) {
608  node = &dag.node(i);
609  if (alreadyHandled.find(node) == alreadyHandled.end()) {
610  writeNode(retVal, dag, *node, varBindings,
611  alreadyHandled, tempVarCount, currentlyHandling,
612  &opReplacements, varReplacements);
613  }
614  }
615  return retVal;
616 }
OperationDAGEdge::dstOperand
int dstOperand() const
Definition: OperationDAGEdge.cc:54
OperationDAGLanguageParser.hh
BoostGraph::outEdge
virtual Edge & outEdge(const Node &node, const int index) const
POP_CLANG_DIAGS
#define POP_CLANG_DIAGS
Definition: CompilerWarnings.hh:96
OperationDAGLanguageGrammar::tokenData_
TokenizerData tokenData_
Definition: OperationDAGLanguageParser.hh:1917
BoostGraph::tailNode
virtual Node & tailNode(const Edge &edge) const
BoostGraph::headNode
virtual Node & headNode(const Edge &edge) const
Operand::OperandType
OperandType
Definition: Operand.hh:58
Operand::HALF_FLOAT_WORD
@ HALF_FLOAT_WORD
Definition: Operand.hh:63
BoostGraph::node
Node & node(const int index) const
OperationPimpl
Definition: OperationPimpl.hh:54
OperationDAGConverter.hh
OperationDAGConverter::createOsalCode
static std::string createOsalCode(const OperationDAG &dag)
Definition: OperationDAGConverter.cc:509
skip_grammar
Definition: OperationDAGLanguageParser.hh:751
IGNORE_CLANG_WARNING
#define IGNORE_CLANG_WARNING(X)
Definition: CompilerWarnings.hh:85
Operand::UINT_WORD
@ UINT_WORD
Definition: Operand.hh:60
ConstantNode::toString
virtual std::string toString() const
Definition: ConstantNode.cc:65
TerminalNode
Definition: TerminalNode.hh:47
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
OperationNode::referencedOperation
Operation & referencedOperation() const
Definition: OperationNode.cc:70
OperationNode
Definition: OperationNode.hh:47
GraphNode::toString
virtual std::string toString() const
Definition: GraphNode.cc:61
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
OperationDAGEdge
Definition: OperationDAGEdge.hh:38
Conversion::toString
static std::string toString(const T &source)
BoostGraph::outDegree
virtual int outDegree(const Node &node) const
OperationDAGBuilder::parse
void parse()
Definition: OperationDAGBuilder.cc:64
TCEString.hh
assert
#define assert(condition)
Definition: Application.hh:86
skip_grammar::strippedParts
std::vector< std::pair< const char *, const char * > > strippedParts
Definition: OperationDAGLanguageParser.hh:783
OperationDAGEdge.hh
IllegalParameters
Definition: Exception.hh:113
DEBUG_CODE
#define DEBUG_CODE(x)
Definition: OperationDAGConverter.cc:168
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
OperationDAGEdge::srcOperand
int srcOperand() const
Definition: OperationDAGEdge.cc:49
OperationDAGNode
Definition: OperationDAGNode.hh:45
OperationDAGLanguageGrammar
Definition: OperationDAGLanguageParser.hh:787
Operand::SLONG_WORD
@ SLONG_WORD
Definition: Operand.hh:66
BoostGraph::inEdge
virtual Edge & inEdge(const Node &node, const int index) const
TokenizerData::TokenTreeNode
Definition: OperationDAGLanguageParser.hh:397
OperationDAG.hh
OperationDAG
Definition: OperationDAG.hh:43
__func__
#define __func__
Definition: Application.hh:67
Operand::FLOAT_WORD
@ FLOAT_WORD
Definition: Operand.hh:61
ConstantNode
Definition: ConstantNode.hh:43
OperationDAGBuilder
Definition: OperationDAGBuilder.hh:47
Operation.hh
OperationDAGConverter::castedVar
static std::string castedVar(std::string var, Operand::OperandType type)
Definition: OperationDAGConverter.cc:479
OperationPimpl::operand
Operand & operand(int id) const
Definition: OperationPimpl.cc:655
OperationPimpl.hh
OperationDAGConverter::createSimulationCode
static std::string createSimulationCode(const OperationDAG &dag, std::vector< std::string > *varReplacements=NULL)
Definition: OperationDAGConverter.cc:534
Operand::SINT_WORD
@ SINT_WORD
Definition: Operand.hh:59
Operand::ULONG_WORD
@ ULONG_WORD
Definition: Operand.hh:67
BoostGraph::inDegree
virtual int inDegree(const Node &node) const
OperationDAGConverter::writeNode
static bool writeNode(std::string &retVal, const OperationDAG &dag, const OperationDAGNode &node, std::map< VariableKey, std::string > &varBindings, std::set< const OperationDAGNode * > &alreadyHandled, int &tempVarCount, std::set< const OperationDAGNode * > &currentlyHandling, std::map< std::string, std::string > *opReplace=NULL, std::vector< std::string > *varReplacements=NULL)
Definition: OperationDAGConverter.cc:171
Operation
Definition: Operation.hh:59
Operand::DOUBLE_WORD
@ DOUBLE_WORD
Definition: Operand.hh:62
Operation::operand
virtual Operand & operand(int id) const
Definition: Operation.cc:541
Operand::type
virtual OperandType type() const
Definition: Operand.cc:165
TCEString
Definition: TCEString.hh:53
OperationDAGConverter::VariableKey
std::pair< const OperationDAGNode *, int > VariableKey
Definition: OperationDAGConverter.hh:60
OperationDAGBuilder.hh
OperationDAG::stepsToRoot
int stepsToRoot(const OperationDAGNode &node) const
Definition: OperationDAG.cc:108
TerminalNode.hh
ConstantNode.hh
OperationNode.hh
TokenizerData::tokenTree
const TokenTreeNode * tokenTree() const
Definition: OperationDAGLanguageParser.hh:699
BoostGraph::nodeCount
int nodeCount() const
OperationPool.hh
Operation::numberOfOutputs
virtual int numberOfOutputs() const
Definition: Operation.cc:202
OperationDAG::operation
const class OperationPimpl & operation() const
Definition: OperationDAG.hh:59
TerminalNode::operandIndex
virtual int operandIndex() const
Definition: TerminalNode.cc:60
CompilerWarnings.hh
OperationDAGConverter::createDAG
static OperationDAG * createDAG(const OperationPimpl &operation, std::string sourceCode)
Definition: OperationDAGConverter.cc:61