summaryrefslogtreecommitdiff
path: root/gcc/ipa-struct-reorg.c
diff options
context:
space:
mode:
authorolga <olga@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-20 16:57:35 +0000
committerolga <olga@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-20 16:57:35 +0000
commit751fdddd8e2693313c51bcf0f9ed3dc061dcd74e (patch)
treee6ccd08cacdf089b387b9ee04bd12d0dbcecc98c /gcc/ipa-struct-reorg.c
parent3aba59117bfa9c0a7397fdf6f17a1b85bf980685 (diff)
downloadgcc-751fdddd8e2693313c51bcf0f9ed3dc061dcd74e.tar.gz
2009-11-17 Olga Golovanevsky <olga@il.ibm.com>
PR middle-end/39960 * ipa-struct-reorg.c (find_pos_in_stmt): New parameter. (ref_pos): New field in structure. (insert_new_var_in_stmt): New function. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154374 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-struct-reorg.c')
-rw-r--r--gcc/ipa-struct-reorg.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/gcc/ipa-struct-reorg.c b/gcc/ipa-struct-reorg.c
index 65777f59394..d2187b82b99 100644
--- a/gcc/ipa-struct-reorg.c
+++ b/gcc/ipa-struct-reorg.c
@@ -868,6 +868,7 @@ struct ref_pos
{
tree *pos;
tree ref;
+ tree container;
};
@@ -890,6 +891,7 @@ find_pos_in_stmt_1 (tree *tp, int *walk_subtrees, void * data)
return t;
}
+ r_pos->container = t;
*walk_subtrees = 1;
return NULL_TREE;
}
@@ -899,18 +901,18 @@ find_pos_in_stmt_1 (tree *tp, int *walk_subtrees, void * data)
It returns it, if found, and NULL otherwise. */
static tree *
-find_pos_in_stmt (gimple stmt, tree ref)
+find_pos_in_stmt (gimple stmt, tree ref, struct ref_pos * r_pos)
{
- struct ref_pos r_pos;
struct walk_stmt_info wi;
- r_pos.ref = ref;
- r_pos.pos = NULL;
+ r_pos->ref = ref;
+ r_pos->pos = NULL;
+ r_pos->container = NULL_TREE;
memset (&wi, 0, sizeof (wi));
- wi.info = &r_pos;
+ wi.info = r_pos;
walk_gimple_op (stmt, find_pos_in_stmt_1, &wi);
- return r_pos.pos;
+ return r_pos->pos;
}
/* This structure is used to represent array
@@ -948,6 +950,7 @@ replace_field_acc (struct field_access_site *acc, tree new_type)
tree field_id = DECL_NAME (acc->field_decl);
VEC (type_wrapper_t, heap) *wrapper = VEC_alloc (type_wrapper_t, heap, 10);
type_wrapper_t *wr_p = NULL;
+ struct ref_pos r_pos;
while (TREE_CODE (ref_var) == INDIRECT_REF
|| TREE_CODE (ref_var) == ARRAY_REF)
@@ -999,14 +1002,14 @@ replace_field_acc (struct field_access_site *acc, tree new_type)
gimple_assign_set_rhs1 (acc->stmt, new_acc);
else
{
- pos = find_pos_in_stmt (acc->stmt, acc->comp_ref);
+ pos = find_pos_in_stmt (acc->stmt, acc->comp_ref, &r_pos);
gcc_assert (pos);
*pos = new_acc;
}
}
else
{
- pos = find_pos_in_stmt (acc->stmt, acc->comp_ref);
+ pos = find_pos_in_stmt (acc->stmt, acc->comp_ref, &r_pos);
gcc_assert (pos);
*pos = new_acc;
}
@@ -1244,6 +1247,35 @@ create_new_stmts_for_cond_expr (gimple stmt)
}
}
+/* This function looks for VAR in STMT, and replace it with NEW_VAR.
+ If needed, it wraps NEW_VAR in pointers and indirect references
+ before insertion. */
+
+static void
+insert_new_var_in_stmt (gimple stmt, tree var, tree new_var)
+{
+ struct ref_pos r_pos;
+ tree *pos;
+
+ pos = find_pos_in_stmt (stmt, var, &r_pos);
+ gcc_assert (pos);
+
+ while (r_pos.container && (TREE_CODE(r_pos.container) == INDIRECT_REF
+ || TREE_CODE(r_pos.container) == ADDR_EXPR))
+ {
+ tree type = TREE_TYPE (TREE_TYPE (new_var));
+
+ if (TREE_CODE(r_pos.container) == INDIRECT_REF)
+ new_var = build1 (INDIRECT_REF, type, new_var);
+ else
+ new_var = build_fold_addr_expr (new_var);
+ pos = find_pos_in_stmt (stmt, r_pos.container, &r_pos);
+ }
+
+ *pos = new_var;
+}
+
+
/* Create a new general access to replace original access ACC
for structure type NEW_TYPE. */
@@ -1264,7 +1296,6 @@ create_general_new_stmt (struct access_site *acc, tree new_type)
for (i = 0; VEC_iterate (tree, acc->vars, i, var); i++)
{
- tree *pos;
tree new_var = find_new_var_of_type (var, new_type);
tree lhs, rhs = NULL_TREE;
@@ -1296,20 +1327,10 @@ create_general_new_stmt (struct access_site *acc, tree new_type)
else if (rhs == var)
gimple_assign_set_rhs1 (new_stmt, new_var);
else
- {
- pos = find_pos_in_stmt (new_stmt, var);
- gcc_assert (pos);
- /* ??? This misses adjustments to the type of the
- INDIRECT_REF we possibly replace the operand of. */
- *pos = new_var;
- }
+ insert_new_var_in_stmt (new_stmt, var, new_var);
}
else
- {
- pos = find_pos_in_stmt (new_stmt, var);
- gcc_assert (pos);
- *pos = new_var;
- }
+ insert_new_var_in_stmt (new_stmt, var, new_var);
}
finalize_stmt (new_stmt);