tree-flow.h (find_new_referenced_vars): Add prototype.

2004-09-23  Diego Novillo  <dnovillo@redhat.com>
	    Jakub Jelinek  <jakub@redhat.com>

	* tree-flow.h (find_new_referenced_vars): Add prototype.
	* tree-sra.c (find_new_referenced_vars_1, find_new_referenced_vars):
	Move to...
	* tree-dfa.c (find_new_referenced_vars_1, find_new_referenced_vars):
	... here.
	(mark_new_vars_to_rename): Walk through all operands.
	* tree-ssa-ccp.c (convert_to_gimple_builtin): New function.
	(execute_fold_all_builtins): Use it.
	(pass_fold_builtins): Add TODO_rename_vars to todo_flags_finish.

	* gcc.c-torture/execute/builtins/strcpy-2.c: New test.
	* gcc.c-torture/execute/builtins/strcpy-2-lib.c: New.

From-SVN: r87983
This commit is contained in:
Jakub Jelinek 2004-09-23 23:01:02 +02:00
parent 512baaea75
commit b28b16008e
8 changed files with 134 additions and 30 deletions

View File

@ -1,3 +1,16 @@
2004-09-23 Diego Novillo <dnovillo@redhat.com>
Jakub Jelinek <jakub@redhat.com>
* tree-flow.h (find_new_referenced_vars): Add prototype.
* tree-sra.c (find_new_referenced_vars_1, find_new_referenced_vars):
Move to...
* tree-dfa.c (find_new_referenced_vars_1, find_new_referenced_vars):
... here.
(mark_new_vars_to_rename): Walk through all operands.
* tree-ssa-ccp.c (convert_to_gimple_builtin): New function.
(execute_fold_all_builtins): Use it.
(pass_fold_builtins): Add TODO_rename_vars to todo_flags_finish.
2004-09-23 P.J. Darcy <darcypj@us.ibm.com>
* gthr-tpf.h: New file.

View File

@ -1,3 +1,8 @@
2004-09-23 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/builtins/strcpy-2.c: New test.
* gcc.c-torture/execute/builtins/strcpy-2-lib.c: New.
2004-09-23 Andrew Pinski <pinskia@physics.uc.edu>
PR c++/17618

View File

@ -0,0 +1 @@
#include "lib/strcpy.c"

View File

@ -0,0 +1,47 @@
/* Copyright (C) 2004 Free Software Foundation.
Ensure builtin strcpy is optimized into memcpy
even when there is more than one possible string literal
passed to it, but all string literals passed to it
have equal length.
Written by Jakub Jelinek, 9/15/2004. */
extern void abort (void);
extern char *strcpy (char *, const char *);
typedef __SIZE_TYPE__ size_t;
extern void *memcpy (void *, const void *, size_t);
extern int memcmp (const void *, const void *, size_t);
char buf[32], *p;
int i;
char *
__attribute__((noinline))
test (void)
{
int j;
const char *q = "abcdefg";
for (j = 0; j < 3; ++j)
{
if (j == i)
q = "bcdefgh";
else if (j == i + 1)
q = "cdefghi";
else if (j == i + 2)
q = "defghij";
}
p = strcpy (buf, q);
return strcpy (buf + 16, q);
}
void
main_test (void)
{
#ifndef __OPTIMIZE_SIZE__
/* For -Os, strcpy above is not replaced with
memcpy (buf, q, 8);, as that is larger. */
if (test () != buf + 16 || p != buf)
abort ();
#endif
}

View File

@ -981,9 +981,7 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
v_may_defs_after = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt));
v_must_defs_after = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt));
FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter,
SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF)
FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_ALL_OPERANDS)
{
if (DECL_P (val))
{
@ -1004,3 +1002,27 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
BITMAP_XFREE (vars_in_vops_to_rename);
}
/* Find all variables within the gimplified statement that were not previously
visible to the function and add them to the referenced variables list. */
static tree
find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
void *data ATTRIBUTE_UNUSED)
{
tree t = *tp;
if (TREE_CODE (t) == VAR_DECL && !var_ann (t))
add_referenced_tmp_var (t);
if (IS_TYPE_OR_DECL_P (t))
*walk_subtrees = 0;
return NULL;
}
void
find_new_referenced_vars (tree *stmt_p)
{
walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL);
}

View File

@ -541,6 +541,8 @@ extern void free_df_for_stmt (tree);
extern tree get_virtual_var (tree);
extern void add_referenced_tmp_var (tree var);
extern void mark_new_vars_to_rename (tree, bitmap);
extern void find_new_referenced_vars (tree *);
extern void redirect_immediate_uses (tree, tree);
extern tree make_rename_temp (tree, const char *);

View File

@ -1541,30 +1541,6 @@ generate_element_zero (struct sra_elt *elt, tree *list_p)
}
}
/* Find all variables within the gimplified statement that were not previously
visible to the function and add them to the referenced variables list. */
static tree
find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
void *data ATTRIBUTE_UNUSED)
{
tree t = *tp;
if (TREE_CODE (t) == VAR_DECL && !var_ann (t))
add_referenced_tmp_var (t);
if (IS_TYPE_OR_DECL_P (t))
*walk_subtrees = 0;
return NULL;
}
static inline void
find_new_referenced_vars (tree *stmt_p)
{
walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL);
}
/* Generate an assignment VAR = INIT, where INIT may need gimplification.
Add the result to *LIST_P. */

View File

@ -2099,6 +2099,37 @@ fold_stmt (tree *stmt_p)
}
/* Convert EXPR into a GIMPLE value suitable for substitution on the
RHS of an assignment. Insert the necessary statements before
iterator *SI_P. */
static tree
convert_to_gimple_builtin (block_stmt_iterator *si_p, tree expr)
{
tree_stmt_iterator ti;
tree stmt = bsi_stmt (*si_p);
tree tmp, stmts = NULL;
push_gimplify_context ();
tmp = get_initialized_tmp_var (expr, &stmts, NULL);
pop_gimplify_context (NULL);
/* The replacement can expose previously unreferenced variables. */
for (ti = tsi_start (stmts); !tsi_end_p (ti); tsi_next (&ti))
{
find_new_referenced_vars (tsi_stmt_ptr (ti));
mark_new_vars_to_rename (tsi_stmt (ti), vars_to_rename);
}
if (EXPR_HAS_LOCATION (stmt))
annotate_all_with_locus (&stmts, EXPR_LOCATION (stmt));
bsi_insert_before (si_p, stmts, BSI_SAME_STMT);
return tmp;
}
/* A simple pass that attempts to fold all builtin functions. This pass
is run after we've propagated as many constants as we can. */
@ -2142,8 +2173,13 @@ execute_fold_all_builtins (void)
print_generic_stmt (dump_file, *stmtp, dump_flags);
}
if (set_rhs (stmtp, result))
modify_stmt (*stmtp);
if (!set_rhs (stmtp, result))
{
result = convert_to_gimple_builtin (&i, result);
if (result && !set_rhs (stmtp, result))
abort ();
}
modify_stmt (*stmtp);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@ -2169,6 +2205,8 @@ struct tree_opt_pass pass_fold_builtins =
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */
TODO_dump_func
| TODO_verify_ssa
| TODO_rename_vars, /* todo_flags_finish */
0 /* letter */
};