1169689Skan/* Interprocedural analyses.
2169689Skan   Copyright (C) 2005 Free Software Foundation, Inc.
3169689Skan
4169689SkanThis file is part of GCC.
5169689Skan
6169689SkanGCC is free software; you can redistribute it and/or modify it under
7169689Skanthe terms of the GNU General Public License as published by the Free
8169689SkanSoftware Foundation; either version 2, or (at your option) any later
9169689Skanversion.
10169689Skan
11169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
12169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
13169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14169689Skanfor more details.
15169689Skan
16169689SkanYou should have received a copy of the GNU General Public License
17169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19169689Skan02110-1301, USA.  */
20169689Skan
21169689Skan#include "config.h"
22169689Skan#include "system.h"
23169689Skan#include "coretypes.h"
24169689Skan#include "tree.h"
25169689Skan#include "langhooks.h"
26169689Skan#include "ggc.h"
27169689Skan#include "target.h"
28169689Skan#include "cgraph.h"
29169689Skan#include "ipa-prop.h"
30169689Skan#include "tree-flow.h"
31169689Skan#include "tree-pass.h"
32169689Skan#include "flags.h"
33169689Skan#include "timevar.h"
34169689Skan
35169689Skan/* This file contains interfaces that can be used for various IPA
36169689Skan   optimizations:
37169689Skan
38169689Skan   - ipa_methodlist interface - It is used to create and handle a temporary
39169689Skan   worklist used in  the propagation stage of IPCP. (can be used for more
40169689Skan   IPA optimizations).
41169689Skan
42169689Skan   - ipa_callsite interface - for each callsite this interface creates and
43169689Skan   handles ipa_edge structure associated with it.
44169689Skan
45169689Skan   - ipa_method interface - for each method this interface creates and
46169689Skan   handles ipa_node structure associated with it.  */
47169689Skan
48169689Skan/* ipa_methodlist interface.  */
49169689Skan
50169689Skan/* Create a new worklist node.  */
51169689Skanstatic inline ipa_methodlist_p
52169689Skanipa_create_methodlist_node (void)
53169689Skan{
54169689Skan  return (ipa_methodlist_p) xcalloc (1, sizeof (struct ipa_methodlist));
55169689Skan}
56169689Skan
57169689Skan/* Return true if worklist WL is empty.  */
58169689Skanbool
59169689Skanipa_methodlist_not_empty (ipa_methodlist_p wl)
60169689Skan{
61169689Skan  return (wl != NULL);
62169689Skan}
63169689Skan
64169689Skan/* Return the method in worklist element WL.  */
65169689Skanstatic inline struct cgraph_node *
66169689Skanipa_methodlist_method (ipa_methodlist_p wl)
67169689Skan{
68169689Skan  return wl->method_p;
69169689Skan}
70169689Skan
71169689Skan/* Make worklist element WL point to method MT in the callgraph.  */
72169689Skanstatic inline void
73169689Skanipa_methodlist_method_set (ipa_methodlist_p wl, struct cgraph_node *mt)
74169689Skan{
75169689Skan  wl->method_p = mt;
76169689Skan}
77169689Skan
78169689Skan/* Return the next element in the worklist following worklist
79169689Skan   element WL.  */
80169689Skanstatic inline ipa_methodlist_p
81169689Skanipa_methodlist_next_method (ipa_methodlist_p wl)
82169689Skan{
83169689Skan  return wl->next_method;
84169689Skan}
85169689Skan
86169689Skan/* Set worklist element WL1 to point to worklist element WL2.  */
87169689Skanstatic inline void
88169689Skanipa_methodlist_next_method_set (ipa_methodlist_p wl1, ipa_methodlist_p wl2)
89169689Skan{
90169689Skan  wl1->next_method = wl2;
91169689Skan}
92169689Skan
93169689Skan/* Initialize worklist to contain all methods.  */
94169689Skanipa_methodlist_p
95169689Skanipa_methodlist_init (void)
96169689Skan{
97169689Skan  struct cgraph_node *node;
98169689Skan  ipa_methodlist_p wl;
99169689Skan
100169689Skan  wl = NULL;
101169689Skan  for (node = cgraph_nodes; node; node = node->next)
102169689Skan    ipa_add_method (&wl, node);
103169689Skan
104169689Skan  return wl;
105169689Skan}
106169689Skan
107169689Skan/* Add method MT to the worklist. Set worklist element WL
108169689Skan   to point to MT.  */
109169689Skanvoid
110169689Skanipa_add_method (ipa_methodlist_p * wl, struct cgraph_node *mt)
111169689Skan{
112169689Skan  ipa_methodlist_p temp;
113169689Skan
114169689Skan  temp = ipa_create_methodlist_node ();
115169689Skan  ipa_methodlist_method_set (temp, mt);
116169689Skan  ipa_methodlist_next_method_set (temp, *wl);
117169689Skan  *wl = temp;
118169689Skan}
119169689Skan
120169689Skan/* Remove a method from the worklist. WL points to the first
121169689Skan   element in the list, which is removed.  */
122169689Skanstruct cgraph_node *
123169689Skanipa_remove_method (ipa_methodlist_p * wl)
124169689Skan{
125169689Skan  ipa_methodlist_p first;
126169689Skan  struct cgraph_node *return_method;
127169689Skan
128169689Skan  first = *wl;
129169689Skan  *wl = ipa_methodlist_next_method (*wl);
130169689Skan  return_method = ipa_methodlist_method (first);
131169689Skan  free (first);
132169689Skan  return return_method;
133169689Skan}
134169689Skan
135169689Skan/* ipa_method interface.  */
136169689Skan
137169689Skan/* Return number of formals of method MT.  */
138169689Skanint
139169689Skanipa_method_formal_count (struct cgraph_node *mt)
140169689Skan{
141169689Skan  return IPA_NODE_REF (mt)->ipa_arg_num;
142169689Skan}
143169689Skan
144169689Skan/* Set number of formals of method MT to I.  */
145169689Skanvoid
146169689Skanipa_method_formal_count_set (struct cgraph_node *mt, int i)
147169689Skan{
148169689Skan  IPA_NODE_REF (mt)->ipa_arg_num = i;
149169689Skan}
150169689Skan
151169689Skan/* Return whether I-th formal of MT is modified in MT.  */
152169689Skanstatic inline bool
153169689Skanipa_method_is_modified (struct cgraph_node *mt, int i)
154169689Skan{
155169689Skan  return IPA_NODE_REF (mt)->ipa_mod[i];
156169689Skan}
157169689Skan
158169689Skan/* Return the tree of I-th formal of MT.  */
159169689Skantree
160169689Skanipa_method_get_tree (struct cgraph_node *mt, int i)
161169689Skan{
162169689Skan  return IPA_NODE_REF (mt)->ipa_param_tree[i];
163169689Skan}
164169689Skan
165169689Skan/* Create tree map structure for MT.  */
166169689Skanstatic inline void
167169689Skanipa_method_tree_map_create (struct cgraph_node *mt)
168169689Skan{
169169689Skan  IPA_NODE_REF (mt)->ipa_param_tree =
170169689Skan    XCNEWVEC (tree, ipa_method_formal_count (mt));
171169689Skan}
172169689Skan
173169689Skan/* Create modify structure for MT.  */
174169689Skanstatic inline void
175169689Skanipa_method_modify_create (struct cgraph_node *mt)
176169689Skan{
177169689Skan  ((struct ipa_node *) mt->aux)->ipa_mod =
178169689Skan    XCNEWVEC (bool, ipa_method_formal_count (mt));
179169689Skan}
180169689Skan
181169689Skan/* Set modify of I-th formal of MT to VAL.  */
182169689Skanstatic inline void
183169689Skanipa_method_modify_set (struct cgraph_node *mt, int i, bool val)
184169689Skan{
185169689Skan  IPA_NODE_REF (mt)->ipa_mod[i] = val;
186169689Skan}
187169689Skan
188169689Skan/* Return index of the formal whose tree is PTREE in method MT.  */
189169689Skanstatic int
190169689Skanipa_method_tree_map (struct cgraph_node *mt, tree ptree)
191169689Skan{
192169689Skan  int i, count;
193169689Skan
194169689Skan  count = ipa_method_formal_count (mt);
195169689Skan  for (i = 0; i < count; i++)
196169689Skan    if (IPA_NODE_REF (mt)->ipa_param_tree[i] == ptree)
197169689Skan      return i;
198169689Skan
199169689Skan  return -1;
200169689Skan}
201169689Skan
202169689Skan/* Insert the formal trees to the ipa_param_tree array in method MT.  */
203169689Skanvoid
204169689Skanipa_method_compute_tree_map (struct cgraph_node *mt)
205169689Skan{
206169689Skan  tree fndecl;
207169689Skan  tree fnargs;
208169689Skan  tree parm;
209169689Skan  int param_num;
210169689Skan
211169689Skan  ipa_method_tree_map_create (mt);
212169689Skan  fndecl = mt->decl;
213169689Skan  fnargs = DECL_ARGUMENTS (fndecl);
214169689Skan  param_num = 0;
215169689Skan  for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
216169689Skan    {
217169689Skan      IPA_NODE_REF (mt)->ipa_param_tree[param_num] = parm;
218169689Skan      param_num++;
219169689Skan    }
220169689Skan}
221169689Skan
222169689Skan/* Count number of formals in MT. Insert the result to the
223169689Skan   ipa_node.  */
224169689Skanvoid
225169689Skanipa_method_formal_compute_count (struct cgraph_node *mt)
226169689Skan{
227169689Skan  tree fndecl;
228169689Skan  tree fnargs;
229169689Skan  tree parm;
230169689Skan  int param_num;
231169689Skan
232169689Skan  fndecl = mt->decl;
233169689Skan  fnargs = DECL_ARGUMENTS (fndecl);
234169689Skan  param_num = 0;
235169689Skan  for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
236169689Skan    param_num++;
237169689Skan  ipa_method_formal_count_set (mt, param_num);
238169689Skan}
239169689Skan
240169689Skan/* Check STMT to detect whether a formal is modified within MT,
241169689Skan   the appropriate entry is updated in the ipa_mod array of ipa_node
242169689Skan   (associated with MT).  */
243169689Skanstatic void
244169689Skanipa_method_modify_stmt (struct cgraph_node *mt, tree stmt)
245169689Skan{
246169689Skan  int i, j;
247169689Skan
248169689Skan  switch (TREE_CODE (stmt))
249169689Skan    {
250169689Skan    case MODIFY_EXPR:
251169689Skan      if (TREE_CODE (TREE_OPERAND (stmt, 0)) == PARM_DECL)
252169689Skan	{
253169689Skan	  i = ipa_method_tree_map (mt, TREE_OPERAND (stmt, 0));
254169689Skan	  if (i >= 0)
255169689Skan            ipa_method_modify_set (mt, i, true);
256169689Skan	}
257169689Skan      break;
258169689Skan    case ASM_EXPR:
259169689Skan      /* Asm code could modify any of the parameters.  */
260169689Skan      for (j = 0; j < ipa_method_formal_count (mt); j++)
261169689Skan	ipa_method_modify_set (mt, j, true);
262169689Skan      break;
263169689Skan    default:
264169689Skan      break;
265169689Skan    }
266169689Skan}
267169689Skan
268169689Skan/* Initialize ipa_mod array of MT.  */
269169689Skanstatic void
270169689Skanipa_method_modify_init (struct cgraph_node *mt)
271169689Skan{
272169689Skan  int i, count;
273169689Skan
274169689Skan  ipa_method_modify_create (mt);
275169689Skan  count = ipa_method_formal_count (mt);
276169689Skan  for (i = 0; i < count; i++)
277169689Skan    ipa_method_modify_set (mt, i, false);
278169689Skan}
279169689Skan
280169689Skan/* The modify computation driver for MT. Compute which formal arguments
281169689Skan   of method MT are locally modified.  Formals may be modified in MT
282169689Skan   if their address is taken, or if
283169689Skan   they appear on the left hand side of an assignment.  */
284169689Skanvoid
285169689Skanipa_method_compute_modify (struct cgraph_node *mt)
286169689Skan{
287169689Skan  tree decl;
288169689Skan  tree body;
289169689Skan  int j, count;
290169689Skan  basic_block bb;
291169689Skan  struct function *func;
292169689Skan  block_stmt_iterator bsi;
293169689Skan  tree stmt, parm_tree;
294169689Skan
295169689Skan  ipa_method_modify_init (mt);
296169689Skan  decl = mt->decl;
297169689Skan  count = ipa_method_formal_count (mt);
298169689Skan  /* ??? Handle pending sizes case. Set all parameters
299169689Skan     of the method to be modified.  */
300169689Skan  if (DECL_UNINLINABLE (decl))
301169689Skan    {
302169689Skan      for (j = 0; j < count; j++)
303169689Skan	ipa_method_modify_set (mt, j, true);
304169689Skan      return;
305169689Skan    }
306169689Skan  /* Formals whose address is taken are considered modified.  */
307169689Skan  for (j = 0; j < count; j++)
308169689Skan    {
309169689Skan      parm_tree = ipa_method_get_tree (mt, j);
310169689Skan      if (TREE_ADDRESSABLE (parm_tree))
311169689Skan	ipa_method_modify_set (mt, j, true);
312169689Skan    }
313169689Skan  body = DECL_SAVED_TREE (decl);
314169689Skan  if (body != NULL)
315169689Skan    {
316169689Skan      func = DECL_STRUCT_FUNCTION (decl);
317169689Skan      FOR_EACH_BB_FN (bb, func)
318169689Skan      {
319169689Skan	for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
320169689Skan	  {
321169689Skan	    stmt = bsi_stmt (bsi);
322169689Skan	    ipa_method_modify_stmt (mt, stmt);
323169689Skan	  }
324169689Skan      }
325169689Skan    }
326169689Skan}
327169689Skan
328169689Skan
329169689Skan/* ipa_callsite interface.  */
330169689Skan
331169689Skan/* Return number of arguments in callsite CS.  */
332169689Skanint
333169689Skanipa_callsite_param_count (struct cgraph_edge *cs)
334169689Skan{
335169689Skan  return IPA_EDGE_REF (cs)->ipa_param_num;
336169689Skan}
337169689Skan
338169689Skan/* Set number of arguments in callsite CS to I.  */
339169689Skanvoid
340169689Skanipa_callsite_param_count_set (struct cgraph_edge *cs, int i)
341169689Skan{
342169689Skan  IPA_EDGE_REF (cs)->ipa_param_num = i;
343169689Skan}
344169689Skan
345169689Skan/* Return the jump function (ipa_jump_func struct) for argument I of
346169689Skan   callsite CS.  */
347169689Skanstruct ipa_jump_func *
348169689Skanipa_callsite_param (struct cgraph_edge *cs, int i)
349169689Skan{
350169689Skan  return &(IPA_EDGE_REF (cs)->ipa_param_map[i]);
351169689Skan}
352169689Skan
353169689Skan/* return the callee (cgraph_node) of callsite CS.  */
354169689Skanstruct cgraph_node *
355169689Skanipa_callsite_callee (struct cgraph_edge *cs)
356169689Skan{
357169689Skan  return cs->callee;
358169689Skan}
359169689Skan
360169689Skan/* Set field 'type' of jump function (ipa_jump_func struct) of argument I
361169689Skan   in callsite CS.  */
362169689Skanstatic inline void
363169689Skanipa_callsite_param_set_type (struct cgraph_edge *cs, int i,
364169689Skan			     enum jump_func_type type1)
365169689Skan{
366169689Skan  IPA_EDGE_REF (cs)->ipa_param_map[i].type = type1;
367169689Skan}
368169689Skan
369169689Skan/* Set FORMAL as 'info_type' field of jump function (ipa_jump_func struct)
370169689Skan   of argument I of callsite CS.  */
371169689Skanstatic inline void
372169689Skanipa_callsite_param_set_info_type_formal (struct cgraph_edge *cs, int i,
373169689Skan					 unsigned int formal)
374169689Skan{
375169689Skan  ipa_callsite_param (cs, i)->info_type.formal_id = formal;
376169689Skan}
377169689Skan
378169689Skan/* Set int-valued INFO_TYPE1 as 'info_type' field of
379169689Skan   jump function (ipa_jump_func struct) of argument I of callsite CS.  */
380169689Skanstatic inline void
381169689Skanipa_callsite_param_set_info_type (struct cgraph_edge *cs, int i, tree info_type1)
382169689Skan{
383169689Skan  ipa_callsite_param (cs, i)->info_type.value = info_type1;
384169689Skan}
385169689Skan
386169689Skan/* Allocate space for callsite CS.  */
387169689Skanstatic inline void
388169689Skanipa_callsite_param_map_create (struct cgraph_edge *cs)
389169689Skan{
390169689Skan  IPA_EDGE_REF (cs)->ipa_param_map =
391169689Skan    XCNEWVEC (struct ipa_jump_func, ipa_callsite_param_count (cs));
392169689Skan}
393169689Skan
394169689Skan/* Return the call expr tree related to callsite CS.  */
395169689Skanstatic inline tree
396169689Skanipa_callsite_tree (struct cgraph_edge *cs)
397169689Skan{
398169689Skan  return cs->call_stmt;
399169689Skan}
400169689Skan
401169689Skan/* Return the caller (cgraph_node) of CS.  */
402169689Skanstatic inline struct cgraph_node *
403169689Skanipa_callsite_caller (struct cgraph_edge *cs)
404169689Skan{
405169689Skan  return cs->caller;
406169689Skan}
407169689Skan
408169689Skan/* Count number of arguments callsite CS has and store it in
409169689Skan   ipa_edge structure corresponding to this callsite.  */
410169689Skanvoid
411169689Skanipa_callsite_compute_count (struct cgraph_edge *cs)
412169689Skan{
413169689Skan  tree call_tree;
414169689Skan  tree arg;
415169689Skan  int arg_num;
416169689Skan
417169689Skan  call_tree = get_call_expr_in (ipa_callsite_tree (cs));
418169689Skan  gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
419169689Skan  arg = TREE_OPERAND (call_tree, 1);
420169689Skan  arg_num = 0;
421169689Skan  for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
422169689Skan    arg_num++;
423169689Skan  ipa_callsite_param_count_set (cs, arg_num);
424169689Skan}
425169689Skan
426169689Skan/* Compute jump function for all arguments of callsite CS
427169689Skan   and insert the information in the ipa_param_map array
428169689Skan   in the ipa_edge corresponding to this callsite. (Explanation
429169689Skan   on jump functions is in ipa-prop.h).  */
430169689Skanvoid
431169689Skanipa_callsite_compute_param (struct cgraph_edge *cs)
432169689Skan{
433169689Skan  tree call_tree;
434169689Skan  tree arg, cst_decl;
435169689Skan  int arg_num;
436169689Skan  int i;
437169689Skan  struct cgraph_node *mt;
438169689Skan
439169689Skan  if (ipa_callsite_param_count (cs) == 0)
440169689Skan    return;
441169689Skan  ipa_callsite_param_map_create (cs);
442169689Skan  call_tree = get_call_expr_in (ipa_callsite_tree (cs));
443169689Skan  gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
444169689Skan  arg = TREE_OPERAND (call_tree, 1);
445169689Skan  arg_num = 0;
446169689Skan
447169689Skan  for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
448169689Skan    {
449169689Skan      /* If the formal parameter was passed as argument, we store
450169689Skan         FORMAL_IPATYPE and its index in the caller as the jump function
451169689Skan         of this argument.  */
452169689Skan      if (TREE_CODE (TREE_VALUE (arg)) == PARM_DECL)
453169689Skan	{
454169689Skan	  mt = ipa_callsite_caller (cs);
455169689Skan	  i = ipa_method_tree_map (mt, TREE_VALUE (arg));
456169689Skan	  if (i < 0 || ipa_method_is_modified (mt, i))
457169689Skan	    ipa_callsite_param_set_type (cs, arg_num, UNKNOWN_IPATYPE);
458169689Skan	  else
459169689Skan	    {
460169689Skan	      ipa_callsite_param_set_type (cs, arg_num, FORMAL_IPATYPE);
461169689Skan	      ipa_callsite_param_set_info_type_formal (cs, arg_num, i);
462169689Skan	    }
463169689Skan	}
464169689Skan      /* If a constant value was passed as argument,
465169689Skan         we store CONST_IPATYPE and its value as the jump function
466169689Skan         of this argument.  */
467169689Skan      else if (TREE_CODE (TREE_VALUE (arg)) == INTEGER_CST
468169689Skan	       || TREE_CODE (TREE_VALUE (arg)) == REAL_CST)
469169689Skan	{
470169689Skan	  ipa_callsite_param_set_type (cs, arg_num, CONST_IPATYPE);
471169689Skan	  ipa_callsite_param_set_info_type (cs, arg_num,
472169689Skan					    TREE_VALUE (arg));
473169689Skan	}
474169689Skan      /* This is for the case of Fortran. If the address of a const_decl
475169689Skan         was passed as argument then we store
476169689Skan         CONST_IPATYPE_REF/CONST_IPATYPE_REF and the constant
477169689Skan         value as the jump function corresponding to this argument.  */
478169689Skan      else if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR
479169689Skan	       && TREE_CODE (TREE_OPERAND (TREE_VALUE (arg), 0)) ==
480169689Skan	       CONST_DECL)
481169689Skan	{
482169689Skan	  cst_decl = TREE_OPERAND (TREE_VALUE (arg), 0);
483169689Skan	  if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
484169689Skan	      || TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST)
485169689Skan	    {
486169689Skan	      ipa_callsite_param_set_type (cs, arg_num,
487169689Skan					   CONST_IPATYPE_REF);
488169689Skan	      ipa_callsite_param_set_info_type (cs, arg_num,
489169689Skan						DECL_INITIAL (cst_decl));
490169689Skan	    }
491169689Skan	}
492169689Skan      else
493169689Skan	ipa_callsite_param_set_type (cs, arg_num, UNKNOWN_IPATYPE);
494169689Skan      arg_num++;
495169689Skan    }
496169689Skan}
497169689Skan
498169689Skan/* Return type of jump function JF.  */
499169689Skanenum jump_func_type
500169689Skanget_type (struct ipa_jump_func *jf)
501169689Skan{
502169689Skan  return jf->type;
503169689Skan}
504169689Skan
505169689Skan/* Return info type of jump function JF.  */
506169689Skanunion parameter_info *
507169689Skanipa_jf_get_info_type (struct ipa_jump_func *jf)
508169689Skan{
509169689Skan  return &(jf->info_type);
510169689Skan}
511169689Skan
512169689Skan/* Allocate and initialize ipa_node structure.
513169689Skan   cgraph_node NODE points to the new allocated ipa_node.  */
514169689Skanvoid
515169689Skanipa_node_create (struct cgraph_node *node)
516169689Skan{
517169689Skan  node->aux = xcalloc (1, sizeof (struct ipa_node));
518169689Skan}
519169689Skan
520169689Skan/* Allocate and initialize ipa_node structure for all
521169689Skan   nodes in callgraph.  */
522169689Skanvoid
523169689Skanipa_nodes_create (void)
524169689Skan{
525169689Skan  struct cgraph_node *node;
526169689Skan
527169689Skan  for (node = cgraph_nodes; node; node = node->next)
528169689Skan    ipa_node_create (node);
529169689Skan}
530169689Skan
531169689Skan/* Allocate and initialize ipa_edge structure.  */
532169689Skanvoid
533169689Skanipa_edges_create (void)
534169689Skan{
535169689Skan  struct cgraph_node *node;
536169689Skan  struct cgraph_edge *cs;
537169689Skan
538169689Skan  for (node = cgraph_nodes; node; node = node->next)
539169689Skan    for (cs = node->callees; cs; cs = cs->next_callee)
540169689Skan      cs->aux = xcalloc (1, sizeof (struct ipa_edge));
541169689Skan}
542169689Skan
543169689Skan/* Free ipa_node structure.  */
544169689Skanvoid
545169689Skanipa_nodes_free (void)
546169689Skan{
547169689Skan  struct cgraph_node *node;
548169689Skan
549169689Skan  for (node = cgraph_nodes; node; node = node->next)
550169689Skan    {
551169689Skan      free (node->aux);
552169689Skan      node->aux = NULL;
553169689Skan    }
554169689Skan}
555169689Skan
556169689Skan/* Free ipa_edge structure.  */
557169689Skanvoid
558169689Skanipa_edges_free (void)
559169689Skan{
560169689Skan  struct cgraph_node *node;
561169689Skan  struct cgraph_edge *cs;
562169689Skan
563169689Skan  for (node = cgraph_nodes; node; node = node->next)
564169689Skan    for (cs = node->callees; cs; cs = cs->next_callee)
565169689Skan      {
566169689Skan	free (cs->aux);
567169689Skan	cs->aux = NULL;
568169689Skan      }
569169689Skan}
570169689Skan
571169689Skan/* Free ipa data structures of ipa_node and ipa_edge.  */
572169689Skanvoid
573169689Skanipa_free (void)
574169689Skan{
575169689Skan  struct cgraph_node *node;
576169689Skan  struct cgraph_edge *cs;
577169689Skan
578169689Skan  for (node = cgraph_nodes; node; node = node->next)
579169689Skan    {
580169689Skan      if (node->aux == NULL)
581169689Skan	continue;
582169689Skan      if (IPA_NODE_REF (node)->ipcp_cval)
583169689Skan	free (IPA_NODE_REF (node)->ipcp_cval);
584169689Skan      if (IPA_NODE_REF (node)->ipa_param_tree)
585169689Skan	free (IPA_NODE_REF (node)->ipa_param_tree);
586169689Skan      if (IPA_NODE_REF (node)->ipa_mod)
587169689Skan	free (IPA_NODE_REF (node)->ipa_mod);
588169689Skan      for (cs = node->callees; cs; cs = cs->next_callee)
589169689Skan	{
590169689Skan	  if (cs->aux)
591169689Skan	    if (IPA_EDGE_REF (cs)->ipa_param_map)
592169689Skan	      free (IPA_EDGE_REF (cs)->ipa_param_map);
593169689Skan	}
594169689Skan    }
595169689Skan}
596169689Skan
597169689Skan/* Print ipa_tree_map data structures of all methods in the
598169689Skan   callgraph to F.  */
599169689Skanvoid
600169689Skanipa_method_tree_print (FILE * f)
601169689Skan{
602169689Skan  int i, count;
603169689Skan  tree temp;
604169689Skan  struct cgraph_node *node;
605169689Skan
606169689Skan  fprintf (f, "\nPARAM TREE MAP PRINT\n");
607169689Skan  for (node = cgraph_nodes; node; node = node->next)
608169689Skan    {
609169689Skan      fprintf (f, "method  %s Trees :: \n", cgraph_node_name (node));
610169689Skan      count = ipa_method_formal_count (node);
611169689Skan      for (i = 0; i < count; i++)
612169689Skan	{
613169689Skan	  temp = ipa_method_get_tree (node, i);
614169689Skan	  if (TREE_CODE (temp) == PARM_DECL)
615169689Skan	    fprintf (f, "  param [%d] : %s\n", i,
616169689Skan		     (*lang_hooks.decl_printable_name) (temp, 2));
617169689Skan	}
618169689Skan
619169689Skan    }
620169689Skan}
621169689Skan
622169689Skan/* Print ipa_modify data structures of all methods in the
623169689Skan   callgraph to F.  */
624169689Skanvoid
625169689Skanipa_method_modify_print (FILE * f)
626169689Skan{
627169689Skan  int i, count;
628169689Skan  bool temp;
629169689Skan  struct cgraph_node *node;
630169689Skan
631169689Skan  fprintf (f, "\nMODIFY PRINT\n");
632169689Skan  for (node = cgraph_nodes; node; node = node->next)
633169689Skan    {
634169689Skan      fprintf (f, "method  %s :: \n", cgraph_node_name (node));
635169689Skan      count = ipa_method_formal_count (node);
636169689Skan      for (i = 0; i < count; i++)
637169689Skan	{
638169689Skan	  temp = ipa_method_is_modified (node, i);
639169689Skan	  if (temp)
640169689Skan	    fprintf (f, " param [%d] true \n", i);
641169689Skan	  else
642169689Skan	    fprintf (f, " param [%d] false \n", i);
643169689Skan	}
644169689Skan    }
645169689Skan}
646