/* Interprocedural analyses.
- Copyright (C) 2005-2014 Free Software Foundation, Inc.
+ Copyright (C) 2005-2016 Free Software Foundation, Inc.
This file is part of GCC.
#ifndef IPA_PROP_H
#define IPA_PROP_H
-
/* The following definitions and interfaces are used by
interprocedural analyses or parameters. */
IPA_JF_ANCESTOR is a special pass-through jump function, which means that
the result is an address of a part of the object pointed to by the formal
parameter to which the function refers. It is mainly intended to represent
- getting addresses of of ancestor fields in C++
+ getting addresses of ancestor fields in C++
(e.g. &this_1(D)->D.1766.D.1756). Note that if the original pointer is
NULL, ancestor jump function must behave like a simple pass-through.
IPA_JF_ANCESTOR /* represented by field ancestor */
};
-/* Structure holding data required to describe a known type jump function. */
-struct GTY(()) ipa_known_type_data
-{
- /* Offset of the component of the base_type being described. */
- HOST_WIDE_INT offset;
- /* Type of the whole object. */
- tree base_type;
- /* Type of the component of the object that is being described. */
- tree component_type;
-};
-
struct ipa_cst_ref_desc;
/* Structure holding data required to describe a constant jump function. */
typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p;
+/* Info about pointer alignments. */
+struct GTY(()) ipa_alignment
+{
+ /* The data fields below are valid only if known is true. */
+ bool known;
+ /* See ptr_info_def and get_pointer_alignment_1 for description of these
+ two. */
+ unsigned align;
+ unsigned misalign;
+};
+
/* A jump function for a callsite represents the values passed as actual
arguments of the callsite. See enum jump_func_type for the various
types of jump functions supported. */
description. */
struct ipa_agg_jump_function agg;
+ /* Information about alignment of pointers. */
+ struct ipa_alignment alignment;
+
enum jump_func_type type;
/* Represents a value of a jump function. pass_through is used only in jump
function context. constant represents the actual constant in constant jump
struct ipa_node_params
{
+ ~ipa_node_params ();
+
/* Information about individual formal parameters that are gathered when
summaries are generated. */
vec<ipa_param_descriptor> descriptors;
/* Node has been completely replaced by clones and will be removed after
ipa-cp is finished. */
unsigned node_dead : 1;
+ /* Node is involved in a recursion, potentionally indirect. */
+ unsigned node_within_scc : 1;
+ /* Node is calling a private function called only once. */
+ unsigned node_calling_single_call : 1;
+ /* False when there is something makes versioning impossible. */
+ unsigned versionable : 1;
+};
+
+/* Intermediate information that we get from alias analysis about a particular
+ parameter in a particular basic_block. When a parameter or the memory it
+ references is marked modified, we use that information in all dominated
+ blocks without consulting alias analysis oracle. */
+
+struct ipa_param_aa_status
+{
+ /* Set when this structure contains meaningful information. If not, the
+ structure describing a dominating BB should be used instead. */
+ bool valid;
+
+ /* Whether we have seen something which might have modified the data in
+ question. PARM is for the parameter itself, REF is for data it points to
+ but using the alias type of individual accesses and PT is the same thing
+ but for computing aggregate pass-through functions using a very inclusive
+ ao_ref. */
+ bool parm_modified, ref_modified, pt_modified;
+};
+
+/* Information related to a given BB that used only when looking at function
+ body. */
+
+struct ipa_bb_info
+{
+ /* Call graph edges going out of this BB. */
+ vec<cgraph_edge *> cg_edges;
+ /* Alias analysis statuses of each formal parameter at this bb. */
+ vec<ipa_param_aa_status> param_aa_statuses;
+};
+
+/* Structure with global information that is only used when looking at function
+ body. */
+
+struct ipa_func_body_info
+{
+ /* The node that is being analyzed. */
+ cgraph_node *node;
+
+ /* Its info. */
+ struct ipa_node_params *info;
+
+ /* Information about individual BBs. */
+ vec<ipa_bb_info> bb_infos;
+
+ /* Number of parameters. */
+ int param_count;
+
+ /* Number of statements already walked by when analyzing this function. */
+ unsigned int aa_walked;
};
/* ipa_node_params access functions. Please use these to access fields that
bool by_ref;
};
-typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
+/* Structure holding information for the transformation phase of IPA-CP. */
+
+struct GTY(()) ipcp_transformation_summary
+{
+ /* Linked list of known aggregate values. */
+ ipa_agg_replacement_value *agg_values;
+ /* Alignment information for pointers. */
+ vec<ipa_alignment, va_gc> *alignments;
+};
void ipa_set_node_agg_value_chain (struct cgraph_node *node,
struct ipa_agg_replacement_value *aggvals);
+void ipcp_grow_transformations_if_necessary (void);
/* ipa_edge_args stores information related to a callsite and particularly its
arguments. It can be accessed by the IPA_EDGE_REF macro. */
return &(*args->polymorphic_call_contexts)[i];
}
-/* Types of vectors holding the infos. */
+/* Function summary for ipa_node_params. */
+class ipa_node_params_t: public function_summary <ipa_node_params *>
+{
+public:
+ ipa_node_params_t (symbol_table *table):
+ function_summary<ipa_node_params *> (table) { }
-/* Vector where the parameter infos are actually stored. */
-extern vec<ipa_node_params> ipa_node_params_vector;
-/* Vector of known aggregate values in cloned nodes. */
-extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
+ /* Hook that is called by summary when a node is duplicated. */
+ virtual void duplicate (cgraph_node *node,
+ cgraph_node *node2,
+ ipa_node_params *data,
+ ipa_node_params *data2);
+};
+
+/* Function summary where the parameter infos are actually stored. */
+extern ipa_node_params_t *ipa_node_params_sum;
+/* Vector of IPA-CP transformation data for each clone. */
+extern GTY(()) vec<ipcp_transformation_summary, va_gc> *ipcp_transformations;
/* Vector where the parameter infos are actually stored. */
extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
/* Return the associated parameter/argument info corresponding to the given
node/edge. */
-#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
+#define IPA_NODE_REF(NODE) (ipa_node_params_sum->get (NODE))
#define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
/* This macro checks validity of index returned by
ipa_get_param_decl_index function. */
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 ipa_free_all_structures_after_ipa_cp (void);
void ipa_free_all_structures_after_iinln (void);
+
void ipa_register_cgraph_hooks (void);
int count_formal_params (tree fndecl);
static inline void
ipa_check_create_node_params (void)
{
- if (!ipa_node_params_vector.exists ())
- ipa_node_params_vector.create (symtab->cgraph_max_uid);
-
- if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid)
- ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1);
+ if (!ipa_node_params_sum)
+ ipa_node_params_sum = new ipa_node_params_t (symtab);
}
/* This function ensures the array of edge arguments infos is big enough to
return ((unsigned) edge->uid < vec_safe_length (ipa_edge_args_vector));
}
+static inline ipcp_transformation_summary *
+ipcp_get_transformation_summary (cgraph_node *node)
+{
+ if ((unsigned) node->uid >= vec_safe_length (ipcp_transformations))
+ return NULL;
+ return &(*ipcp_transformations)[node->uid];
+}
+
/* Return the aggregate replacements for NODE, if there are any. */
static inline struct ipa_agg_replacement_value *
-ipa_get_agg_replacements_for_node (struct cgraph_node *node)
+ipa_get_agg_replacements_for_node (cgraph_node *node)
{
- if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements))
- return NULL;
- return (*ipa_node_agg_replacements)[node->uid];
+ ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
+ return ts ? ts->agg_values : NULL;
}
/* Function formal parameters related computations. */
tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
vec<tree> ,
vec<ipa_polymorphic_call_context>,
- vec<ipa_agg_jump_function_p> );
+ vec<ipa_agg_jump_function_p>,
+ bool *);
struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree,
bool speculative = false);
-tree ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *);
tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
/* Functions related to both. */
void ipa_analyze_node (struct cgraph_node *);
/* Aggregate jump function related functions. */
-tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
- bool);
-bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
- HOST_WIDE_INT *, bool *);
+tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg, tree scalar,
+ HOST_WIDE_INT offset, bool by_ref,
+ bool *from_global_constant = NULL);
+bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
+ vec<ipa_param_descriptor> descriptors,
+ gimple *stmt, tree op, int *index_p,
+ HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
+ bool *by_ref, bool *guaranteed_unmodified = NULL);
/* Debugging interface. */
void ipa_print_node_params (FILE *, struct cgraph_node *node);
void ipa_print_all_jump_functions (FILE * f);
void ipcp_verify_propagated_values (void);
-extern alloc_pool ipcp_cst_values_pool;
-extern alloc_pool ipcp_poly_ctx_values_pool;
-extern alloc_pool ipcp_sources_pool;
-extern alloc_pool ipcp_agg_lattice_pool;
+template <typename value>
+class ipcp_value;
+
+extern object_allocator<ipcp_value<tree> > ipcp_cst_values_pool;
+extern object_allocator<ipcp_value<ipa_polymorphic_call_context> >
+ ipcp_poly_ctx_values_pool;
+
+template <typename valtype>
+class ipcp_value_source;
+
+extern object_allocator<ipcp_value_source<tree> > ipcp_sources_pool;
+
+class ipcp_agg_lattice;
+
+extern object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool;
/* Operation to be performed for the parameter in ipa_parm_adjustment
below. */
or one about to be removed. */
enum ipa_parm_op op;
+ /* Storage order of the original parameter (for the cases when the new
+ parameter is a component of an original one). */
+ unsigned reverse : 1;
+
/* The parameter is to be passed by reference. */
unsigned by_ref : 1;
};
vec<tree> ipa_get_vector_of_formal_parms (tree fndecl);
vec<tree> ipa_get_vector_of_formal_parm_types (tree fntype);
void ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec);
-void ipa_modify_call_arguments (struct cgraph_edge *, gimple,
+void ipa_modify_call_arguments (struct cgraph_edge *, gcall *,
ipa_parm_adjustment_vec);
ipa_parm_adjustment_vec ipa_combine_adjustments (ipa_parm_adjustment_vec,
ipa_parm_adjustment_vec);
struct ipa_agg_replacement_value *av);
void ipa_prop_write_jump_functions (void);
void ipa_prop_read_jump_functions (void);
-void ipa_prop_write_all_agg_replacement (void);
-void ipa_prop_read_all_agg_replacement (void);
+void ipcp_write_transformation_summaries (void);
+void ipcp_read_transformation_summaries (void);
void ipa_update_after_lto_read (void);
int ipa_get_param_decl_index (struct ipa_node_params *, tree);
tree ipa_value_from_jfunc (struct ipa_node_params *info,
ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
ipa_parm_adjustment_vec,
bool);
-
+void ipa_release_body_info (struct ipa_func_body_info *);
/* From tree-sra.c: */
-tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, tree,
+tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, bool, tree,
gimple_stmt_iterator *, bool);
/* In ipa-cp.c */