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
This commit is contained in:
Olga Golovanevsky 2009-11-20 16:57:35 +00:00 committed by Olga Golovanevsky
parent 25bcd7ea32
commit eed8fcad82
2 changed files with 50 additions and 21 deletions

View file

@ -1,3 +1,11 @@
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>
* config.gcc (alpha*-dec-osf[45]*): Set use_gcc_stdint.

View file

@ -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);