mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-02 16:23:56 +08:00
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:
parent
512baaea75
commit
b28b16008e
@ -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.
|
||||
|
@ -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
|
||||
|
@ -0,0 +1 @@
|
||||
#include "lib/strcpy.c"
|
47
gcc/testsuite/gcc.c-torture/execute/builtins/strcpy-2.c
Normal file
47
gcc/testsuite/gcc.c-torture/execute/builtins/strcpy-2.c
Normal 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
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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 */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user