Commit eed8fcad by Olga Golovanevsky Committed by Olga Golovanevsky

re PR tree-optimization/39960 (struct-reorg is broken)

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.

From-SVN: r154374
parent 25bcd7ea
2009-11-20 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.
2009-11-20 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2009-11-20 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* config.gcc (alpha*-dec-osf[45]*): Set use_gcc_stdint. * config.gcc (alpha*-dec-osf[45]*): Set use_gcc_stdint.
...@@ -868,6 +868,7 @@ struct ref_pos ...@@ -868,6 +868,7 @@ struct ref_pos
{ {
tree *pos; tree *pos;
tree ref; tree ref;
tree container;
}; };
...@@ -890,6 +891,7 @@ find_pos_in_stmt_1 (tree *tp, int *walk_subtrees, void * data) ...@@ -890,6 +891,7 @@ find_pos_in_stmt_1 (tree *tp, int *walk_subtrees, void * data)
return t; return t;
} }
r_pos->container = t;
*walk_subtrees = 1; *walk_subtrees = 1;
return NULL_TREE; return NULL_TREE;
} }
...@@ -899,18 +901,18 @@ find_pos_in_stmt_1 (tree *tp, int *walk_subtrees, void * data) ...@@ -899,18 +901,18 @@ find_pos_in_stmt_1 (tree *tp, int *walk_subtrees, void * data)
It returns it, if found, and NULL otherwise. */ It returns it, if found, and NULL otherwise. */
static tree * 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; struct walk_stmt_info wi;
r_pos.ref = ref; r_pos->ref = ref;
r_pos.pos = NULL; r_pos->pos = NULL;
r_pos->container = NULL_TREE;
memset (&wi, 0, sizeof (wi)); memset (&wi, 0, sizeof (wi));
wi.info = &r_pos; wi.info = r_pos;
walk_gimple_op (stmt, find_pos_in_stmt_1, &wi); 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 /* This structure is used to represent array
...@@ -948,6 +950,7 @@ replace_field_acc (struct field_access_site *acc, tree new_type) ...@@ -948,6 +950,7 @@ replace_field_acc (struct field_access_site *acc, tree new_type)
tree field_id = DECL_NAME (acc->field_decl); tree field_id = DECL_NAME (acc->field_decl);
VEC (type_wrapper_t, heap) *wrapper = VEC_alloc (type_wrapper_t, heap, 10); VEC (type_wrapper_t, heap) *wrapper = VEC_alloc (type_wrapper_t, heap, 10);
type_wrapper_t *wr_p = NULL; type_wrapper_t *wr_p = NULL;
struct ref_pos r_pos;
while (TREE_CODE (ref_var) == INDIRECT_REF while (TREE_CODE (ref_var) == INDIRECT_REF
|| TREE_CODE (ref_var) == ARRAY_REF) || TREE_CODE (ref_var) == ARRAY_REF)
...@@ -999,14 +1002,14 @@ replace_field_acc (struct field_access_site *acc, tree new_type) ...@@ -999,14 +1002,14 @@ replace_field_acc (struct field_access_site *acc, tree new_type)
gimple_assign_set_rhs1 (acc->stmt, new_acc); gimple_assign_set_rhs1 (acc->stmt, new_acc);
else 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); gcc_assert (pos);
*pos = new_acc; *pos = new_acc;
} }
} }
else 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); gcc_assert (pos);
*pos = new_acc; *pos = new_acc;
} }
...@@ -1244,6 +1247,35 @@ create_new_stmts_for_cond_expr (gimple stmt) ...@@ -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 /* Create a new general access to replace original access ACC
for structure type NEW_TYPE. */ for structure type NEW_TYPE. */
...@@ -1264,7 +1296,6 @@ create_general_new_stmt (struct access_site *acc, tree 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++) 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 new_var = find_new_var_of_type (var, new_type);
tree lhs, rhs = NULL_TREE; tree lhs, rhs = NULL_TREE;
...@@ -1296,20 +1327,10 @@ create_general_new_stmt (struct access_site *acc, tree new_type) ...@@ -1296,20 +1327,10 @@ create_general_new_stmt (struct access_site *acc, tree new_type)
else if (rhs == var) else if (rhs == var)
gimple_assign_set_rhs1 (new_stmt, new_var); gimple_assign_set_rhs1 (new_stmt, new_var);
else else
{ insert_new_var_in_stmt (new_stmt, var, new_var);
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;
}
} }
else else
{ insert_new_var_in_stmt (new_stmt, var, new_var);
pos = find_pos_in_stmt (new_stmt, var);
gcc_assert (pos);
*pos = new_var;
}
} }
finalize_stmt (new_stmt); finalize_stmt (new_stmt);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment