+2009-05-20 Martin Jambor <mjambor@suse.cz>
+
+ * tree-flow.h (insert_edge_copies_seq): Undeclare.
+ (sra_insert_before): Likewise.
+ (sra_insert_after): Likewise.
+ (sra_init_cache): Likewise.
+ (sra_type_can_be_decomposed_p): Likewise.
+ * tree-mudflap.c (insert_edge_copies_seq): Copied here from tree-sra.c
+ * tree-sra.c (sra_type_can_be_decomposed_p): Made static.
+ (sra_insert_before): Likewise.
+ (sra_insert_after): Likewise.
+ (sra_init_cache): Likewise.
+ (insert_edge_copies_seq): Made static and moved upwards.
+
+ * tree-complex.c (extract_component): Added VIEW_CONVERT_EXPR switch
+ case.
+
+ * tree-flow-inline.h (contains_view_convert_expr_p): New function.
+
+ * ipa-prop.c (get_ssa_def_if_simple_copy): New function.
+ (determine_cst_member_ptr): Call get_ssa_def_if_simple_copy to skip
+ simple copies.
+
2009-05-20 Richard Guenther <rguenther@suse.de>
* expr.c (expand_expr_real_1): Avoid calling do_store_flag
jfunc->value.member_cst.delta = delta;
}
+/* If RHS is an SSA_NAMe and it is defined by a simple copy assign statement,
+ return the rhs of its defining statement. */
+
+static inline tree
+get_ssa_def_if_simple_copy (tree rhs)
+{
+ while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
+ {
+ gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
+
+ if (gimple_assign_single_p (def_stmt))
+ rhs = gimple_assign_rhs1 (def_stmt);
+ }
+ return rhs;
+}
+
/* Traverse statements from CALL backwards, scanning whether the argument ARG
which is a member pointer is filled in with constant values. If it is, fill
the jump function JFUNC in appropriately. METHOD_FIELD and DELTA_FIELD are
fld = TREE_OPERAND (lhs, 1);
if (!method && fld == method_field)
{
+ rhs = get_ssa_def_if_simple_copy (rhs);
if (TREE_CODE (rhs) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (rhs, 0)) == FUNCTION_DECL
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) == METHOD_TYPE)
if (!delta && fld == delta_field)
{
+ rhs = get_ssa_def_if_simple_copy (rhs);
if (TREE_CODE (rhs) == INTEGER_CST)
{
delta = rhs;
case INDIRECT_REF:
case COMPONENT_REF:
case ARRAY_REF:
+ case VIEW_CONVERT_EXPR:
{
tree inner_type = TREE_TYPE (TREE_TYPE (t));
return false;
}
+/* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
+
+static inline bool
+contains_view_convert_expr_p (const_tree ref)
+{
+ while (handled_component_p (ref))
+ {
+ if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
+ return true;
+ ref = TREE_OPERAND (ref, 0);
+ }
+
+ return false;
+}
+
/* Return true, if the two ranges [POS1, SIZE1] and [POS2, SIZE2]
overlap. SIZE1 and/or SIZE2 can be (unsigned)-1 in which case the
range is open-ended. Otherwise return false. */
/* In tree-ssa-sink.c */
bool is_hidden_global_store (gimple);
-/* In tree-sra.c */
-void insert_edge_copies_seq (gimple_seq, basic_block);
-void sra_insert_before (gimple_stmt_iterator *, gimple_seq);
-void sra_insert_after (gimple_stmt_iterator *, gimple_seq);
-void sra_init_cache (void);
-bool sra_type_can_be_decomposed_p (tree);
-
/* In tree-loop-linear.c */
extern void linear_transform_loops (void);
extern unsigned perfect_loop_nest_depth (struct loop *);
return 0;
}
+/* Insert a gimple_seq SEQ on all the outgoing edges out of BB. Note that
+ if BB has more than one edge, STMT will be replicated for each edge.
+ Also, abnormal edges will be ignored. */
+
+static void
+insert_edge_copies_seq (gimple_seq seq, basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+ unsigned n_copies = -1;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (!(e->flags & EDGE_ABNORMAL))
+ n_copies++;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (!(e->flags & EDGE_ABNORMAL))
+ gsi_insert_seq_on_edge (e, n_copies-- > 0 ? gimple_seq_copy (seq) : seq);
+}
+
/* Create and initialize local shadow variables for the lookup cache
globals. Put their decls in the *_l globals for use by
mf_build_check_statement_for. */
instantiated, just that if we decide to break up the type into
separate pieces that it can be done. */
-bool
+static bool
sra_type_can_be_decomposed_p (tree type)
{
unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
return XOBFINISH (&sra_obstack, char *);
}
+/* Insert a gimple_seq SEQ on all the outgoing edges out of BB. Note that
+ if BB has more than one edge, STMT will be replicated for each edge.
+ Also, abnormal edges will be ignored. */
+
+static void
+insert_edge_copies_seq (gimple_seq seq, basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+ unsigned n_copies = -1;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (!(e->flags & EDGE_ABNORMAL))
+ n_copies++;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (!(e->flags & EDGE_ABNORMAL))
+ gsi_insert_seq_on_edge (e, n_copies-- > 0 ? gimple_seq_copy (seq) : seq);
+}
+
/* Instantiate an element as an independent variable. */
static void
return ret;
}
-/* Insert a gimple_seq SEQ on all the outgoing edges out of BB. Note that
- if BB has more than one edge, STMT will be replicated for each edge.
- Also, abnormal edges will be ignored. */
-
-void
-insert_edge_copies_seq (gimple_seq seq, basic_block bb)
-{
- edge e;
- edge_iterator ei;
- unsigned n_copies = -1;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (!(e->flags & EDGE_ABNORMAL))
- n_copies++;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (!(e->flags & EDGE_ABNORMAL))
- gsi_insert_seq_on_edge (e, n_copies-- > 0 ? gimple_seq_copy (seq) : seq);
-}
-
/* Helper function to insert LIST before GSI, and set up line number info. */
-void
+static void
sra_insert_before (gimple_stmt_iterator *gsi, gimple_seq seq)
{
gimple stmt = gsi_stmt (*gsi);
/* Similarly, but insert after GSI. Handles insertion onto edges as well. */
-void
+static void
sra_insert_after (gimple_stmt_iterator *gsi, gimple_seq seq)
{
gimple stmt = gsi_stmt (*gsi);
fputc ('\n', stderr);
}
-void
+static void
sra_init_cache (void)
{
if (sra_type_decomp_cache)