This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [tree-ssa] preliminary l-i reorganization patch
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 10 Aug 2002 01:43:59 +0100
- Subject: Re: [tree-ssa] preliminary l-i reorganization patch
- References: <wvlznvwlyw8.fsf@prospero.cambridge.redhat.com>
On Fri, 09 Aug 2002 18:34:15 +0100, Jason Merrill <jason@redhat.com> wrote:
> This patch, which I'm not checking in, does the bits of reorganization
> which can be done without actually changing the target language from C
> trees to language-independent trees. It:
>
> 1) Changes the language hook from simplify_function_tree to simplify_expr,
> and splits out c_simplify_expr from simplify_expr.
> 2) Moves the simplification code for l-i trees to tree-simple.c, and
> is_simple tests for C trees to c-simplify.c. This is not complete, as
> some of the code for simplifying l-i trees creates C-specific trees.
Here's a patch which I am checking in, which only does #1. Tested
i686-pc-linux-gnu.
2002-08-09 Jason Merrill <jason@redhat.com>
* langhooks-def.h: Replace the simplify_function_tree hook
with a simplify_expr hook.
* langhooks.h: Likewise.
* langhooks.c: Replace lhd_simplify_function_tree with
lhd_simplify_expr.
* c-lang.c (LANG_HOOKS_SIMPLIFY_FUNCTION_TREE): Don't define.
(LANG_HOOKS_SIMPLIFY_EXPR): Define.
* c-decl.c (c_expand_body): De-hook simplify_function_tree.
* c-common.h: Declare c_simplify_expr.
* c-simplify.c (simplify_function_tree): Rename from
c_simplify_function_tree. Call simplify_expr instead of
simplify_stmt.
(c_simplify_expr): Split out from...
(simplify_expr): ...here. No longer static. Call langhook.
(is_simple_decl_stmt): Move here from tree-simple.c.
* tree-simple.c: Don't include c-tree.h.
(is_simple_stmt, is_simple_compstmt): Remove.
(is_simple_decl_stmt): Move to c-simplify.c.
* tree.h: Declare simplify_function_tree.
* tree-simple.h: Declare simplify_expr, add_tree.
* tree-simple.c (rationalize_compound_expr): New fn.
cp/:
* cp-simplify.c (cp_simplify_expr): New fn.
(simplify_target_expr): New fn.
(cp_simplify_function_tree): Remove.
* cp-lang.c (LANG_HOOKS_SIMPLIFY_FUNCTION_TREE): Don't define.
(LANG_HOOKS_SIMPLIFY_EXPR): Define.
* optimize.c (optimize_function): De-hook simplify_function_tree.
* cp-tree.h: Declare cp_simplify_expr.
Index: gcc/c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.141.2.3
diff -c -p -r1.141.2.3 c-common.h
*** gcc/c-common.h 5 Aug 2002 18:14:08 -0000 1.141.2.3
--- gcc/c-common.h 9 Aug 2002 22:38:05 -0000
*************** extern void dump_time_statistics PARAMS
*** 1225,1228 ****
--- 1225,1230 ----
extern int c_dump_tree PARAMS ((void *, tree));
+ extern int c_simplify_expr PARAMS ((tree *, tree *, tree *));
+
#endif /* ! GCC_C_COMMON_H */
Index: gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.334.2.6
diff -c -p -r1.334.2.6 c-decl.c
*** gcc/c-decl.c 5 Aug 2002 18:14:08 -0000 1.334.2.6
--- gcc/c-decl.c 9 Aug 2002 22:38:09 -0000
*************** c_expand_body (fndecl, nested_p, can_def
*** 6713,6719 ****
/* Simplify the function. Don't try to optimize the function if
simplification failed. */
if (!flag_disable_simple
! && (*lang_hooks.simplify_function_tree) (fndecl))
{
/* Invoke the SSA tree optimizer. */
if (flag_tree_ssa)
--- 6713,6719 ----
/* Simplify the function. Don't try to optimize the function if
simplification failed. */
if (!flag_disable_simple
! && simplify_function_tree (fndecl))
{
/* Invoke the SSA tree optimizer. */
if (flag_tree_ssa)
Index: gcc/c-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lang.c,v
retrieving revision 1.94.2.2
diff -c -p -r1.94.2.2 c-lang.c
*** gcc/c-lang.c 31 Jul 2002 18:07:16 -0000 1.94.2.2
--- gcc/c-lang.c 9 Aug 2002 22:38:09 -0000
*************** static void c_init_options PARAMS ((void
*** 114,122 ****
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
/* Hooks for tree simplification. */
! #undef LANG_HOOKS_SIMPLIFY_FUNCTION_TREE
! #define LANG_HOOKS_SIMPLIFY_FUNCTION_TREE \
! c_simplify_function_tree
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
--- 114,121 ----
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
/* Hooks for tree simplification. */
! #undef LANG_HOOKS_SIMPLIFY_EXPR
! #define LANG_HOOKS_SIMPLIFY_EXPR c_simplify_expr
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
Index: gcc/c-simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-simplify.c,v
retrieving revision 1.1.4.9
diff -c -p -r1.1.4.9 c-simplify.c
*** gcc/c-simplify.c 7 Aug 2002 16:02:57 -0000 1.1.4.9
--- gcc/c-simplify.c 9 Aug 2002 22:38:10 -0000
*************** Software Foundation, 59 Temple Place - S
*** 61,67 ****
static void simplify_stmt PARAMS ((tree *));
static void simplify_expr_stmt PARAMS ((tree, tree *, tree *));
static void simplify_decl_stmt PARAMS ((tree, tree *, tree *, tree *));
- static void simplify_constructor PARAMS ((tree, tree *, tree *));
static void maybe_fixup_loop_cond PARAMS ((tree *, tree *, tree *));
static void simplify_for_stmt PARAMS ((tree, tree *));
static void simplify_while_stmt PARAMS ((tree, tree *));
--- 61,66 ----
*************** static void simplify_do_stmt PAR
*** 69,100 ****
static void simplify_if_stmt PARAMS ((tree, tree *));
static void simplify_switch_stmt PARAMS ((tree, tree *));
static void simplify_return_stmt PARAMS ((tree, tree *));
- typedef enum fallback_t {
- fb_rvalue=1,
- fb_lvalue=2,
- fb_either=1|2
- } fallback_t;
- static void simplify_expr PARAMS ((tree *, tree *, tree *,
- int (*) PARAMS ((tree)),
- fallback_t));
- static void simplify_array_ref PARAMS ((tree *, tree *, tree *));
- static void simplify_compound_lval PARAMS ((tree *, tree *, tree *));
- static void simplify_self_mod_expr PARAMS ((tree *, tree *, tree *));
- static void simplify_component_ref PARAMS ((tree *, tree *, tree *));
- static void simplify_call_expr PARAMS ((tree *, tree *, tree *));
- static void simplify_tree_list PARAMS ((tree *, tree *, tree *));
- static void simplify_cond_expr PARAMS ((tree *, tree *));
- static void simplify_modify_expr PARAMS ((tree *, tree *, tree *));
- static void simplify_boolean_expr PARAMS ((tree *, tree *));
- static void simplify_compound_expr PARAMS ((tree *, tree *, tree *));
- static void simplify_expr_wfl PARAMS ((tree *, tree *, tree *,
- int (*) PARAMS ((tree))));
- static void simplify_save_expr PARAMS ((tree *, tree *));
static void simplify_stmt_expr PARAMS ((tree *, tree *));
static void simplify_compound_literal_expr PARAMS ((tree *, tree *, tree *));
- static void simplify_addr_expr PARAMS ((tree *, tree *, tree *));
static void make_type_writable PARAMS ((tree));
- static tree add_tree PARAMS ((tree, tree *));
static tree insert_before_continue PARAMS ((tree, tree));
static tree tree_last_decl PARAMS ((tree));
static int stmt_has_effect PARAMS ((tree));
--- 68,76 ----
*************** static int expr_has_effect PAR
*** 102,111 ****
static tree mostly_copy_tree_r PARAMS ((tree *, int *, void *));
static inline void remove_suffix PARAMS ((char *, int));
static const char *get_name PARAMS ((tree));
- static tree build_addr_expr PARAMS ((tree));
static int is_last_stmt_of_scope PARAMS ((tree));
static tree tail_expression PARAMS ((tree *, int));
/* Local variables. */
static FILE *dump_file;
static int dump_flags;
--- 78,105 ----
static tree mostly_copy_tree_r PARAMS ((tree *, int *, void *));
static inline void remove_suffix PARAMS ((char *, int));
static const char *get_name PARAMS ((tree));
static int is_last_stmt_of_scope PARAMS ((tree));
static tree tail_expression PARAMS ((tree *, int));
+ /* Should move to tree-simple.c when the target language loses the C-isms. */
+ static void simplify_constructor PARAMS ((tree, tree *, tree *));
+ static void simplify_array_ref PARAMS ((tree *, tree *, tree *));
+ static void simplify_compound_lval PARAMS ((tree *, tree *, tree *));
+ static void simplify_component_ref PARAMS ((tree *, tree *, tree *));
+ static void simplify_call_expr PARAMS ((tree *, tree *, tree *));
+ static void simplify_tree_list PARAMS ((tree *, tree *, tree *));
+ static void simplify_modify_expr PARAMS ((tree *, tree *, tree *));
+ static void simplify_compound_expr PARAMS ((tree *, tree *, tree *));
+ static void simplify_save_expr PARAMS ((tree *, tree *));
+ static void simplify_addr_expr PARAMS ((tree *, tree *, tree *));
+ static void simplify_self_mod_expr PARAMS ((tree *, tree *, tree *));
+ static void simplify_cond_expr PARAMS ((tree *, tree *));
+ static void simplify_boolean_expr PARAMS ((tree *, tree *));
+ static void simplify_expr_wfl PARAMS ((tree *, tree *, tree *,
+ int (*) (tree)));
+ static tree build_addr_expr PARAMS ((tree));
+
+
/* Local variables. */
static FILE *dump_file;
static int dump_flags;
*************** static int dump_flags;
*** 116,122 ****
node for the function we want to simplify. */
int
! c_simplify_function_tree (fndecl)
tree fndecl;
{
tree fnbody;
--- 110,116 ----
node for the function we want to simplify. */
int
! simplify_function_tree (fndecl)
tree fndecl;
{
tree fnbody;
*************** c_simplify_function_tree (fndecl)
*** 149,155 ****
pushlevel (0);
/* Simplify the function's body. */
! simplify_stmt (&fnbody);
/* Declare the new temporary variables. */
declare_tmp_vars (getdecls(), fnbody);
--- 143,149 ----
pushlevel (0);
/* Simplify the function's body. */
! simplify_expr (&fnbody, NULL, NULL, NULL, fb_rvalue);
/* Declare the new temporary variables. */
declare_tmp_vars (getdecls(), fnbody);
*************** simplify_compound_literal_expr (expr_p,
*** 1041,1047 ****
bit is set, an rvalue is OK. If the 2 bit is set, an lvalue is OK.
If both are set, either is OK, but an lvalue is preferable. */
! static void
simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
tree *expr_p;
tree *pre_p;
--- 1035,1041 ----
bit is set, an rvalue is OK. If the 2 bit is set, an lvalue is OK.
If both are set, either is OK, but an lvalue is preferable. */
! void
simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
tree *expr_p;
tree *pre_p;
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 1051,1056 ****
--- 1045,1060 ----
{
tree tmp;
tree internal_post = NULL_TREE;
+ int done;
+
+ if (pre_p == NULL)
+ {
+ /* Temporary kludge: If pre_p is null, this is a statement. Hand off
+ to the C-specific code. Soon we will have a l-i notion of
+ statements. */
+ (*lang_hooks.simplify_expr) (expr_p, pre_p, post_p);
+ return;
+ }
if (simple_test_f == NULL)
abort ();
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 1062,1070 ****
if (post_p == NULL)
post_p = &internal_post;
! /* First deal with the special cases. */
! switch (TREE_CODE (*expr_p))
{
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
case PREINCREMENT_EXPR:
--- 1066,1080 ----
if (post_p == NULL)
post_p = &internal_post;
! /* First do any language-specific simplification. */
! done = (*lang_hooks.simplify_expr) (expr_p, pre_p, post_p);
!
! if (done)
! /* The frontend completely simplified this node. */;
! else switch (TREE_CODE (*expr_p))
{
+ /* First deal with the special cases. */
+
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
case PREINCREMENT_EXPR:
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 1154,1172 ****
case COMPLEX_CST:
break;
- case COMPOUND_LITERAL_EXPR:
- simplify_compound_literal_expr (expr_p, pre_p, post_p);
- break;
-
case CONSTRUCTOR:
simplify_constructor (*expr_p, pre_p, post_p);
break;
/* The following are special cases that are not handled by the original
SIMPLE grammar. */
- case STMT_EXPR:
- simplify_stmt_expr (expr_p, pre_p);
- break;
/* SAVE_EXPR nodes are converted into a SIMPLE identifier and
eliminated. */
--- 1164,1175 ----
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 1271,1276 ****
--- 1274,1309 ----
add_tree (internal_post, pre_p);
}
+ /* Do C-specific simplification. Args are as for simplify_expr. */
+
+ int
+ c_simplify_expr (expr_p, pre_p, post_p)
+ tree *expr_p;
+ tree *pre_p;
+ tree *post_p;
+ {
+ if (pre_p == NULL)
+ {
+ simplify_stmt (expr_p);
+ return 1;
+ }
+
+ switch (TREE_CODE (*expr_p))
+ {
+ case COMPOUND_LITERAL_EXPR:
+ simplify_compound_literal_expr (expr_p, pre_p, post_p);
+ return 1;
+ break;
+
+ case STMT_EXPR:
+ simplify_stmt_expr (expr_p, pre_p);
+ return 1;
+ break;
+ }
+
+ return 0;
+ }
+
/* Build an expression for the address of T. Folds away INDIRECT_REF to
avoid confusing the simplify process. */
*************** simplify_addr_expr (expr_p, pre_p, post_
*** 1995,2001 ****
{
/* Fold &*EXPR into EXPR and simplify EXPR into a legal argument for
ADDR_EXPR. Notice that we need to request an rvalue because EXPR is
! already the lvalue that we were looking for originally. */
*expr_p = TREE_OPERAND (TREE_OPERAND (*expr_p, 0), 0);
simplify_expr (expr_p, pre_p, post_p, is_simple_addr_expr_arg, fb_rvalue);
}
--- 2028,2037 ----
{
/* Fold &*EXPR into EXPR and simplify EXPR into a legal argument for
ADDR_EXPR. Notice that we need to request an rvalue because EXPR is
! already the lvalue that we were looking for originally.
!
! ??? is_simple_addr_expr_arg is wrong here. we really want to tell
! simplify_expr to start over. */
*expr_p = TREE_OPERAND (TREE_OPERAND (*expr_p, 0), 0);
simplify_expr (expr_p, pre_p, post_p, is_simple_addr_expr_arg, fb_rvalue);
}
*************** tree_build_scope (t)
*** 2056,2062 ****
Return the newly added list node or NULL_TREE if T was not added to
LIST_P. */
! static tree
add_tree (t, list_p)
tree t;
tree *list_p;
--- 2092,2098 ----
Return the newly added list node or NULL_TREE if T was not added to
LIST_P. */
! tree
add_tree (t, list_p)
tree t;
tree *list_p;
*************** tail_expression (chain, decl_is_bad)
*** 2685,2688 ****
--- 2721,2750 ----
}
}
return NULL_TREE;
+ }
+
+ /* Returns nonzero if STMT is a SIMPLE declaration, i.e. one with no
+ initializer.
+
+ This is not appropriate for static decls, so we leave them alone. */
+
+ int
+ is_simple_decl_stmt (stmt)
+ tree stmt;
+ {
+ tree decl = DECL_STMT_DECL (stmt);
+ tree init = DECL_INITIAL (decl);
+
+ if (!is_simple_val (DECL_SIZE_UNIT (decl)))
+ return 0;
+
+ /* Plain decls are simple. */
+ if (init == NULL_TREE || init == error_mark_node)
+ return 1;
+
+ /* Don't mess with a compile-time initializer. */
+ if (TREE_STATIC (decl))
+ return 1;
+
+ return 0;
}
Index: gcc/c-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.99.2.4
diff -c -p -r1.99.2.4 c-tree.h
*** gcc/c-tree.h 5 Aug 2002 18:14:09 -0000 1.99.2.4
--- gcc/c-tree.h 9 Aug 2002 22:38:10 -0000
*************** extern void c_finish_incomplete_decl PAR
*** 327,335 ****
extern GTY(()) tree static_ctors;
extern GTY(()) tree static_dtors;
- /* In c-simplify.c */
- extern int c_simplify_function_tree PARAMS ((tree));
-
/* In c-pretty-print.c */
extern void print_c_tree PARAMS ((FILE*, tree));
extern void print_c_node PARAMS ((FILE*, tree));
--- 327,332 ----
Index: gcc/langhooks-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks-def.h,v
retrieving revision 1.34.2.3
diff -c -p -r1.34.2.3 langhooks-def.h
*** gcc/langhooks-def.h 5 Aug 2002 18:14:18 -0000 1.34.2.3
--- gcc/langhooks-def.h 9 Aug 2002 22:38:11 -0000
*************** void lhd_tree_inlining_end_inlining PAR
*** 82,88 ****
tree lhd_tree_inlining_convert_parm_for_inlining PARAMS ((tree, tree, tree));
/* Declarations for tree simplification hooks. */
! int lhd_simplify_function_tree PARAMS ((tree));
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
--- 82,88 ----
tree lhd_tree_inlining_convert_parm_for_inlining PARAMS ((tree, tree, tree));
/* Declarations for tree simplification hooks. */
! int lhd_simplify_expr PARAMS ((tree *, tree *, tree *));
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
*************** int lhd_simplify_function_tree PARAMS
*** 170,177 ****
}
/* Hooks for tree simplification. */
! #define LANG_HOOKS_SIMPLIFY_FUNCTION_TREE \
! lhd_simplify_function_tree
/* Tree dump hooks. */
int lhd_tree_dump_dump_tree PARAMS ((void *, tree));
--- 170,176 ----
}
/* Hooks for tree simplification. */
! #define LANG_HOOKS_SIMPLIFY_EXPR lhd_simplify_expr
/* Tree dump hooks. */
int lhd_tree_dump_dump_tree PARAMS ((void *, tree));
*************** int lhd_tree_dump_type_quals PARAMS ((
*** 265,271 ****
LANG_HOOKS_TREE_DUMP_INITIALIZER, \
LANG_HOOKS_DECLS, \
LANG_HOOKS_FOR_TYPES_INITIALIZER, \
! LANG_HOOKS_SIMPLIFY_FUNCTION_TREE \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
--- 264,270 ----
LANG_HOOKS_TREE_DUMP_INITIALIZER, \
LANG_HOOKS_DECLS, \
LANG_HOOKS_FOR_TYPES_INITIALIZER, \
! LANG_HOOKS_SIMPLIFY_EXPR \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
Index: gcc/langhooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.c,v
retrieving revision 1.31.2.2
diff -c -p -r1.31.2.2 langhooks.c
*** gcc/langhooks.c 5 Aug 2002 18:14:18 -0000 1.31.2.2
--- gcc/langhooks.c 9 Aug 2002 22:38:11 -0000
*************** lhd_expr_size (exp)
*** 436,447 ****
return size_in_bytes (TREE_TYPE (exp));
}
! /* lang_hooks.simplify_function_tree re-writes the body of function FNDECL
! into SIMPLE form. */
int
! lhd_simplify_function_tree (fndecl)
! tree fndecl ATTRIBUTE_UNUSED;
{
return 0;
}
--- 436,448 ----
return size_in_bytes (TREE_TYPE (exp));
}
! /* lang_hooks.simplify_expr re-writes *EXPR_P into SIMPLE form. */
int
! lhd_simplify_expr (expr_p, pre_p, post_p)
! tree *expr_p ATTRIBUTE_UNUSED;
! tree *pre_p ATTRIBUTE_UNUSED;
! tree *post_p ATTRIBUTE_UNUSED;
{
return 0;
}
Index: gcc/langhooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.h,v
retrieving revision 1.42.2.3
diff -c -p -r1.42.2.3 langhooks.h
*** gcc/langhooks.h 5 Aug 2002 18:14:18 -0000 1.42.2.3
--- gcc/langhooks.h 9 Aug 2002 22:38:11 -0000
*************** struct lang_hooks
*** 354,363 ****
struct lang_hooks_for_types types;
! /* Given FUNCTION_DECL tree node, this function converts the body of the
! function into SIMPLE form. The SIMPLE grammar is defined and
! documented in tree-simple.c */
! int (*simplify_function_tree) PARAMS ((tree));
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
--- 354,363 ----
struct lang_hooks_for_types types;
! /* Perform language-specific simplification on the argument. Returns
! 1 if simplification is complete, or 0 to use default simplification
! semantics. */
! int (*simplify_expr) PARAMS ((tree *, tree *, tree *));
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
Index: gcc/tree-simple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.c,v
retrieving revision 1.1.4.6
diff -c -p -r1.1.4.6 tree-simple.c
*** gcc/tree-simple.c 7 Aug 2002 16:02:58 -0000 1.1.4.6
--- gcc/tree-simple.c 9 Aug 2002 22:38:12 -0000
*************** Boston, MA 02111-1307, USA. */
*** 22,30 ****
#include "config.h"
#include "system.h"
#include "tree.h"
- /* ??? SIMPLE trees use many tree nodes defined in the C front end. These
- should be moved to tree.def. */
- #include "c-tree.h"
#include "tree-simple.h"
#include "output.h"
#include "rtl.h"
--- 22,27 ----
*************** Boston, MA 02111-1307, USA. */
*** 195,346 ****
---------------------------------------------------------------------- */
- /* Validation of SIMPLE statements. */
-
- /* Return nonzero if T is a statement that complies with the SIMPLE
- grammar.
-
- stmt
- : compstmt
- | expr ';'
- | IF '(' condexpr ')' stmt
- | IF '(' condexpr ')' stmt ELSE stmt
- | WHILE '(' condexpr ')' stmt
- | DO stmt WHILE '(' condexpr ')'
- | FOR '('exprseq ';' condexpr ';'exprseq ')' stmt
- | SWITCH '(' val ')' casestmts
- | ';'
-
- casestmts
- : '{' cases default'}'
- | ';'
- | '{' '}'
-
- cases
- : cases case
- | case
-
- case
- : CASE CONST':' stmtlist stop_stmt
-
- default
- : DEFAULT ':' stmtlist stop_stmt
-
- stop_stmt
- : BREAK ';'
- | CONTINUE ';'
- | RETURN ';'
- | RETURN val ';'
- | RETURN '(' val ')' ';' */
-
- int
- is_simple_stmt (t)
- tree t;
- {
- if (t == NULL_TREE)
- return 1;
-
- switch (TREE_CODE (t))
- {
- case COMPOUND_STMT:
- return is_simple_compstmt (COMPOUND_BODY (t));
-
- case SCOPE_STMT:
- return is_simple_compstmt (t);
-
- case EXPR_STMT:
- return is_simple_expr (EXPR_STMT_EXPR (t));
-
- case IF_STMT:
- return (is_simple_condexpr (IF_COND (t))
- && is_simple_stmt (THEN_CLAUSE (t))
- && is_simple_stmt (ELSE_CLAUSE (t)));
-
- case WHILE_STMT:
- return (is_simple_condexpr (WHILE_COND (t))
- && is_simple_stmt (WHILE_BODY (t)));
-
- case DO_STMT:
- return (is_simple_condexpr (DO_COND (t))
- && is_simple_stmt (DO_BODY (t)));
-
- case FOR_STMT:
- {
- int s1, s2, s3, s4;
-
- if (TREE_CODE (FOR_INIT_STMT (t)) == DECL_STMT)
- s1 = 0;
- else
- s1 = is_simple_exprseq (EXPR_STMT_EXPR (FOR_INIT_STMT (t)));
-
- s2 = is_simple_condexpr (FOR_COND (t));
- s3 = is_simple_exprseq (FOR_EXPR (t));
- s4 = is_simple_stmt (FOR_BODY (t));
-
- return (s1 && s2 && s3 && s4);
- }
-
- /* Note that we can assume that we don't need to special case the body
- of the switch() statement. If we got to this stage, we can assume
- that the switch() is properly formed (i.e., it will be a compound
- statement containing all the case labels). */
- case SWITCH_STMT:
- return (is_simple_val (SWITCH_COND (t))
- && is_simple_stmt (SWITCH_BODY (t)));
-
- case FILE_STMT:
- case LABEL_STMT:
- case GOTO_STMT:
- case ASM_STMT:
- case CASE_LABEL:
- case CONTINUE_STMT:
- case BREAK_STMT:
- return 1;
-
- case RETURN_STMT:
- {
- tree type = TREE_TYPE (TREE_TYPE (current_function_decl));
- if (TREE_CODE (type) != VOID_TYPE
- && RETURN_EXPR (t))
- return is_simple_rhs (TREE_OPERAND (RETURN_EXPR (t), 1));
- else
- return 1;
- }
-
- case DECL_STMT:
- return is_simple_decl_stmt (t);
-
- default:
- return 0;
- }
- }
-
- /* Returns nonzero if STMT is a SIMPLE declaration, i.e. one with no
- initializer.
-
- This is not appropriate for static decls, so we leave them alone. */
-
- int
- is_simple_decl_stmt (stmt)
- tree stmt;
- {
- tree decl = DECL_STMT_DECL (stmt);
- tree init = DECL_INITIAL (decl);
-
- if (!is_simple_val (DECL_SIZE_UNIT (decl)))
- return 0;
-
- /* Plain decls are simple. */
- if (init == NULL_TREE || init == error_mark_node)
- return 1;
-
- /* Don't mess with a compile-time initializer. */
- if (TREE_STATIC (decl))
- return 1;
-
- return 0;
- }
-
/* Returns nonzero if T is a simple CONSTRUCTOR:
aggr_init: '{' vals '}'
--- 192,197 ----
*************** is_simple_initializer (t)
*** 400,432 ****
| '{' decls all_stmts '}'
| '{' decls '}' */
- int
- is_simple_compstmt (t)
- tree t;
- {
- if (t == NULL_TREE)
- return 1;
-
- /* Look for '{'. */
- if (TREE_CODE (t) != SCOPE_STMT
- || !SCOPE_BEGIN_P (t))
- return 0;
-
- /* Test all the statements in the body. */
- for (t = TREE_CHAIN (t);
- t && !(TREE_CODE (t) == SCOPE_STMT && SCOPE_END_P (t));
- t = TREE_CHAIN (t))
- if (!is_simple_stmt (t))
- return 0;
-
- /* Look for '}'. */
- if (t
- && (TREE_CODE (t) != SCOPE_STMT
- || !SCOPE_END_P (t)))
- return 0;
-
- return 1;
- }
--- 251,256 ----
*************** is_simplifiable_builtin (expr)
*** 1069,1072 ****
--- 893,928 ----
default:
return 1;
}
+ }
+
+ /* Given a COMPOUND_EXPR TOP, reorganize all of the nested COMPOUND_EXPRs
+ so that they only appear as the second operand. */
+
+ tree
+ rationalize_compound_expr (top)
+ tree top;
+ {
+ tree cur = top;
+ while (TREE_CODE (cur) == COMPOUND_EXPR)
+ {
+ tree lhs = TREE_OPERAND (cur, 0);
+ tree rhs = TREE_OPERAND (cur, 1);
+ if (TREE_CODE (lhs) == COMPOUND_EXPR)
+ {
+ /* We have ((a, b), c). Rearrange to (a, (b, c)). */
+ tree lhs1 = TREE_OPERAND (lhs, 0);
+ tree rhs1 = TREE_OPERAND (lhs, 1);
+
+ /* Change lhs from (a, b) to (b, c). */
+ TREE_OPERAND (lhs, 0) = rhs1;
+ TREE_OPERAND (lhs, 1) = rhs;
+
+ /* Change cur from (lhs, c) to (a, lhs), i.e. (a, (b, c)). */
+ TREE_OPERAND (cur, 0) = lhs1;
+ TREE_OPERAND (cur, 1) = lhs;
+ }
+ else
+ cur = rhs;
+ }
+ return top;
}
Index: gcc/tree-simple.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.h,v
retrieving revision 1.1.4.3
diff -c -p -r1.1.4.3 tree-simple.h
*** gcc/tree-simple.h 17 Jul 2002 14:06:21 -0000 1.1.4.3
--- gcc/tree-simple.h 9 Aug 2002 22:38:12 -0000
*************** int is_simple_constructor_elt P
*** 67,70 ****
--- 67,83 ----
int is_simple_initializer PARAMS ((tree));
int is_simplifiable_builtin PARAMS ((tree));
+ /* FIXME this needs a better name. */
+ tree add_tree PARAMS ((tree, tree *));
+ /* FIXME we should deduce this from the predicate. */
+ typedef enum fallback_t {
+ fb_rvalue=1,
+ fb_lvalue=2,
+ fb_either=1|2
+ } fallback_t;
+ void simplify_expr PARAMS ((tree *, tree *, tree *,
+ int (*) PARAMS ((tree)),
+ fallback_t));
+
+
#endif /* _TREE_SIMPLE_H */
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.7
diff -c -p -r1.342.2.7 tree.h
*** gcc/tree.h 7 Aug 2002 16:02:59 -0000 1.342.2.7
--- gcc/tree.h 9 Aug 2002 22:38:14 -0000
*************** extern int dump_switch_p
*** 3110,3115 ****
--- 3110,3116 ----
extern void dump_enable_all_ssa PARAMS ((void));
const char *dump_flag_name PARAMS ((enum tree_dump_index));
+ extern int simplify_function_tree PARAMS ((tree));
/* Redefine abort to report an internal error w/o coredump, and
reporting the location of the error in the source file. This logic
Index: gcc/cp/cp-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-lang.c,v
retrieving revision 1.36.2.3
diff -c -p -r1.36.2.3 cp-lang.c
*** gcc/cp/cp-lang.c 5 Aug 2002 18:14:49 -0000 1.36.2.3
--- gcc/cp/cp-lang.c 9 Aug 2002 22:38:15 -0000
*************** static tree cp_expr_size PARAMS ((tree))
*** 153,160 ****
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR cxx_incomplete_type_error
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to
! #undef LANG_HOOKS_SIMPLIFY_FUNCTION_TREE
! #define LANG_HOOKS_SIMPLIFY_FUNCTION_TREE cp_simplify_function_tree
/* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
--- 153,160 ----
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR cxx_incomplete_type_error
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to
! #undef LANG_HOOKS_SIMPLIFY_EXPR
! #define LANG_HOOKS_SIMPLIFY_EXPR cp_simplify_expr
/* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Index: gcc/cp/cp-simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Attic/cp-simplify.c,v
retrieving revision 1.1.4.1
diff -c -p -r1.1.4.1 cp-simplify.c
*** gcc/cp/cp-simplify.c 22 Jun 2002 04:40:17 -0000 1.1.4.1
--- gcc/cp/cp-simplify.c 9 Aug 2002 22:38:15 -0000
*************** Software Foundation, 59 Temple Place - S
*** 26,35 ****
#include "cp-tree.h"
#include "c-common.h"
#include "toplev.h"
int
! cp_simplify_function_tree (fndecl)
! tree fndecl;
{
! return c_simplify_function_tree (fndecl);
}
--- 26,75 ----
#include "cp-tree.h"
#include "c-common.h"
#include "toplev.h"
+ #include "tree-simple.h"
+
+ static void simplify_target_expr PARAMS ((tree *, tree *, tree *));
+
+ /* Do C++-specific simplification. Args are as for simplify_expr. */
int
! cp_simplify_expr (expr_p, pre_p, post_p)
! tree *expr_p;
! tree *pre_p;
! tree *post_p;
! {
! switch (TREE_CODE (*expr_p))
! {
! case INIT_EXPR:
! {
! /* If we are initializing something from a TARGET_EXPR, strip the
! TARGET_EXPR and initialize it directly. */
! tree *from = &TREE_OPERAND (*expr_p, 1);
! if (TREE_CODE (*from) == TARGET_EXPR)
! *from = TARGET_EXPR_INITIAL (*from);
! /* And then fall through to the default code. */
! break;
! }
! case TARGET_EXPR:
! simplify_target_expr (expr_p, pre_p, post_p);
! break;
! }
!
! return c_simplify_expr (expr_p, pre_p, post_p);
! }
!
! /* Simplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
!
! static void
! simplify_target_expr (expr_p, pre_p, post_p)
! tree *expr_p;
! tree *pre_p;
! tree *post_p;
{
! tree temp = TARGET_EXPR_SLOT (*expr_p);
! tree decl = build_stmt (DECL_STMT, temp);
! tree init = build (INIT_EXPR, TREE_TYPE (temp), temp,
! TARGET_EXPR_INITIAL (*expr_p));
! add_tree (decl, pre_p);
! *expr_p = init;
}
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.719.2.6
diff -c -p -r1.719.2.6 cp-tree.h
*** gcc/cp/cp-tree.h 5 Aug 2002 18:14:49 -0000 1.719.2.6
--- gcc/cp/cp-tree.h 9 Aug 2002 22:38:18 -0000
*************** extern tree mangle_ref_init_variable
*** 4367,4373 ****
extern int cp_dump_tree PARAMS ((void *, tree));
/* in cp-simplify.c */
! extern int cp_simplify_function_tree PARAMS ((tree));
/* -- end of C++ */
--- 4367,4373 ----
extern int cp_dump_tree PARAMS ((void *, tree));
/* in cp-simplify.c */
! extern int cp_simplify_expr PARAMS ((tree *, tree *, tree *));
/* -- end of C++ */
Index: gcc/cp/optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/optimize.c,v
retrieving revision 1.81.10.1
diff -c -p -r1.81.10.1 optimize.c
*** gcc/cp/optimize.c 22 Jun 2002 04:40:25 -0000 1.81.10.1
--- gcc/cp/optimize.c 9 Aug 2002 22:38:18 -0000
*************** optimize_function (fn)
*** 82,88 ****
/* Simplify the function. Don't try to optimize the function if
simplification failed. */
if (!flag_disable_simple
! && (*lang_hooks.simplify_function_tree) (fn))
{
/* Invoke the SSA tree optimizer. */
if (flag_tree_ssa)
--- 82,88 ----
/* Simplify the function. Don't try to optimize the function if
simplification failed. */
if (!flag_disable_simple
! && simplify_function_tree (fn))
{
/* Invoke the SSA tree optimizer. */
if (flag_tree_ssa)