ipa-prop.h 13.4 KB
Newer Older
Razya Ladelsky committed
1
/* Interprocedural analyses.
2
   Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
Razya Ladelsky committed
3 4 5 6 7

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
8
Software Foundation; either version 3, or (at your option) any later
Razya Ladelsky committed
9 10 11 12 13 14 15 16
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
17 18
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
Razya Ladelsky committed
19 20 21 22 23

#ifndef IPA_PROP_H
#define IPA_PROP_H

#include "tree.h"
24
#include "vec.h"
25
#include "cgraph.h"
Razya Ladelsky committed
26 27 28 29

/* The following definitions and interfaces are used by
   interprocedural analyses.  */

30
/* A jump function for a callsite represents the values passed as actual
Razya Ladelsky committed
31 32
   arguments of the callsite. There are three main types of values :
   Formal - the caller's formal parameter is passed as an actual argument.
33
   Constant - a constant is passed as an actual argument.
Razya Ladelsky committed
34
   Unknown - neither of the above.
35 36
   Integer and real constants are represented as IPA_CONST.
   Finally, IPA_CONST_MEMBER_PTR stands for C++ member pointers constants.  */
Razya Ladelsky committed
37 38
enum jump_func_type
{
39
  IPA_UNKNOWN = 0,     /* newly allocated and zeroed jump functions default */
40
  IPA_CONST,
41
  IPA_CONST_MEMBER_PTR,
42
  IPA_PASS_THROUGH
Razya Ladelsky committed
43 44
};

45 46 47
/* All formal parameters in the program have a lattice associated with it
   computed by the interprocedural stage of IPCP.
   There are three main values of the lattice:
48 49 50
   IPA_TOP - unknown,
   IPA_BOTTOM - non constant,
   IPA_CONST_VALUE - simple scalar constant,
Razya Ladelsky committed
51 52
   Cval of formal f will have a constant value if all callsites to this
   function have the same constant value passed to f.
53
   Integer and real constants are represented as IPA_CONST.  */
54 55 56 57 58
enum ipa_lattice_type
{
  IPA_BOTTOM,
  IPA_CONST_VALUE,
  IPA_TOP
Razya Ladelsky committed
59 60
};

61 62 63 64 65 66 67 68 69 70 71 72 73
/* Structure holding a C++ member pointer constant.  Holds a pointer to the
   method and delta offset.  */
struct ipa_member_ptr_cst
{
  tree pfn;
  tree delta;
};

/* Represents a value of a jump function.  formal_id is used only in jump
   function context and represents pass-through parameter (the formal parameter
   of the caller is passed as argument).  constant represents the actual
   constant in constant jump functions and member_cst holds constant c++ member
   functions.  */
74
union jump_func_value
Razya Ladelsky committed
75 76
{
  unsigned int formal_id;
77
  tree constant;
78
  struct ipa_member_ptr_cst member_cst;
Razya Ladelsky committed
79 80
};

81 82
/* A jump function for a callsite represents the values passed as actual
   arguments of the callsite. See enum jump_func_type for the various
Razya Ladelsky committed
83 84 85 86
   types of jump functions supported.  */
struct ipa_jump_func
{
  enum jump_func_type type;
87
  union jump_func_value value;
Razya Ladelsky committed
88 89
};

90
/* All formal parameters in the program have a cval computed by
91 92 93
   the interprocedural stage of IPCP. See enum ipa_lattice_type for
   the various types of lattices supported */
struct ipcp_lattice
Razya Ladelsky committed
94
{
95 96
  enum ipa_lattice_type type;
  tree constant;
Razya Ladelsky committed
97 98 99 100 101 102 103 104
};

/* Represent which DECL tree (or reference to such tree)
   will be replaced by another tree while versioning.  */
struct ipa_replace_map
{
  /* The tree that will be replaced.  */
  tree old_tree;
105
  /* The new (replacing) tree.  */
Razya Ladelsky committed
106 107 108 109 110 111 112
  tree new_tree;
  /* True when a substitution should be done, false otherwise.  */
  bool replace_p;
  /* True when we replace a reference to old_tree.  */
  bool ref_p;
};

113 114 115 116 117 118 119 120
/* Each instance of the following  structure describes a statement that calls a
   function parameter.  Those referring  to statements within the same function
   are linked in a list.  */
struct ipa_param_call_note
{
  /* Linked list's next */
  struct ipa_param_call_note *next;
  /* Statement that contains the call to the parameter above.  */
121
  gimple stmt;
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
  /* Index of the parameter that is called.  */
  unsigned int formal_id;
  /* Expected number of executions: calculated in profile.c.  */
  gcov_type count;
  /* Expected frequency of executions within the function. see cgraph_edge in
     cgraph.h for more on this. */
  int frequency;
  /* Depth of loop nest, 1 means no loop nest.  */
  int loop_nest;
  /* Set when we have already found the target to be a compile time constant
     and turned this into an edge or when the note was found unusable for some
     reason.  */
  bool processed;
};

137 138 139 140 141 142 143 144 145 146 147 148 149
/* Structure describing a single formal parameter.  */
struct ipa_param_descriptor
{
  /* IPA-CP lattice.  */
  struct ipcp_lattice ipcp_lattice;
  /* PARAM_DECL of this parameter.  */
  tree decl;
  /* Whether the value parameter has been modified within the function.  */
  unsigned modified : 1;
  /* Whether the parameter has been used as a call destination. */
  unsigned called : 1;
};

150 151 152 153
/* ipa_node_params stores information related to formal parameters of functions
   and some other information for interprocedural passes that operate on
   parameters (such as ipa-cp).  */
struct ipa_node_params
Razya Ladelsky committed
154
{
155
  /* Number of formal parameters of this function.  When set to 0,
156
     this function's parameters would not be analyzed by the different
Razya Ladelsky committed
157
     stages of IPA CP.  */
158
  int param_count;
159 160 161
  /* Pointer to an array of structures describing individual formal
     parameters.  */
  struct ipa_param_descriptor *params;
162 163
  /* List of structures enumerating calls to a formal parameter.  */
  struct ipa_param_call_note *param_calls;
Razya Ladelsky committed
164 165 166
  /* Only for versioned nodes this field would not be NULL,
     it points to the node that IPA cp cloned from.  */
  struct cgraph_node *ipcp_orig_node;
167
  /* Meaningful only for original functions.  Expresses the
168 169
     ratio between the direct calls and sum of all invocations of
     this function (given by profiling info).  It is used to calculate
Razya Ladelsky committed
170 171 172
     the profiling information of the original function and the versioned
     one.  */
  gcov_type count_scale;
173

174
  /* Whether this function is called with variable number of actual
175 176
     arguments.  */
  unsigned called_with_var_arguments : 1;
177 178 179 180
  /* Whether the modification analysis has already been performed. */
  unsigned modification_analysis_done : 1;
  /* Whether the param uses analysis has already been performed.  */
  unsigned uses_analysis_done : 1;
Razya Ladelsky committed
181 182
};

183 184 185 186
/* ipa_node_params access functions.  Please use these to access fields that
   are or will be shared among various passes.  */

/* Set the number of formal parameters. */
187

188 189 190 191 192 193 194
static inline void
ipa_set_param_count (struct ipa_node_params *info, int count)
{
  info->param_count = count;
}

/* Return the number of formal parameters. */
195

196 197 198 199 200 201
static inline int
ipa_get_param_count (struct ipa_node_params *info)
{
  return info->param_count;
}

202 203 204
/* Return the declaration of Ith formal parameter of the function corresponding
   to INFO.  Note there is no setter function as this array is built just once
   using ipa_initialize_node_params. */
205

206
static inline tree
207
ipa_get_param (struct ipa_node_params *info, int i)
208
{
209
  return info->params[i].decl;
210 211
}

212 213 214 215
/* Return the modification flag corresponding to the Ith formal parameter of
   the function associated with INFO.  Note that there is no setter method as
   the goal is to set all flags when building the array in
   ipa_detect_param_modifications.  */
216

217
static inline bool
218
ipa_is_param_modified (struct ipa_node_params *info, int i)
219
{
220
  return info->params[i].modified;
221 222
}

223 224 225
/* Return the called flag corresponding to the Ith formal parameter of the
   function associated with INFO.  Note that there is no setter method as the
   goal is to set all flags when building the array in
226
   ipa_detect_called_params.  */
227

228
static inline bool
229
ipa_is_param_called (struct ipa_node_params *info, int i)
230
{
231
  return info->params[i].called;
232 233 234
}

/* Flag this node as having callers with variable number of arguments.  */
235

236 237 238 239 240 241 242
static inline void
ipa_set_called_with_variable_arg (struct ipa_node_params *info)
{
  info->called_with_var_arguments = 1;
}

/* Have we detected this node was called with variable number of arguments? */
243

244 245 246 247 248 249 250 251 252 253 254 255
static inline bool
ipa_is_called_with_var_arguments (struct ipa_node_params *info)
{
  return info->called_with_var_arguments;
}



/* ipa_edge_args stores information related to a callsite and particularly
   its arguments. It is pointed to by a field in the
   callsite's corresponding cgraph_edge.  */
struct ipa_edge_args
Razya Ladelsky committed
256 257 258 259
{
  /* Number of actual arguments in this callsite.  When set to 0,
     this callsite's parameters would not be analyzed by the different
     stages of IPA CP.  */
260
  int argument_count;
Razya Ladelsky committed
261
  /* Array of the callsite's jump function of each parameter.  */
262
  struct ipa_jump_func *jump_functions;
Razya Ladelsky committed
263 264
};

265 266 267 268
/* ipa_edge_args access functions.  Please use these to access fields that
   are or will be shared among various passes.  */

/* Set the number of actual arguments. */
269

270 271
static inline void
ipa_set_cs_argument_count (struct ipa_edge_args *args, int count)
Razya Ladelsky committed
272
{
273 274 275 276
  args->argument_count = count;
}

/* Return the number of actual arguments. */
277

278 279 280 281 282 283 284 285 286
static inline int
ipa_get_cs_argument_count (struct ipa_edge_args *args)
{
  return args->argument_count;
}

/* Returns a pointer to the jump function for the ith argument.  Please note
   there is no setter function as jump functions are all set up in
   ipa_compute_jump_functions. */
287

288 289 290 291 292 293
static inline struct ipa_jump_func *
ipa_get_ith_jump_func (struct ipa_edge_args *args, int i)
{
  return &args->jump_functions[i];
}

294 295 296 297
/* Vectors need to have typedefs of structures.  */
typedef struct ipa_node_params ipa_node_params_t;
typedef struct ipa_edge_args ipa_edge_args_t;

298
/* Types of vectors holding the infos.  */
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
DEF_VEC_O (ipa_node_params_t);
DEF_VEC_ALLOC_O (ipa_node_params_t, heap);
DEF_VEC_O (ipa_edge_args_t);
DEF_VEC_ALLOC_O (ipa_edge_args_t, heap);

/* Vector where the parameter infos are actually stored. */
extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
/* Vector where the parameter infos are actually stored. */
extern VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;

/* Return the associated parameter/argument info corresponding to the given
   node/edge.  */
#define IPA_NODE_REF(NODE) (VEC_index (ipa_node_params_t, \
				       ipa_node_params_vector, (NODE)->uid))
#define IPA_EDGE_REF(EDGE) (VEC_index (ipa_edge_args_t, \
				       ipa_edge_args_vector, (EDGE)->uid))
/* This macro checks validity of index returned by
   ipa_get_param_decl_index function.  */
#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)

/* Creating and freeing ipa_node_params and ipa_edge_args.  */
void ipa_create_all_node_params (void);
void ipa_create_all_edge_args (void);
void ipa_free_edge_args_substructures (struct ipa_edge_args *);
void ipa_free_node_params_substructures (struct ipa_node_params *);
void ipa_free_all_node_params (void);
void ipa_free_all_edge_args (void);
void free_all_ipa_structures_after_ipa_cp (void);
327
void free_all_ipa_structures_after_iinln (void);
328 329 330
void ipa_register_cgraph_hooks (void);

/* This function ensures the array of node param infos is big enough to
331 332
   accommodate a structure for all nodes and reallocates it if not.  */

333 334 335 336 337 338 339 340 341 342 343 344 345
static inline void
ipa_check_create_node_params (void)
{
  if (!ipa_node_params_vector)
    ipa_node_params_vector = VEC_alloc (ipa_node_params_t, heap,
					cgraph_max_uid);

  if (VEC_length (ipa_node_params_t, ipa_node_params_vector)
      <= (unsigned) cgraph_max_uid)
    VEC_safe_grow_cleared (ipa_node_params_t, heap,
			   ipa_node_params_vector, cgraph_max_uid + 1);
}

346 347 348
/* This function ensures the array of edge arguments infos is big enough to
   accommodate a structure for all edges and reallocates it if not.  */

349 350 351 352 353 354 355 356 357 358 359 360 361
static inline void
ipa_check_create_edge_args (void)
{
  if (!ipa_edge_args_vector)
    ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, heap,
				      cgraph_edge_max_uid);

  if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
      <=  (unsigned) cgraph_edge_max_uid)
    VEC_safe_grow_cleared (ipa_edge_args_t, heap, ipa_edge_args_vector,
			   cgraph_edge_max_uid + 1);
}

362
/* Returns true if the array of edge infos is large enough to accommodate an
363 364
   info for EDGE.  The main purpose of this function is that debug dumping
   function can check info availability without causing reallocations.  */
365

366 367 368 369 370 371 372
static inline bool
ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
{
  return ((unsigned) edge->uid < VEC_length (ipa_edge_args_t,
					     ipa_edge_args_vector));
}

373 374 375 376 377 378
/* A function list element.  It is used to create a temporary worklist used in
   the propagation stage of IPCP. (can be used for more IPA optimizations)  */
struct ipa_func_list
{
  struct cgraph_node *node;
  struct ipa_func_list *next;
Razya Ladelsky committed
379 380
};

381 382 383 384 385 386 387 388 389
/* ipa_func_list interface.  */
struct ipa_func_list *ipa_init_func_list (void);
void ipa_push_func_to_list (struct ipa_func_list **, struct cgraph_node *);
struct cgraph_node *ipa_pop_func_from_list (struct ipa_func_list **);

/* Callsite related calculations.  */
void ipa_compute_jump_functions (struct cgraph_edge *);
void ipa_count_arguments (struct cgraph_edge *);

390 391
/* Function formal parameters related computations.  */
void ipa_initialize_node_params (struct cgraph_node *node);
392
void ipa_detect_param_modifications (struct cgraph_node *);
393
void ipa_analyze_params_uses (struct cgraph_node *);
394
bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
395
					VEC (cgraph_edge_p, heap) **new_edges);
Razya Ladelsky committed
396 397

/* Debugging interface.  */
398 399
void ipa_print_node_params (FILE *, struct cgraph_node *node);
void ipa_print_all_params (FILE *);
400 401
void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
void ipa_print_all_jump_functions (FILE * f);
Razya Ladelsky committed
402 403

#endif /* IPA_PROP_H */