ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
InterproceduralInfo.h
Go to the documentation of this file.
1 #ifndef __INTERPROCEDURAL_INFO_H__ // added by HK
2 #define __INTERPROCEDURAL_INFO_H__ // added by HK
3 
4 #include <AstInterface.h>
5 #include <StmtInfoCollect.h>
6 #include <ReachingDefinition.h>
7 #include <DefUseChain.h>
8 #include "CallGraph.h"
9 #include <ostream>
10 #include <string>
11 #include <map>
12 #include <utility>
13 #include <set>
14 #include "DominanceFrontier.h"
15 #include "SimpleDirectedGraph.h"
16 
17 // #include "rose.h"
18 // #include "../newImDomImpl/filteredCFG.h"
19 #include <virtualCFG.h>
20 #include "filteredCFG.h"
21 #include "DominatorTree.h"
22 #include "DominanceFrontier.h"
23 
24 // #define VERBOSE_DEBUG
25 
26 
27 /* ! \class InterproceduralInfo
28 
29  This class holds information necessary to perform interprocedural slicing.
30  As specified in the paper by Horowitz et al, every function in a program
31  requires: - An "entry" node - A "formal-in" node for each parameter - A
32  "formal-out" node for each return parameter
33 
34  Similarly, every function call in a procedure requires: - A "call-site"
35  node - An "actual-in" node for every argument to the function - An
36  "actual-out" node for every return variable
37 
38  There should be one InterproceduralInfo object associated with each
39  procedure in a program. It is initialized by passing in a newly created
40  object to the constructor of a ControlDependenceGraph. It must then be
41  passed to the constructor of a DataDependenceGraph. At this point, it
42  contains all the appropriate intraprocedural edges and nodes as specified
43  above.
44 
45  */
46 
48 {
49  public:
51  {
52  if (dec->get_definition()!=NULL)
53  {
54  return dec->get_definition();
55  }
56  else
57  {
58  return dec;
59  }
60  }
62  {
63  return def;
64  }
65  public:
66  // ! the nodes required to fully represent a call site in the PDG
68  {
74  // ! the callsite - one per SgFunctionCallExp
75  // ! the actual-in nodes - one per argument
76  std::vector<SgExpression*> actual_in;
77 // std::vector<SgExpression*
78  // ! the actual-out nodes - one per argument
79  // ! a list which records the order of the function arguments
80  // std::list < SgExpression * >expr_order;
81  // ! an actual-out node representing the return value of the function
82  // call
84  };
85  void setCallInterestingNode(int id,SgNode * node)
86  {
87  callSites[id].sgCallInterestingNode=node;
88  }
90  {
91  return callSites[id].sgCallInterestingNode;
92  }
94  {
95  return callSites[id].actual_return;
96  }
97  SgNode * getActualIn(int id,int varNr)
98  {
99  return callSites[id].actual_in[varNr];
100  }
101  int getActualInCount(int id)
102  {
103  return callSites[id].actual_in.size();
104  }
105  void addActualIn(int id,SgExpression * node)
106  {
107  callSites[id].actual_in.push_back(node);
108  }
109  void setSliceImportantNode(int id,SgNode * node)
110  {
111  callSites[id].sliceImportantNode=node;
112  }
113  void setActualReturn(int id,SgNode * node)
114  {
115  callSites[id].actual_return=node;
116  }
117 
120  {
121  return callSites[i].sliceImportantNode;
122  }
123  std::set<SgNode *> getExitNodes()
124  {
125  return exitNodes;
126  }
127  void addParameterToFunctionCall(SgNode * functionCall,SgExpression * param)
128  {
129  }
130 
132  {
133  return callSites.size();
134  }
136  {
137  return callSites[i].sgFunctionCallExpNode;
138  }
140  {
141  return entry;
142  }
144  {
146  }
148  {
149  return ellipseNode;
150  }
151  protected:
152 
156 
157  // ! the nodes required to fully represent a procedure entry in the PDG
158  // ! an entry node - one per function declaration
159  // ! the formal-in nodes - one per function parameter
160  // ! the formal-out nodes - one per function parameter
161  // ! a list which records the order of the parameters
162  std::list < SgInitializedName * >arg_order;
163  // ! a formal out node representing the return value of the function
165  std::vector<SgNode*> formal;
167  // list containing the nodes from the function that exit...
168  std::set<SgNode *> exitNodes;
169 
170  // ! The entry node for a procedure
171  // ProcedureEntryStructure procedureEntry;
172  std::vector<CallSiteStructure> callSites;
173 
174  std::map<SgNode *, int> callSitesMap;
175 
176 
177  public:
178  bool isUndefined()
179  {
180  if (def==NULL) return true;
181  else return false;
182  }
184  {
185  return formal.size();
186  }
187  SgNode * getFormal(int nr)
188  {
189  if (formal.size()>(unsigned int)nr && nr>=0)
190  return formal[nr];
191  ROSE_ASSERT(false);
192 
193  // DQ (12/1/2009): avoid MSVC warning of non-void function without return stmt.
194  return NULL;
195  }
196 
197  void setFormalReturn(SgNode * node)
198  {
199  formal_return=node;
200  }
202  {
203  return formal_return;
204  }
205  // add this DependenceNode to the list of nodes which lead to exiting this function
206  void addExitNode(SgNode * node)
207  {
208  exitNodes.insert(node);
209  }/*
210  void createSafeConfiguration()
211  {
212  DependenceNode * formalIn,*formalOut,*entry,*formalReturn;
213  entry=getNode(DependenceNode::ENTRY,getFunctionEntry());
214  formalReturn=getNode(DependenceNode::FORMALOUT,getFormalReturn());
215 
216  // this is done for "unknown" functions
217  for (int i=0;i<getFormalCount();i++)
218  {
219  formalIn=getNode(DependenceNode::FORMALIN,getFormal(i));
220  formalOut=getNode(DependenceNode::FORMALOUT,getFormal(i));
221  // create connection formalin->return
222  establishEdge(formalIn,entry,DATA);
223  establishEdge(formalIn,fornalOut,DATA);
224  establishEdge(formalIn,formalReturn,DATA);
225  }
226  }
227  */
229  {
230 #ifdef VERBOSE_DEBUG
231  std::cout << "creating interprocedural info for " << functionDeclaration->get_name().getString() << "\n";
232 #endif
233  decl=functionDeclaration;
234  def=functionDeclaration->get_definition();
235  if (def==NULL) entry=decl;
236  else entry=def;
237  // create formal stuff
238  formal_return=functionDeclaration;/*->get_type()->get_return_type();*/
239  ellipseNode=NULL;
240  Rose_STL_Container<SgInitializedName*> argList=functionDeclaration->get_args();
241  for (Rose_STL_Container<SgInitializedName*>::iterator i=argList.begin();i!=argList.end();i++)
242  {
243  if (isSgTypeEllipse((*i)->get_type()))
244  {
245  ellipseNode=*i;
246  }
247  else
248  {
249 #ifdef VERBOSE_DEBUG
250  std::cout << "\tadding formal in "<<*i<<"\n";
251 #endif
252  formal.push_back(*i);
253  }
254  }
255 
256  }
257 
258  /* ! \brief Gets the function declaration that the InterproceduralInfo object is for.
259  Returns: The SgFunctionDeclaration node that is associated with this object */
262  { return def;}
264  {
265  return decl;
266  }
267 
268  // adds an function call to the tracking list, this will alter on be used to analyse the calls site in the ...
269  // void addFunctionCall(SgNode * sliceImportantNode,SgNode * functionCall,SgNode * actualReturnIdentifier=NULL)
270  int addFunctionCall(SgNode * functionCall)
271  {
273  cs.sliceImportantNode=NULL;//sliceImportantNode;
274  cs.sgFunctionCallExpNode=functionCall;
275 // cs.callSiteDepNode=NULL;
276  cs.actual_return=NULL;
277  callSites.push_back(cs);
278  callSitesMap[functionCall]=callSites.size()-1;
279  return callSites.size()-1;
280  }
281 
285 /* static std::list < SgFunctionCallExp * >extractFunctionCalls(SgNode * node)
286  {
287  std::list < SgFunctionCallExp * >retval;
288  std::list < SgNode * >calls = NodeQuery::querySubTree(node, V_SgFunctionCallExp);
289  for (std::list < SgNode * >::iterator i = calls.begin(); i != calls.end(); i++)
290  {
291  SgFunctionCallExp *fce = isSgFunctionCallExp(*i);
292  ROSE_ASSERT(fce != NULL);
293  retval.push_back(fce);
294  }
295 
296  return retval;
297  }*/
298  // ! maps function calls to the call site structure that represents them
299 // std::map < SgFunctionCallExp *, CallSiteStructure > callsite_map;
300 };
301 
302 #endif // #ifndef __INTERPROCEDURAL_INFO_H__ // added by HK