Author: Martin Jambor Date: To: GCC Patches CC: Jan Hubicka, Kenneth Zadeck, Razya Ladelsky Subject: [middle-end, patch 4/9] Overhaul of modification analysis
This patch is a rewrite of modification analysis done by ipa-cp. It
is not really crucial for ipa-cp itself but is hopefully cleaner and
has extended capabilities required for indirect inlining. In
particular, it does not mark all addressable parameters as modified
but only those that are really modified or their address was
explicitly taken in the given function. This is necessary so that we
do not consider all member pointers modified.
2008-07-03 Martin Jambor <mjambor@???>
* ipa-prop.h (struct ipa_param_flags): New structure.
(struct ipa_node_params): New field modification_analysis_done,
modified_flags changed into param_flags.
(ipa_is_ith_param_modified): Changed to use new flags.
* ipa-prop.c: Include diagnostic.h.
(ipa_detect_param_modifications): Don't care about function
inlinability or parameter addressability.
(ipa_check_stmt_modifications): Check GIMPLE_MODIFY_EXPRs properly,
check calls, changed formal parameters.
(ipa_check_call_modifications): New function.
(ipa_check_operand_modifications): New function.
(ipa_compute_jump_functions): Changed accesses to modification flags.
(ipa_node_duplication_hook): Update flags duplication.
(ipa_free_node_params_substructures): Update flags destruction.
* ipa-cp.c (ipcp_initialize_node_lattices): Initialize lattices to
bottom if the function is not inlinable.
/* Create a new assignment statement and make it the first statement in the
Index: iinln/gcc/ipa-prop.c
===================================================================
--- iinln.orig/gcc/ipa-prop.c
+++ iinln/gcc/ipa-prop.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.
#include "flags.h"
#include "timevar.h"
#include "flags.h"
+#include "diagnostic.h"
/* To avoid frequent reallocation the size of arrays is greater than needed,
the number of elements is (not less than) 1.25 * size_wanted. */
@@ -149,95 +150,134 @@ ipa_count_formal_params (struct cgraph_n
ipa_set_param_count (IPA_NODE_REF (mt), param_num);
}
-/* Check STMT to detect whether a formal is modified within MT, the appropriate
- entry is updated in the modified_flags array of ipa_node_params (associated
- with MT). */
+/* This function checks whether OP which is an operand of an expression on the
+ right hand side of a modify statement or an argument of call expr takes an
+ address of a parameter of the function characterized by INFO. If it does,
+ the parameter is marked as modified. */
static void
-ipa_check_stmt_modifications (struct cgraph_node *mt, tree stmt)
+ipa_check_operand_modifications (struct ipa_node_params *info, tree op)
{
- int index, j;
- tree parm_decl;
- struct ipa_node_params *info;
+ while (UNARY_CLASS_P (op)
+ || TREE_CODE (op) == TRUTH_NOT_EXPR)
+ op = TREE_OPERAND (op, 0);
+
+ if (TREE_CODE (op) == ADDR_EXPR)
+ {
+ int index;
+
+ op = TREE_OPERAND (op, 0);
+ while (handled_component_p (op))
+ op = TREE_OPERAND (op, 0);
+ index = ipa_get_param_decl_index (info, op);
+ if (index >= 0)
+ info->param_flags[index].modified = true;
+ }
+}
+
+/* Check whether any of the arguments passed in a CALL is an ADDR_EXPR and if
+ yes, marked it as modified. INFO is characterizes the callers formal
+ parameters. */
+static void
+ipa_check_call_modifications (struct ipa_node_params *info, tree call)
+{
+ call_expr_arg_iterator iter;
+ tree arg;
+
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, call)
+ ipa_check_operand_modifications (info, arg);
+}
+
+/* Check STMT to detect whether a formal parameter is modified within NODE, the
+ appropriate entry is updated in the modified flags of INFO. */
+static void
+ipa_check_stmt_modifications (struct ipa_node_params *info, tree stmt)
+{
+ int j;
+ int index;
+ tree lhs;
+ tree rhs;
-/* The modify computation driver for MT. Compute which formal arguments
- of function MT are locally modified. Formals may be modified in MT
- if their address is taken, or if
- they appear on the left hand side of an assignment. */
-void
-ipa_detect_param_modifications (struct cgraph_node *mt)
-{
- tree decl;
- tree body;
- int j, count;
+/* Compute which formal parameters of function associated with NODE are locally
+ modified. Parameters may be modified in NODE if their address is taken, or
+ if they appear on the left hand side of an assignment. */
+void
+ipa_detect_param_modifications (struct cgraph_node *node)
+{
+ tree decl = node->decl;
basic_block bb;
struct function *func;
block_stmt_iterator bsi;
- tree stmt, parm_tree;
- struct ipa_node_params *info = IPA_NODE_REF (mt);
+ tree stmt;
+ struct ipa_node_params *info = IPA_NODE_REF (node);
+/* ipa_param_flags contains various flags that describe how the associated
+ parameter is treated within a function. */
+struct ipa_param_flags
+{
+ /* Whether the value parameter has been modified within the function. */
+ unsigned modified : 1;
+
+};
+
/* 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). */
@@ -114,8 +123,8 @@ struct ipa_node_params
struct ipcp_lattice *ipcp_lattices;
/* Mapping each parameter to its PARM_DECL tree. */
tree *param_decls;
- /* Indicating which parameter is modified in its function. */
- bool *modified_flags;
+ /* Various flags describing individual parameters. */
+ struct ipa_param_flags *param_flags;
/* 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;
@@ -129,6 +138,8 @@ struct ipa_node_params
/* Whether this function is called with variable number of actual
arguments. */
unsigned called_with_var_arguments : 1;
+ /* Whether the modification analysis has already been performed. */
+ unsigned modification_analysis_done : 1;
};
/* ipa_node_params access functions. Please use these to access fields that
@@ -163,7 +174,7 @@ ipa_get_ith_param (struct ipa_node_param
static inline bool
ipa_is_ith_param_modified (struct ipa_node_params *info, int i)
{
- return info->modified_flags[i];
+ return info->param_flags[i].modified;
}
/* Flag this node as having callers with variable number of arguments. */