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