[middle-end, patch 3/9] Make ipa-cp analyze only required no…

Top Page

Reply to this message
Author: Martin Jambor
Date:  
To: GCC Patches
CC: Jan Hubicka, Kenneth Zadeck, Razya Ladelsky
Subject: [middle-end, patch 3/9] Make ipa-cp analyze only required nodes
This patch makes ipa-cp to only look at nodes that comply with the
predicate:
((NODE)->analyzed && ((NODE)->needed || (NODE)->reachable))

Looking at others should not be necessary. This way ipa-cp also
examines the same nodes ipa-inline does. Similar conditions are
widely used across ipa passes and possibly should be unified and moved
elsewhere else (as I have pointed out in an email about a month) but
so far I duplicate it here.

This patch also makes debug dumping functions check that infos are
allocated for the node and/or edges they examine.


2008-07-03 Martin Jambor <mjambor@???>

    * ipa-cp.c (ipcp_driver): Calling check-and-allocate functions rather
    than direct allocation function.
    (ipcp_init_stage): Check that nodes are relevant.
    (ipcp_insert_stage): Check that the node is relevant. Check there is
    an info for every node and edge.
    (ipcp_update_callgraph): Check that the node is relevant.
    (ipcp_propagate_stage): Check on the side arrays are properly
    allocated.
    (ipcp_print_all_jump_functions): Make sure not to touch anything
    outside of the on-the-side arrays.
    (ipcp_function_scale_print): Make sure not to touch anything outside
    of the on-the-side arrays.
    (ipcp_print_all_lattices): Make sure not to touch anything outside
    of the on-the-side arrays.

    * ipa-prop.c: (ipa_init_func_list): Check the functions are relevant.

    * ipa-prop.h (ipa_node_params_info_available_for_node_p): New function.
    (ipa_edge_args_info_available_for_edge_p): New function.
    (IPA_NODE_RELEVANT_P): New macro.


Index: iinln/gcc/ipa-cp.c
===================================================================
--- iinln.orig/gcc/ipa-cp.c
+++ iinln/gcc/ipa-cp.c
@@ -293,7 +293,11 @@ ipcp_print_all_lattices (FILE * f)
fprintf (f, "\nLATTICE PRINT\n");
for (node = cgraph_nodes; node; node = node->next)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ struct ipa_node_params *info;
+
+ if (!ipa_node_params_info_available_for_node_p (node))
+    continue;
+ info = IPA_NODE_REF (node);
fprintf (f, "Printing lattices %s:\n", cgraph_node_name (node));
count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
@@ -413,6 +417,8 @@ ipcp_init_stage (void)

for (node = cgraph_nodes; node; node = node->next)
{
+ if (!IPA_NODE_RELEVANT_P (node))
+    continue;
ipa_count_formal_params (node);
ipa_create_param_decls_array (node);
ipcp_initialize_node_lattices (node);
@@ -421,9 +427,13 @@ ipcp_init_stage (void)
}
for (node = cgraph_nodes; node; node = node->next)
{
+ if (!IPA_NODE_RELEVANT_P (node))
+    continue;
/* building jump functions */
for (cs = node->callees; cs; cs = cs->next_callee)
    {
+     if (!IPA_NODE_RELEVANT_P (cs->callee))
+     continue;
     ipa_count_arguments (cs);
     if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
     != ipa_get_param_count (IPA_NODE_REF (cs->callee)))
@@ -480,6 +490,8 @@ ipcp_propagate_stage (void)
struct ipa_func_list *wl;
int count;

+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
/* Initialize worklist to contain all functions. */
wl = ipa_init_func_list ();
while (wl)
@@ -550,12 +562,16 @@ ipcp_print_all_jump_functions (FILE * f)
fprintf (f, "\nCALLSITE PARAM PRINT\n");
for (node = cgraph_nodes; node; node = node->next)
{
+ if (!ipa_node_params_info_available_for_node_p (node))
+    continue;
+
for (cs = node->callees; cs; cs = cs->next_callee)
    {
     fprintf (f, "callsite %s ", cgraph_node_name (node));
     fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));

-     if (ipa_is_called_with_var_arguments (IPA_NODE_REF (cs->callee)))
+     if (!ipa_edge_args_info_available_for_edge_p (cs)
+     || ipa_is_called_with_var_arguments (IPA_NODE_REF (cs->callee)))
     continue;

     count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
@@ -592,6 +608,8 @@ ipcp_function_scale_print (FILE * f)

for (node = cgraph_nodes; node; node = node->next)
{
+ if (!ipa_node_params_info_available_for_node_p (node))
+    continue;
fprintf (f, "printing scale for %s: ", cgraph_node_name (node));
fprintf (f, "value is " HOST_WIDE_INT_PRINT_DEC
     " \n", (HOST_WIDE_INT) ipcp_get_node_scale (node));
@@ -820,7 +838,7 @@ ipcp_update_callgraph (void)
for (node = cgraph_nodes; node; node = node->next)
{
/* want to fix only original nodes */
- if (ipcp_node_is_clone (node))
+ if (!IPA_NODE_RELEVANT_P (node) || ipcp_node_is_clone (node))
    continue;
for (cs = node->callees; cs; cs = cs->next_callee)
    if (ipcp_node_is_clone (cs->callee))
@@ -906,13 +924,17 @@ ipcp_insert_stage (void)
tree parm_tree;
struct ipa_replace_map *replace_param;

+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
+
for (node = cgraph_nodes; node; node = node->next)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
- /* Propagation of the constant is forbidden in
- certain conditions. */
- if (!node->analyzed || ipcp_node_not_modifiable_p (node)
-     || ipa_is_called_with_var_arguments (info))
+ struct ipa_node_params *info;
+ /* Propagation of the constant is forbidden in certain conditions. */
+ if (!IPA_NODE_RELEVANT_P (node) || ipcp_node_not_modifiable_p (node))
+     continue;
+ info = IPA_NODE_REF (node);
+ if (ipa_is_called_with_var_arguments (info))
    continue;
const_param = 0;
count = ipa_get_param_count (info);
@@ -998,8 +1020,8 @@ ipcp_driver (void)
{
if (dump_file)
fprintf (dump_file, "\nIPA constant propagation start:\n");
- ipa_create_all_node_params ();
- ipa_create_all_edge_args ();
+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
ipa_register_cgraph_hooks ();
/* 1. Call the init stage to initialize
the ipa_node_params and ipa_edge_args structures. */
Index: iinln/gcc/ipa-prop.c
===================================================================
--- iinln.orig/gcc/ipa-prop.c
+++ iinln/gcc/ipa-prop.c
@@ -61,7 +61,8 @@ ipa_init_func_list (void)

wl = NULL;
for (node = cgraph_nodes; node; node = node->next)
- ipa_push_func_to_list (&wl, node);
+ if (IPA_NODE_RELEVANT_P (node))
+    ipa_push_func_to_list (&wl, node);

return wl;
}
@@ -557,7 +558,11 @@ ipa_print_all_tree_maps (FILE * f)
fprintf (f, "\nPARAM TREE MAP PRINT\n");
for (node = cgraph_nodes; node; node = node->next)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ struct ipa_node_params *info;
+
+ if (!ipa_node_params_info_available_for_node_p (node))
+    continue;
+ info = IPA_NODE_REF (node);
fprintf (f, "function %s Trees :: \n", cgraph_node_name (node));
count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
@@ -583,7 +588,11 @@ ipa_print_all_params_modified (FILE * f)
fprintf (f, "\nMODIFY PRINT\n");
for (node = cgraph_nodes; node; node = node->next)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ struct ipa_node_params *info;
+
+ if (!ipa_node_params_info_available_for_node_p (node))
+    continue;
+ info = IPA_NODE_REF (node);
fprintf (f, "function %s :: \n", cgraph_node_name (node));
count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
Index: iinln/gcc/ipa-prop.h
===================================================================
--- iinln.orig/gcc/ipa-prop.h
+++ iinln/gcc/ipa-prop.h
@@ -237,6 +237,9 @@ extern struct ipa_edge_args *ipa_edge_ar
/* This macro checks validity of index returned by
ipa_get_param_decl_index function. */
#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)
+/* Should various ipa passes even look at the function given by NODE? */
+#define IPA_NODE_RELEVANT_P(NODE)        \
+ ((NODE)->analyzed && ((NODE)->needed || (NODE)->reachable))

/* Creating and freeing ipa_node_params and ipa_edge_args. */
void ipa_create_all_node_params (void);
@@ -266,6 +269,24 @@ ipa_check_create_edge_args (void)
ipa_create_all_edge_args ();
}

+/* Returns true if the array of node infos is large enough to accomodate an
+ info for NODE. The main purpose of this function is that debug dumping
+ function can check info availability without causing reallocations. */
+static inline bool
+ipa_node_params_info_available_for_node_p (struct cgraph_node *node)
+{
+ return (node->uid < ipa_node_params_array_size);
+}
+
+/* Returns true if the array of edge infos is large enough to accomodate an
+ info for EDGE. The main purpose of this function is that debug dumping
+ function can check info availability without causing reallocations. */
+static inline bool
+ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
+{
+ return (edge->uid < ipa_edge_args_array_size);
+}
+
/* 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

--