1/* Procedure integration for GCC. 2 Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 4 Free Software Foundation, Inc. 5 Contributed by Michael Tiemann (tiemann@cygnus.com) 6 7This file is part of GCC. 8 9GCC is free software; you can redistribute it and/or modify it under 10the terms of the GNU General Public License as published by the Free 11Software Foundation; either version 3, or (at your option) any later 12version. 13 14GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15WARRANTY; without even the implied warranty of MERCHANTABILITY or 16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17for more details. 18 19You should have received a copy of the GNU General Public License 20along with GCC; see the file COPYING3. If not see 21<http://www.gnu.org/licenses/>. */ 22 23#include "config.h" 24#include "system.h" 25#include "coretypes.h" 26#include "tm.h" 27 28#include "rtl.h" 29#include "tree.h" 30#include "tm_p.h" 31#include "regs.h" 32#include "flags.h" 33#include "debug.h" 34#include "insn-config.h" 35#include "expr.h" 36#include "output.h" 37#include "recog.h" 38#include "integrate.h" 39#include "real.h" 40#include "except.h" 41#include "function.h" 42#include "toplev.h" 43#include "intl.h" 44#include "params.h" 45#include "ggc.h" 46#include "target.h" 47#include "langhooks.h" 48#include "tree-pass.h" 49#include "df.h" 50 51/* Round to the next highest integer that meets the alignment. */ 52#define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1)) 53 54 55/* Private type used by {get/has}_hard_reg_initial_val. */ 56typedef struct GTY(()) initial_value_pair { 57 rtx hard_reg; 58 rtx pseudo; 59} initial_value_pair; 60typedef struct GTY(()) initial_value_struct { 61 int num_entries; 62 int max_entries; 63 initial_value_pair * GTY ((length ("%h.num_entries"))) entries; 64} initial_value_struct; 65 66static void set_block_origin_self (tree); 67static void set_block_abstract_flags (tree, int); 68 69 70/* Return false if the function FNDECL cannot be inlined on account of its 71 attributes, true otherwise. */ 72bool 73function_attribute_inlinable_p (const_tree fndecl) 74{ 75 if (targetm.attribute_table) 76 { 77 const_tree a; 78 79 for (a = DECL_ATTRIBUTES (fndecl); a; a = TREE_CHAIN (a)) 80 { 81 const_tree name = TREE_PURPOSE (a); 82 int i; 83 84 for (i = 0; targetm.attribute_table[i].name != NULL; i++) 85 if (is_attribute_p (targetm.attribute_table[i].name, name)) 86 return targetm.function_attribute_inlinable_p (fndecl); 87 } 88 } 89 90 return true; 91} 92 93/* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the 94 given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so 95 that it points to the node itself, thus indicating that the node is its 96 own (abstract) origin. Additionally, if the BLOCK_ABSTRACT_ORIGIN for 97 the given node is NULL, recursively descend the decl/block tree which 98 it is the root of, and for each other ..._DECL or BLOCK node contained 99 therein whose DECL_ABSTRACT_ORIGINs or BLOCK_ABSTRACT_ORIGINs are also 100 still NULL, set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN 101 values to point to themselves. */ 102 103static void 104set_block_origin_self (tree stmt) 105{ 106 if (BLOCK_ABSTRACT_ORIGIN (stmt) == NULL_TREE) 107 { 108 BLOCK_ABSTRACT_ORIGIN (stmt) = stmt; 109 110 { 111 tree local_decl; 112 113 for (local_decl = BLOCK_VARS (stmt); 114 local_decl != NULL_TREE; 115 local_decl = TREE_CHAIN (local_decl)) 116 set_decl_origin_self (local_decl); /* Potential recursion. */ 117 } 118 119 { 120 tree subblock; 121 122 for (subblock = BLOCK_SUBBLOCKS (stmt); 123 subblock != NULL_TREE; 124 subblock = BLOCK_CHAIN (subblock)) 125 set_block_origin_self (subblock); /* Recurse. */ 126 } 127 } 128} 129 130/* Given a pointer to some ..._DECL node, if the DECL_ABSTRACT_ORIGIN for 131 the given ..._DECL node is NULL, set the DECL_ABSTRACT_ORIGIN for the 132 node to so that it points to the node itself, thus indicating that the 133 node represents its own (abstract) origin. Additionally, if the 134 DECL_ABSTRACT_ORIGIN for the given node is NULL, recursively descend 135 the decl/block tree of which the given node is the root of, and for 136 each other ..._DECL or BLOCK node contained therein whose 137 DECL_ABSTRACT_ORIGINs or BLOCK_ABSTRACT_ORIGINs are also still NULL, 138 set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN values to 139 point to themselves. */ 140 141void 142set_decl_origin_self (tree decl) 143{ 144 if (DECL_ABSTRACT_ORIGIN (decl) == NULL_TREE) 145 { 146 DECL_ABSTRACT_ORIGIN (decl) = decl; 147 if (TREE_CODE (decl) == FUNCTION_DECL) 148 { 149 tree arg; 150 151 for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg)) 152 DECL_ABSTRACT_ORIGIN (arg) = arg; 153 if (DECL_INITIAL (decl) != NULL_TREE 154 && DECL_INITIAL (decl) != error_mark_node) 155 set_block_origin_self (DECL_INITIAL (decl)); 156 } 157 } 158} 159 160/* Given a pointer to some BLOCK node, and a boolean value to set the 161 "abstract" flags to, set that value into the BLOCK_ABSTRACT flag for 162 the given block, and for all local decls and all local sub-blocks 163 (recursively) which are contained therein. */ 164 165static void 166set_block_abstract_flags (tree stmt, int setting) 167{ 168 tree local_decl; 169 tree subblock; 170 unsigned int i; 171 172 BLOCK_ABSTRACT (stmt) = setting; 173 174 for (local_decl = BLOCK_VARS (stmt); 175 local_decl != NULL_TREE; 176 local_decl = TREE_CHAIN (local_decl)) 177 set_decl_abstract_flags (local_decl, setting); 178 179 for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++) 180 { 181 local_decl = BLOCK_NONLOCALIZED_VAR (stmt, i); 182 if ((TREE_CODE (local_decl) == VAR_DECL && !TREE_STATIC (local_decl)) 183 || TREE_CODE (local_decl) == PARM_DECL) 184 set_decl_abstract_flags (local_decl, setting); 185 } 186 187 for (subblock = BLOCK_SUBBLOCKS (stmt); 188 subblock != NULL_TREE; 189 subblock = BLOCK_CHAIN (subblock)) 190 set_block_abstract_flags (subblock, setting); 191} 192 193/* Given a pointer to some ..._DECL node, and a boolean value to set the 194 "abstract" flags to, set that value into the DECL_ABSTRACT flag for the 195 given decl, and (in the case where the decl is a FUNCTION_DECL) also 196 set the abstract flags for all of the parameters, local vars, local 197 blocks and sub-blocks (recursively) to the same setting. */ 198 199void 200set_decl_abstract_flags (tree decl, int setting) 201{ 202 DECL_ABSTRACT (decl) = setting; 203 if (TREE_CODE (decl) == FUNCTION_DECL) 204 { 205 tree arg; 206 207 for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg)) 208 DECL_ABSTRACT (arg) = setting; 209 if (DECL_INITIAL (decl) != NULL_TREE 210 && DECL_INITIAL (decl) != error_mark_node) 211 set_block_abstract_flags (DECL_INITIAL (decl), setting); 212 } 213} 214 215/* Functions to keep track of the values hard regs had at the start of 216 the function. */ 217 218rtx 219get_hard_reg_initial_reg (rtx reg) 220{ 221 struct initial_value_struct *ivs = crtl->hard_reg_initial_vals; 222 int i; 223 224 if (ivs == 0) 225 return NULL_RTX; 226 227 for (i = 0; i < ivs->num_entries; i++) 228 if (rtx_equal_p (ivs->entries[i].pseudo, reg)) 229 return ivs->entries[i].hard_reg; 230 231 return NULL_RTX; 232} 233 234/* Make sure that there's a pseudo register of mode MODE that stores the 235 initial value of hard register REGNO. Return an rtx for such a pseudo. */ 236 237rtx 238get_hard_reg_initial_val (enum machine_mode mode, unsigned int regno) 239{ 240 struct initial_value_struct *ivs; 241 rtx rv; 242 243 rv = has_hard_reg_initial_val (mode, regno); 244 if (rv) 245 return rv; 246 247 ivs = crtl->hard_reg_initial_vals; 248 if (ivs == 0) 249 { 250 ivs = GGC_NEW (initial_value_struct); 251 ivs->num_entries = 0; 252 ivs->max_entries = 5; 253 ivs->entries = GGC_NEWVEC (initial_value_pair, 5); 254 crtl->hard_reg_initial_vals = ivs; 255 } 256 257 if (ivs->num_entries >= ivs->max_entries) 258 { 259 ivs->max_entries += 5; 260 ivs->entries = GGC_RESIZEVEC (initial_value_pair, ivs->entries, 261 ivs->max_entries); 262 } 263 264 ivs->entries[ivs->num_entries].hard_reg = gen_rtx_REG (mode, regno); 265 ivs->entries[ivs->num_entries].pseudo = gen_reg_rtx (mode); 266 267 return ivs->entries[ivs->num_entries++].pseudo; 268} 269 270/* See if get_hard_reg_initial_val has been used to create a pseudo 271 for the initial value of hard register REGNO in mode MODE. Return 272 the associated pseudo if so, otherwise return NULL. */ 273 274rtx 275has_hard_reg_initial_val (enum machine_mode mode, unsigned int regno) 276{ 277 struct initial_value_struct *ivs; 278 int i; 279 280 ivs = crtl->hard_reg_initial_vals; 281 if (ivs != 0) 282 for (i = 0; i < ivs->num_entries; i++) 283 if (GET_MODE (ivs->entries[i].hard_reg) == mode 284 && REGNO (ivs->entries[i].hard_reg) == regno) 285 return ivs->entries[i].pseudo; 286 287 return NULL_RTX; 288} 289 290unsigned int 291emit_initial_value_sets (void) 292{ 293 struct initial_value_struct *ivs = crtl->hard_reg_initial_vals; 294 int i; 295 rtx seq; 296 297 if (ivs == 0) 298 return 0; 299 300 start_sequence (); 301 for (i = 0; i < ivs->num_entries; i++) 302 emit_move_insn (ivs->entries[i].pseudo, ivs->entries[i].hard_reg); 303 seq = get_insns (); 304 end_sequence (); 305 306 emit_insn_at_entry (seq); 307 return 0; 308} 309 310struct rtl_opt_pass pass_initial_value_sets = 311{ 312 { 313 RTL_PASS, 314 "initvals", /* name */ 315 NULL, /* gate */ 316 emit_initial_value_sets, /* execute */ 317 NULL, /* sub */ 318 NULL, /* next */ 319 0, /* static_pass_number */ 320 TV_NONE, /* tv_id */ 321 0, /* properties_required */ 322 0, /* properties_provided */ 323 0, /* properties_destroyed */ 324 0, /* todo_flags_start */ 325 TODO_dump_func /* todo_flags_finish */ 326 } 327}; 328 329/* If the backend knows where to allocate pseudos for hard 330 register initial values, register these allocations now. */ 331void 332allocate_initial_values (rtx *reg_equiv_memory_loc) 333{ 334 if (targetm.allocate_initial_value) 335 { 336 struct initial_value_struct *ivs = crtl->hard_reg_initial_vals; 337 int i; 338 339 if (ivs == 0) 340 return; 341 342 for (i = 0; i < ivs->num_entries; i++) 343 { 344 int regno = REGNO (ivs->entries[i].pseudo); 345 rtx x = targetm.allocate_initial_value (ivs->entries[i].hard_reg); 346 347 if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1) 348 { 349 if (MEM_P (x)) 350 reg_equiv_memory_loc[regno] = x; 351 else 352 { 353 basic_block bb; 354 int new_regno; 355 356 gcc_assert (REG_P (x)); 357 new_regno = REGNO (x); 358 reg_renumber[regno] = new_regno; 359 /* Poke the regno right into regno_reg_rtx so that even 360 fixed regs are accepted. */ 361 SET_REGNO (ivs->entries[i].pseudo, new_regno); 362 /* Update global register liveness information. */ 363 FOR_EACH_BB (bb) 364 { 365 if (REGNO_REG_SET_P(df_get_live_in (bb), regno)) 366 SET_REGNO_REG_SET (df_get_live_in (bb), new_regno); 367 if (REGNO_REG_SET_P(df_get_live_out (bb), regno)) 368 SET_REGNO_REG_SET (df_get_live_out (bb), new_regno); 369 } 370 } 371 } 372 } 373 } 374} 375 376#include "gt-integrate.h" 377