diff options
author | olga <olga@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-20 16:57:35 +0000 |
---|---|---|
committer | olga <olga@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-20 16:57:35 +0000 |
commit | 751fdddd8e2693313c51bcf0f9ed3dc061dcd74e (patch) | |
tree | e6ccd08cacdf089b387b9ee04bd12d0dbcecc98c /gcc/ipa-struct-reorg.c | |
parent | 3aba59117bfa9c0a7397fdf6f17a1b85bf980685 (diff) | |
download | gcc-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.c | 63 |
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); |