extern const char * const cgraph_availability_names[];
extern const char * const ld_plugin_symbol_resolution_names[];
-/* Function inlining information. */
-
-struct GTY(()) inline_summary
-{
- /* Estimated stack frame consumption by the function. */
- HOST_WIDE_INT estimated_self_stack_size;
-
- /* Size of the function body. */
- int self_size;
- /* How many instructions are likely going to disappear after inlining. */
- int size_inlining_benefit;
- /* Estimated time spent executing the function body. */
- int self_time;
- /* How much time is going to be saved by inlining. */
- int time_inlining_benefit;
-};
-
/* Information about thunk, used only for same body aliases. */
struct GTY(()) cgraph_thunk_info {
/* File stream where this node is being written to. */
struct lto_file_decl_data * lto_file_data;
- struct inline_summary inline_summary;
-
/* Set when function function is visible in current compilation unit only
and its address is never taken. */
unsigned local : 1;
/* Set once it has been finalized so we consider it to be output. */
unsigned finalized : 1;
- /* False when there something makes inlining impossible (such as va_arg). */
- unsigned inlinable : 1;
-
- /* False when there something makes versioning impossible.
- Currently computed and used only by ipa-cp. */
- unsigned versionable : 1;
-
/* False when function calling convention and signature can not be changed.
This is the case when __builtin_apply_args is used. */
unsigned can_change_signature : 1;
- /* True when function should be inlined independently on its size. */
- unsigned disregard_inline_limits : 1;
-
/* True when the function has been originally extern inline, but it is
redefined now. */
unsigned redefined_extern_inline : 1;
-
- /* True if the function is going to be emitted in some other translation
- unit, referenced from vtable. */
- unsigned vtable_method : 1;
};
/* Information about the function that needs to be computed globally
once compilation is finished. Available only with -funit-at-a-time. */
struct GTY(()) cgraph_global_info {
- /* Estimated stack frame consumption by the function. */
- HOST_WIDE_INT estimated_stack_size;
- /* Expected offset of the stack frame of inlined function. */
- HOST_WIDE_INT stack_frame_offset;
-
/* For inline clones this points to the function they will be
inlined into. */
struct cgraph_node *inlined_to;
-
- /* Estimated size of the function after inlining. */
- int time;
- int size;
-
- /* Estimated growth after inlining. INT_MIN if not computed. */
- int estimated_growth;
};
/* Information about the function that is propagated by the RTL backend.
/* Ordering of all cgraph nodes. */
int order;
- /* unique id for profiling. pid is not suitable because of different
- number of cfg nodes with -fprofile-generate and -fprofile-use */
- int pid;
enum ld_plugin_symbol_resolution resolution;
/* Set when function must be output for some reason. The primary
unsigned process : 1;
/* Set for aliases once they got through assemble_alias. */
unsigned alias : 1;
- /* Set for nodes that was constructed and finalized by frontend. */
- unsigned finalized_by_frontend : 1;
/* Set for alias and thunk nodes, same_body points to the node they are alias
of and they are linked through the next/previous pointers. */
unsigned same_body_alias : 1;
/* A cgraph node set is a collection of cgraph nodes. A cgraph node
can appear in multiple sets. */
-struct GTY(()) cgraph_node_set_def
+struct cgraph_node_set_def
{
- htab_t GTY((param_is (struct cgraph_node_set_element_def))) hashtab;
- VEC(cgraph_node_ptr, gc) *nodes;
+ struct pointer_map_t *map;
+ VEC(cgraph_node_ptr, heap) *nodes;
};
typedef struct varpool_node *varpool_node_ptr;
/* A varpool node set is a collection of varpool nodes. A varpool node
can appear in multiple sets. */
-struct GTY(()) varpool_node_set_def
+struct varpool_node_set_def
{
- htab_t GTY((param_is (struct varpool_node_set_element_def))) hashtab;
- VEC(varpool_node_ptr, gc) *nodes;
+ struct pointer_map_t * map;
+ VEC(varpool_node_ptr, heap) *nodes;
};
typedef struct cgraph_node_set_def *cgraph_node_set;
DEF_VEC_ALLOC_P(varpool_node_set,gc);
DEF_VEC_ALLOC_P(varpool_node_set,heap);
-/* A cgraph node set element contains an index in the vector of nodes in
- the set. */
-struct GTY(()) cgraph_node_set_element_def
-{
- struct cgraph_node *node;
- HOST_WIDE_INT index;
-};
-
-typedef struct cgraph_node_set_element_def *cgraph_node_set_element;
-typedef const struct cgraph_node_set_element_def *const_cgraph_node_set_element;
-
/* Iterator structure for cgraph node sets. */
typedef struct
{
unsigned index;
} cgraph_node_set_iterator;
-/* A varpool node set element contains an index in the vector of nodes in
- the set. */
-struct GTY(()) varpool_node_set_element_def
-{
- struct varpool_node *node;
- HOST_WIDE_INT index;
-};
-
-typedef struct varpool_node_set_element_def *varpool_node_set_element;
-typedef const struct varpool_node_set_element_def *const_varpool_node_set_element;
-
/* Iterator structure for varpool node sets. */
typedef struct
{
int frequency;
/* Unique id of the edge. */
int uid;
- /* Depth of loop nest, 1 means no loop nest. */
- unsigned short int loop_nest;
/* Whether this edge was made direct by indirect inlining. */
unsigned int indirect_inlining_edge : 1;
/* Whether this edge describes an indirect call with an undetermined
extern GTY(()) int cgraph_n_nodes;
extern GTY(()) int cgraph_max_uid;
extern GTY(()) int cgraph_edge_max_uid;
-extern GTY(()) int cgraph_max_pid;
extern bool cgraph_global_info_ready;
enum cgraph_state
{
void cgraph_node_remove_callees (struct cgraph_node *node);
struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
struct cgraph_node *,
- gimple, gcov_type, int, int);
+ gimple, gcov_type, int);
struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple,
- int, gcov_type, int, int);
+ int, gcov_type, int);
struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
struct cgraph_node * cgraph_get_node (const_tree);
struct cgraph_node * cgraph_get_node_or_alias (const_tree);
-struct cgraph_node * cgraph_node (tree);
-struct cgraph_node * cgraph_same_body_alias (tree, tree);
-struct cgraph_node * cgraph_add_thunk (tree, tree, bool, HOST_WIDE_INT,
+struct cgraph_node * cgraph_create_node (tree);
+struct cgraph_node * cgraph_get_create_node (tree);
+struct cgraph_node * cgraph_same_body_alias (struct cgraph_node *, tree, tree);
+struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, HOST_WIDE_INT,
HOST_WIDE_INT, tree, tree);
void cgraph_remove_same_body_alias (struct cgraph_node *);
struct cgraph_node *cgraph_node_for_asm (tree);
void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple, gimple);
void cgraph_create_edge_including_clones (struct cgraph_node *,
struct cgraph_node *,
- gimple, gimple, gcov_type, int, int,
+ gimple, gimple, gcov_type, int,
cgraph_inline_failed_t);
void cgraph_update_edges_for_call_stmt (gimple, tree, gimple);
struct cgraph_local_info *cgraph_local_info (tree);
const char * cgraph_node_name (struct cgraph_node *);
struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *,
struct cgraph_node *, gimple,
- unsigned, gcov_type, int, int, bool);
-struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type, int,
- int, bool, VEC(cgraph_edge_p,heap) *);
+ unsigned, gcov_type, int, bool);
+struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type,
+ int, bool, VEC(cgraph_edge_p,heap) *,
+ bool);
void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *,
extern FILE *cgraph_dump_file;
void cgraph_finalize_function (tree, bool);
void cgraph_mark_if_needed (tree);
+void cgraph_analyze_function (struct cgraph_node *);
void cgraph_finalize_compilation_unit (void);
void cgraph_optimize (void);
void cgraph_mark_needed_node (struct cgraph_node *);
void cgraph_mark_address_taken_node (struct cgraph_node *);
void cgraph_mark_reachable_node (struct cgraph_node *);
bool cgraph_inline_p (struct cgraph_edge *, cgraph_inline_failed_t *reason);
-bool cgraph_preserve_function_body_p (tree);
+bool cgraph_preserve_function_body_p (struct cgraph_node *);
void verify_cgraph (void);
void verify_cgraph_node (struct cgraph_node *);
void cgraph_build_static_cdtor (char which, tree body, int priority);
const char *);
void tree_function_versioning (tree, tree, VEC (ipa_replace_map_p,gc)*, bool, bitmap,
bitmap, basic_block);
-struct cgraph_node *save_inline_function_body (struct cgraph_node *);
void record_references_in_initializer (tree, bool);
bool cgraph_process_new_functions (void);
/* In ipa.c */
bool cgraph_remove_unreachable_nodes (bool, FILE *);
-int cgraph_postorder (struct cgraph_node **);
cgraph_node_set cgraph_node_set_new (void);
cgraph_node_set_iterator cgraph_node_set_find (cgraph_node_set,
struct cgraph_node *);
void cgraph_node_set_remove (cgraph_node_set, struct cgraph_node *);
void dump_cgraph_node_set (FILE *, cgraph_node_set);
void debug_cgraph_node_set (cgraph_node_set);
+void free_cgraph_node_set (cgraph_node_set);
varpool_node_set varpool_node_set_new (void);
varpool_node_set_iterator varpool_node_set_find (varpool_node_set,
void varpool_node_set_remove (varpool_node_set, struct varpool_node *);
void dump_varpool_node_set (FILE *, varpool_node_set);
void debug_varpool_node_set (varpool_node_set);
+void free_varpool_node_set (varpool_node_set);
void ipa_discover_readonly_nonaddressable_vars (void);
bool cgraph_comdat_can_be_unshared_p (struct cgraph_node *);
/* In predict.c */
bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e);
+bool cgraph_optimize_for_size_p (struct cgraph_node *);
/* In varpool.c */
extern GTY(()) struct varpool_node *varpool_nodes_queue;
for ((node) = varpool_first_static_initializer (); (node); \
(node) = varpool_next_static_initializer (node))
-/* In ipa-inline.c */
-void cgraph_clone_inlined_nodes (struct cgraph_edge *, bool, bool);
-void compute_inline_parameters (struct cgraph_node *);
+/* Return first function with body defined. */
+static inline struct cgraph_node *
+cgraph_first_defined_function (void)
+{
+ struct cgraph_node *node;
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ if (node->analyzed)
+ return node;
+ }
+ return NULL;
+}
+
+/* Return next reachable static variable with initializer after NODE. */
+static inline struct cgraph_node *
+cgraph_next_defined_function (struct cgraph_node *node)
+{
+ for (node = node->next; node; node = node->next)
+ {
+ if (node->analyzed)
+ return node;
+ }
+ return NULL;
+}
+
+/* Walk all functions with body defined. */
+#define FOR_EACH_DEFINED_FUNCTION(node) \
+ for ((node) = cgraph_first_defined_function (); (node); \
+ (node) = cgraph_next_defined_function (node))
+
+
+/* Return true when NODE is a function with Gimple body defined
+ in current unit. Functions can also be define externally or they
+ can be thunks with no Gimple representation.
+
+ Note that at WPA stage, the function body may not be present in memory. */
+static inline bool
+cgraph_function_with_gimple_body_p (struct cgraph_node *node)
+{
+ return node->analyzed && !node->thunk.thunk_p;
+}
+
+/* Return first function with body defined. */
+static inline struct cgraph_node *
+cgraph_first_function_with_gimple_body (void)
+{
+ struct cgraph_node *node;
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ if (cgraph_function_with_gimple_body_p (node))
+ return node;
+ }
+ return NULL;
+}
+
+/* Return next reachable static variable with initializer after NODE. */
+static inline struct cgraph_node *
+cgraph_next_function_with_gimple_body (struct cgraph_node *node)
+{
+ for (node = node->next; node; node = node->next)
+ {
+ if (cgraph_function_with_gimple_body_p (node))
+ return node;
+ }
+ return NULL;
+}
+
+/* Walk all functions with body defined. */
+#define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \
+ for ((node) = cgraph_first_function_with_gimple_body (); (node); \
+ (node) = cgraph_next_function_with_gimple_body (node))
/* Create a new static variable of type TYPE. */
tree add_new_static_var (tree type);
static inline size_t
cgraph_node_set_size (cgraph_node_set set)
{
- return htab_elements (set->hashtab);
+ return VEC_length (cgraph_node_ptr, set->nodes);
}
/* Return true if iterator VSI points to nothing. */
static inline size_t
varpool_node_set_size (varpool_node_set set)
{
- return htab_elements (set->hashtab);
+ return VEC_length (varpool_node_ptr, set->nodes);
}
/* Uniquize all constants that appear in memory.
/* Constant pool accessor function. */
htab_t constant_pool_htab (void);
+/* Return true when the edge E represents a direct recursion. */
+static inline bool
+cgraph_edge_recursive_p (struct cgraph_edge *e)
+{
+ if (e->caller->global.inlined_to)
+ return e->caller->global.inlined_to->decl == e->callee->decl;
+ else
+ return e->caller->decl == e->callee->decl;
+}
+
/* FIXME: inappropriate dependency of cgraph on IPA. */
#include "ipa-ref-inline.h"