ROSE  0.9.9.109
ssaUnfilteredCfg.h
1 //Author: George Vulov <georgevulov@hotmail.com>
2 #pragma once
3 
4 // DQ (10/5/2014): This is more strict now that we include rose_config.h in the sage3basic.h.
5 // #include "rose.h"
6 // rose.h and sage3basic.h should not be included in librose header files. [Robb P. Matzke 2014-10-15]
7 // #include "sage3basic.h"
8 
9 #include <string>
10 #include <iostream>
11 #include <map>
12 #include <set>
13 #include <vector>
14 #include <algorithm>
15 #include <ostream>
16 #include <fstream>
17 #include <sstream>
18 #include <boost/foreach.hpp>
19 #include "filteredCFG.h"
20 #include <boost/unordered_map.hpp>
21 #include "reachingDefUnfilteredCfg.h"
22 #include "CallGraph.h"
23 #include <uniqueNameTraversal.h>
24 
25 namespace ssa_unfiltered_cfg
26 {
27 
30  {
31 
32  bool operator()(SgFunctionDeclaration * funcDecl)
33  {
34  ROSE_ASSERT(funcDecl != NULL);
35 #if 0
36  //Exclude compiler generated functions, but keep template instantiations
37  if (funcDecl->get_file_info()->isCompilerGenerated() && !isSgTemplateInstantiationFunctionDecl(funcDecl)
38  && !isSgTemplateInstantiationMemberFunctionDecl(funcDecl))
39  return false;
40 
41  //We don't process functions that don't have definitions
42  if (funcDecl->get_definingDeclaration() == NULL)
43  return false;
44 
45  return true;
46 #else
47  // DQ (8/30/2016): Reorganize this to allow it to be more easily debugged.
48  bool returnValue = true;
49 
50  //Exclude compiler generated functions, but keep template instantiations
51  if (funcDecl->get_file_info()->isCompilerGenerated() && !isSgTemplateInstantiationFunctionDecl(funcDecl)
52  && !isSgTemplateInstantiationMemberFunctionDecl(funcDecl))
53  returnValue = false;
54 
55  //We don't process functions that don't have definitions
56  if (funcDecl->get_definingDeclaration() == NULL)
57  returnValue = false;
58 
59  printf ("In FunctionFilter::operator(): funcDecl = %p = %s name = %s returnValue = %s \n",funcDecl,funcDecl->class_name().c_str(),funcDecl->get_name().str(),returnValue ? "true" : "false");
60 
61  return returnValue;
62 #endif
63 
64  }
65  };
66 
82  {
83  private:
85  SgProject* project;
86 
87  public:
88 
90  typedef std::vector<SgInitializedName*> VarName;
91 
92  typedef boost::shared_ptr<ReachingDef> ReachingDefPtr;
93 
95  typedef std::map<VarName, ReachingDefPtr> NodeReachingDefTable;
96 
97  typedef std::map<CFGNode, std::set<VarName> > CFGNodeToVarNamesMap;
98 
99  typedef std::map<SgNode*, std::set<SgVarRefExp*> > ASTNodeToVarRefsMap;
100 
101  typedef std::map<CFGNode, NodeReachingDefTable> CFGNodeToDefTableMap;
102 
103  private:
104 
105  ASTNodeToVarRefsMap astNodeToUses;
106 
109  CFGNodeToDefTableMap localDefTable;
110 
113  CFGNodeToDefTableMap reachingDefTable;
114 
117  CFGNodeToDefTableMap outgoingDefTable;
118 
119  public:
120 
121  SSA_UnfilteredCfg(SgProject* proj) : project(proj) { }
122 
123  ~SSA_UnfilteredCfg() { }
124 
126  void run();
127 
128  static bool getDebug()
129  {
130  return SgProject::get_verbose() > 0;
131  }
132 
133  static bool getDebugExtra()
134  {
135  return SgProject::get_verbose() > 1;
136  }
137 
138  private:
141  void runDefUseDataFlow(SgFunctionDefinition* func);
142 
144  static bool isBuiltinVar(const VarName& var);
145 
159  void expandParentMemberDefinitions(const CFGNodeToVarNamesMap& defs);
160 
165  void insertDefsForChildMemberUses(const CFGNodeToVarNamesMap& defs, const std::set<VarName>& usedNames);
166 
168  void insertDefsForExternalVariables(SgFunctionDefinition* function, const std::set<VarName>& usedNames);
169 
174  void insertPhiFunctions(SgFunctionDefinition* function, const std::vector<CFGNode>& cfgNodesInPostOrder);
175 
180  void renumberAllDefinitions(SgFunctionDefinition* func, const std::vector<CFGNode>& cfgNodesInPostOrder);
181 
184  void updateIncomingPropagatedDefs(const CFGNode& cfgNode);
185 
188  bool propagateDefs(const CFGNode& cfgNode);
189 
192  static std::vector<CFGNode> getCfgNodesInPostorder(SgFunctionDefinition* func);
193 
194 
195  //------------ GRAPH OUTPUT FUNCTIONS ------------ //
196 
197  void printToDOT(SgNode* root, std::ostream &outFile);
198  void printToFilteredDOT(SgSourceFile* file, std::ofstream &outFile);
199 
200  public:
201  //External static helper functions/variables
202 
203  static VarName emptyName;
204 
205  /*
206  * Printing functions.
207  */
208 
213  void toDOT(const std::string fileName);
214 
222  void toFilteredDOT(const std::string fileName);
223 
224 
225  //------------ DEF/USE TABLE ACCESS FUNCTIONS ------------ //
226 
228  const NodeReachingDefTable& getReachingDefsBefore(const CFGNode& node) const;
229 
233  const NodeReachingDefTable& getReachingDefsAfter(const CFGNode& node) const;
234 
237  const NodeReachingDefTable& getDefsAtNode(const CFGNode& node) const;
238 
241  const NodeReachingDefTable& getReachingDefsBefore(SgNode* astNode) const;
242 
245  const NodeReachingDefTable& getReachingDefsAfter(SgNode* astNode) const;
246 
248  const NodeReachingDefTable& getLastVersions(SgFunctionDefinition* astNode) const;
249 
252  const std::set<SgVarRefExp*>& getUsesAtNode(SgNode* astNode) const;
253 
256  const ReachingDefPtr getDefinitionForUse(SgVarRefExp* astNode) const;
257 
260  const ASTNodeToVarRefsMap& getUseTable() const;
261 
262  //------------ STATIC UTILITY FUNCTIONS FUNCTIONS ------------ //
263 
274  static bool isPrefixOfName(VarName name, VarName prefix);
275 
282 
288  static const VarName& getVarName(SgNode* node);
289 
293  static const VarName& getVarForExpression(SgNode* node);
294 
301  static SgExpression* buildVariableReference(const VarName& var, SgScopeStatement* scope = NULL);
302 
308  static std::string varnameToString(const VarName& vec);
309 
310  static void printNodeDefTable(const NodeReachingDefTable& table);
311  static void printFullDefTable(const CFGNodeToDefTableMap& defTable);
312  };
313 
314 } //namespace ssa_unfiltered_cfg
This class represents the concept of a scope in C++ (e.g. global scope, fuction scope, etc.).
void toDOT(const std::string fileName)
Print the CFG with any UniqueNames and Def/Use information visible.
bool isCompilerGenerated() const
Returns true only if compiler generated (either by the front-end or by ROSE).
const NodeReachingDefTable & getLastVersions(SgFunctionDefinition *astNode) const
Get the final versions of all the variables at the end of the given function.
void toFilteredDOT(const std::string fileName)
Print the CFG with any UniqueNames and Def/Use information visible.
virtual Sg_File_Info * get_file_info() const ROSE_OVERRIDE
Interface function to implement original SAGE interface to SgFile_Info objects.
const NodeReachingDefTable & getDefsAtNode(const CFGNode &node) const
Returns the definitions that occur at the given node.
static ssa_private::VarUniqueName * getUniqueName(SgNode *node)
Get the uniqueName attribute for the given node.
static bool isPrefixOfName(VarName name, VarName prefix)
Find if the given prefix is a prefix of the given name.
void run()
Run the analysis.
This class represents the concept of a function declaration statement.
This class represents the concept of a scope in C++ (e.g. global scope, fuction scope, etc.).
This filter determines which function declarations get processed in the analysis. ...
std::map< VarName, ReachingDefPtr > NodeReachingDefTable
A map from each variable to its reaching definitions at the current node.
const ASTNodeToVarRefsMap & getUseTable() const
Returns the entire use table, mapping each non-statement AST node to the variables used in its execut...
This class represents the notion of an expression. Expressions are derived from SgLocatedNodes, since similar to statement, expressions have a concrete location within the user's source code.
static const VarName & getVarForExpression(SgNode *node)
If an expression evaluates to a reference of a variable, returns that variable.
std::vector< SgInitializedName * > VarName
A compound variable name as used by the variable renaming.
static SgExpression * buildVariableReference(const VarName &var, SgScopeStatement *scope=NULL)
Get an AST fragment containing the appropriate varRefs and Dot/Arrow ops to access the given variable...
const NodeReachingDefTable & getReachingDefsAfter(const CFGNode &node) const
Returns the reaching definitions after the given node was executed.
This class represents the base class for all IR nodes within Sage III.
Definition: Cxx_Grammar.h:8322
static const VarName & getVarName(SgNode *node)
Get the variable name of the given node.
static std::string varnameToString(const VarName &vec)
Get a string representation of a varName.
SgDeclarationStatement * get_definingDeclaration() const
This is an access function for the SgDeclarationStatement::p_definingDeclaration data member (see tha...
const ReachingDefPtr getDefinitionForUse(SgVarRefExp *astNode) const
Given a use obtained through getUsesAtNode, resolve its corresponding def.
const NodeReachingDefTable & getReachingDefsBefore(const CFGNode &node) const
Returns the reaching definitions before the given node was executed.
This class represents the variable refernece in expressions.
virtual std::string class_name() const ROSE_OVERRIDE
returns a string representing the class name
static int get_verbose(void)
DQ: Modified to accept a value on the command line (no longer a boolean variable) value of 0 means qu...
const std::set< SgVarRefExp * > & getUsesAtNode(SgNode *astNode) const
Returns all the SgVarRef objects that are used in the execution of the given AST node.
This class represents a source project, with a list of SgFile objects and global information about th...
Class holding a unique name for a variable.