ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VariableRenaming.h
Go to the documentation of this file.
1 //Author: Justin Frye
2 
3 #ifndef SSAANALYSIS_H
4 #define SSAANALYSIS_H
5 
6 #include <string>
7 #include <iostream>
8 #include <map>
9 #include <vector>
10 #include <algorithm>
11 #include <ostream>
12 #include <fstream>
13 #include <sstream>
14 #include <boost/foreach.hpp>
15 #include "filteredCFG.h"
16 #include <boost/unordered_map.hpp>
17 
27 {
28 private:
29 
34  std::vector<SgInitializedName*> key;
35 
36  bool usesThis; // this pointer??
37 
38 public:
41  VarUniqueName() : key(), usesThis(false)
42  {
43  }
44 
52  {
53  key.push_back(thisNode);
54  }
55 
64  VarUniqueName(const std::vector<SgInitializedName*>& prefix, SgInitializedName* thisNode):usesThis(false)
65  {
66  key.assign(prefix.begin(),prefix.end());
67  key.push_back(thisNode);
68  }
69 
74  VarUniqueName(const VarUniqueName& other): AstAttribute(other), usesThis(false)
75  {
76  key.assign(other.key.begin(), other.key.end());
77  }
78 
80  {
81  VarUniqueName* newName = new VarUniqueName(*this);
82  return newName;
83  }
84 
89  std::vector<SgInitializedName*>& getKey() { return key; }
90 
95  void setKey(const std::vector<SgInitializedName*>& newKey) { key.assign(newKey.begin(),newKey.end()); }
96 
97  bool getUsesThis() { return usesThis; }
98  void setUsesThis(bool uses) { usesThis = uses; }
99 
104  std::string getNameString()
105  {
106  std::string name = "";
107  std::vector<SgInitializedName*>::iterator iter;
108  if(usesThis)
109  name += "this->";
110  for(iter = key.begin(); iter != key.end(); ++iter)
111  {
112  if(iter != key.begin())
113  {
114  name += ":"; // why ":" instead of "." ??
115  }
116  name += (*iter)->get_name().getString();
117  }
118 
119  return name;
120  }
121 };
127 {
133  bool operator() (CFGNode cfgn) const
134  {
135  SgNode *node = cfgn.getNode();
136 
137  //If it is the last node in a function call, keep it
138  if (isSgFunctionCallExp(node) && cfgn == node->cfgForEnd())
139  return true;
140 
141  //The begin edges of basic blocks are not considered interesting, but we would like to keep them
142  //This is so we can propagate reachable defs to the top of a basic block
143  if (isSgBasicBlock(node) && cfgn == node->cfgForBeginning())
144  return true;
145 
146  if (isSgExprStatement(node))
147  return (cfgn == node->cfgForBeginning());
148 
149  if (isSgCommaOpExp(node))
150  return (cfgn == node->cfgForBeginning());
151 
152  //Remove all non-interesting nodes
153  //putting this if-statement here may shadow the rest statements, by Liao
154  //TODO this may be a bug, it should be moved to the end
155  if (!cfgn.isInteresting())
156  return false;
157 
158  //Remove all non-end nodes for initNames
159  if (isSgInitializedName(node) && cfgn != node->cfgForEnd())
160  return false;
161 
162  //Remove non-beginning nodes for try statements
163  if (isSgTryStmt(node) && cfgn != node->cfgForBeginning())
164  return false;
165 
166  //Use the last node of binary operators
167  if (isSgAndOp(node) || isSgOrOp(node))
168  {
169  if (cfgn != node->cfgForEnd())
170  return false;
171  }
172 
173  //We only want the middle appearance of the teritatry operator - after its conditional expression
174  //and before the true and false bodies. This makes it behave as an if statement for data flow
175  //purposes
176  if (isSgConditionalExp(node))
177  {
178  return cfgn.getIndex() == 1;
179  }
180 
181  return true;
182  }
183 };
184 
194 {
195 private:
201 
202 public:
205  typedef std::vector<SgNode*> NodeVec;
208  typedef std::vector<SgInitializedName*> VarName;
211  typedef std::map<VarName, NodeVec> TableEntry;
214  typedef boost::unordered_map<SgNode*, TableEntry> DefUseTable;
217  typedef boost::unordered_map<VarName, SgNode*> FirstDefTable;
218 
221  typedef std::vector<SgInitializedName*> InitNameVec;
224  typedef FilteredCFGNode<IsDefUseFilter> cfgNode;
227  typedef FilteredCFGEdge<IsDefUseFilter> cfgEdge;
230  typedef std::vector<cfgNode> cfgNodeVec;
233  typedef std::vector<cfgEdge> cfgEdgeVec;
236  typedef std::map<SgNode*, int> NodeNumRenameEntry;
239  typedef boost::unordered_map<VarName, NodeNumRenameEntry> NodeNumRenameTable;
242  typedef std::map<int, SgNode*> NumNodeRenameEntry;
245  typedef boost::unordered_map<VarName, NumNodeRenameEntry> NumNodeRenameTable;
246 
247 
248 private:
249  //Private member variables
250 
255 
260 
266 
272 
280 
286 
292 
293 public:
294  VariableRenaming(SgProject* proj): project(proj), DEBUG_MODE(SgProject::get_verbose() > 0), DEBUG_MODE_EXTRA(SgProject::get_verbose() > 1){}
295 
297 
298  void run();
299 
300  bool getDebug() const { return DEBUG_MODE; }
301  bool getDebugExtra() const { return DEBUG_MODE_EXTRA; }
302 
303 private:
304  void runDefUse(SgFunctionDefinition* func);
305  bool defUse(cfgNode node, bool *memberRefInserted, NodeVec &changedNodes);
306 
318  int addRenameNumberForNode(const VarName& var, SgNode* node);
319 
320  bool isBuiltinVar(const VarName& var);
321 
334  bool mergeDefs(cfgNode curNode, bool *memberRefInserted, NodeVec &changedNodes);
335 
347  bool resolveUses(cfgNode curNode, bool *memberRefInserted, NodeVec &changedNodes);
348 
354  void aggregatePreviousDefs(cfgNode curNode, TableEntry& results);
355 
371  bool expandMemberDefinitions(cfgNode curNode);
372 
394  bool insertExpandedDefsForUse(cfgNode curNode, VarName name, NodeVec &changedNodes);
395 
412  bool expandMemberUses(cfgNode curNode);
413 
416 
418  std::set<VarName> getVarsUsedInSubtree(SgNode* root);
419 
420  void printToDOT(SgSourceFile* file, std::ofstream &outFile);
421  void printToFilteredDOT(SgSourceFile* file, std::ofstream &outFile);
422 
423  void printUses(const TableEntry& table);
424  void printDefs(const TableEntry& table);
425 
426 public:
427  //External static helper functions/variables
430  static std::string varKeyTag;
431 
437 
439 
441 
443 
444 
445  /*
446  * Printing functions.
447  */
448 
453  void toDOT(const std::string fileName);
454 
462  void toFilteredDOT(const std::string fileName);
463 
469  static std::string keyToString(const VarName& vec);
470 
471  void printDefs(SgNode* node);
472 
473  void printOriginalDefs(SgNode* node);
474 
475  void printOriginalDefTable();
476 
477  void printUses(SgNode* node);
478 
479  void printRenameTable();
480 
481  void printRenameTable(const VarName& var);
482 
483  static void printRenameTable(const NodeNumRenameTable& table);
484 
485  static void printRenameTable(const NumNodeRenameTable& table);
486 
487  static void printRenameEntry(const NodeNumRenameEntry& entry);
488 
489  static void printRenameEntry(const NumNodeRenameEntry& entry);
490 
491 
492 
493  /*
494  * Def/Use Table Access Functions
495  */
496 
502 
507  const DefUseTable& getDefTable() const { return originalDefTable; }
508 
514 
519  const DefUseTable& getPropDefTable() const { return defTable; }
520 
526 
531  const DefUseTable& getUseTable() const { return useTable; }
532 
533 
534 
535  /*
536  * Rename Table Access Functions
537  */
538 
549  int getRenameNumberForNode(const VarName& var, SgNode* node) const;
550 
561  SgNode* getNodeForRenameNumber(const VarName& var, int num) const;
562 
571  int getMaxRenameNumberForName(const VarName& var) const;
572 
573 
574 
575  /*
576  * Variable Renaming Access Functions
577  */
578 
589  NodeVec getAllUsesForDef(const VarName& var, int num);
590 
600  template<typename T> inline std::vector<T*> getAllUsesForDef(const VarName& var, int num)
601  {
602  NodeVec vec = getAllUsesForDef(var, num);
603  std::vector<T*> res;
604  T* temp = NULL;
605 
606  BOOST_FOREACH(NodeVec::value_type& val, vec)
607  {
608  temp = dynamic_cast<T*>(val);
609  if(temp != NULL)
610  {
611  //Push back if it casts correctly.
612  res.push_back(temp);
613  }
614  }
615 
616  return res;
617  }
618 
625 
633 
640 
647 
655 
665 
672 
680 
688 
696 
704 
715 
728 
739 
752 
763 
776 
784 
792 
793  /*
794  * Static Utility Functions
795  */
796 
807  static bool isPrefixOfName(VarName name, VarName prefix);
808 
814  static VarUniqueName* getUniqueName(SgNode* node);
815 
821  static VarName getVarName(SgNode* node);
822 
832  static bool isFromLibrary(SgFunctionDeclaration* node);
833 
840  static SgExpression* buildVariableReference(const VarName& var, SgScopeStatement* scope = NULL);
841 
842 private:
843 
847  {
848  private:
851  std::vector<SgNode*> refs;
852 
853  public:
857 
863  {
864  refs.push_back(thisNode);
865  }
866 
872  VarRefSynthAttr(const std::vector<SgNode*>& subtree, SgNode* thisNode)
873  {
874  refs.assign(subtree.begin(), subtree.end());
875  refs.push_back(thisNode);
876  }
877 
882  VarRefSynthAttr(const std::vector<SgNode*>& subtree)
883  {
884  refs.assign(subtree.begin(), subtree.end());
885  }
886 
891  const std::vector<SgNode*>& getRefs() { return refs; }
892 
897  void setRefs(const std::vector<SgNode*>& newRefs) { refs.assign(newRefs.begin(), newRefs.end()); }
898  };
899 
902  class UniqueNameTraversal : public AstBottomUpProcessing<VariableRenaming::VarRefSynthAttr>
903  {
905 
907  std::vector<SgInitializedName*> allInitNames;
908 
912 
913  public:
914  UniqueNameTraversal(VariableRenaming* varRenaming, const std::vector<SgInitializedName*>& allNames):
915  varRename(varRenaming), allInitNames(allNames)
916  {
917  }
918 
928  };
929 
931  class ChildUses
932  {
933  private:
936 
938  std::vector<SgNode*> uses;
939 
940  public:
941 
944  { }
945 
946  ChildUses(SgNode* useNode, SgVarRefExp* var)
947  {
948  uses.push_back(useNode);
949  currentVar = var;
950  }
951 
956  ChildUses(const std::vector<SgNode*>& useTree, SgVarRefExp* var = NULL)
957  {
958  if (useTree.size() > 0)
959  uses.assign(useTree.begin(), useTree.end());
960  currentVar = var;
961  }
962 
967  std::vector<SgNode*>& getUses()
968  {
969  return uses;
970  }
971 
976  void setUses(const std::vector<SgNode*>& newUses)
977  {
978  uses.assign(newUses.begin(), newUses.end());
979  }
980 
982  {
983  return currentVar;
984  }
985  };
986 
990  class DefsAndUsesTraversal : public AstBottomUpProcessing<ChildUses>
991  {
993 
994  public:
995 
997 
1007 
1008  private:
1009 
1011  void addUsesToNode(SgNode* node, std::vector<SgNode*> uses);
1012 
1014  void addDefForVarAtNode(SgVarRefExp* currentVar, SgNode* defNode);
1015  };
1016 
1017 };
1018 
1019 #endif /* SSAANALYSIS_H */
1020