Commit 7e6eb623 by Daniel Berlin

[multiple changes]


2004-06-11  Steven Bosscher <stevenb@suse.de>

	* tree-ssa-dce.c (mark_control_dependent_edges_necessary):
	Don't try to mark anything control dependent on the entry or
	exit blocks.

2004-06-11  Daniel Berlin  <dberlin@dberlin.org>

	Fix Bug 15899
	Fix Bug 15460
	* tree.h (SSA_NAME_VALUE): New macro.
	(struct tree_ssa_name): Add value_handle member.
	* tree-ssa-pre.c: Replaced.
	* tree-flow.h (tree_ann_type): Add CST_ANN, EXPR_ANN.
	(struct cst_ann_d): New.
	(struct expr_ann_d): New.
	(union tree_ann_d): Add cst_ann, expr_ann.
	* tree-dfa.c (create_cst_ann): New function.
	(create_expr_ann): Ditto.
	* tree-flow-inline.h (cst_ann): New function.
	(expr_ann): Ditto.
	(get_cst_ann): Ditto.
	(get_expr_ann): Ditto..

From-SVN: r83010
parent e4602cf3
2004-06-11 Steven Bosscher <stevenb@suse.de>
* tree-ssa-dce.c (mark_control_dependent_edges_necessary):
Don't try to mark anything control dependent on the entry or
exit blocks.
2004-06-11 Daniel Berlin <dberlin@dberlin.org>
Fix Bug 15899
Fix Bug 15460
* tree.h (SSA_NAME_VALUE): New macro.
(struct tree_ssa_name): Add value_handle member.
* tree-ssa-pre.c: Replaced.
* tree-flow.h (tree_ann_type): Add CST_ANN, EXPR_ANN.
(struct cst_ann_d): New.
(struct expr_ann_d): New.
(union tree_ann_d): Add cst_ann, expr_ann.
* tree-dfa.c (create_cst_ann): New function.
(create_expr_ann): Ditto.
* tree-flow-inline.h (cst_ann): New function.
(expr_ann): Ditto.
(get_cst_ann): Ditto.
(get_expr_ann): Ditto..
2004-06-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2004-06-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa.c (pa_hpux_init_libfunc): Add support for unord_optab. * pa.c (pa_hpux_init_libfunc): Add support for unord_optab.
......
/* This would cause PRE load motion to generate invalid code and ICE */
void foo (char *name)
{
if (*name)
name ++;
while (name[0]);
asm ("" : "=r" (name));
}
...@@ -16,4 +16,4 @@ int main(int argc, char **argv) ...@@ -16,4 +16,4 @@ int main(int argc, char **argv)
} }
/* We should eliminate one evaluation of b + c along the main path, /* We should eliminate one evaluation of b + c along the main path,
causing one reload. */ causing one reload. */
/* { dg-final { scan-tree-dump-times "Reloads:1" 1 "pre"} } */ /* { dg-final { scan-tree-dump-times "Eliminated:1" 1 "pre"} } */
...@@ -17,4 +17,4 @@ int motion_test1(int data, int data_0, int data_3, int v) ...@@ -17,4 +17,4 @@ int motion_test1(int data, int data_0, int data_3, int v)
} }
/* We should eliminate one computation of data_0 + data_3 along the /* We should eliminate one computation of data_0 + data_3 along the
main path, causing one reload. */ main path, causing one reload. */
/* { dg-final { scan-tree-dump-times "Reloads:1" 1 "pre"} } */ /* { dg-final { scan-tree-dump-times "Eliminated:1" 1 "pre"} } */
...@@ -463,6 +463,52 @@ create_stmt_ann (tree t) ...@@ -463,6 +463,52 @@ create_stmt_ann (tree t)
} }
/* Create a new annotation for a constant T. */
cst_ann_t
create_cst_ann (tree t)
{
cst_ann_t ann;
#if defined ENABLE_CHECKING
if (t == NULL_TREE
|| (t->common.ann
&& t->common.ann->common.type != CST_ANN))
abort ();
#endif
ann = ggc_alloc (sizeof (*ann));
memset ((void *) ann, 0, sizeof (*ann));
ann->common.type = CST_ANN;
t->common.ann = (tree_ann) ann;
return ann;
}
/* Create a new annotation for an expression T. */
expr_ann_t
create_expr_ann (tree t)
{
expr_ann_t ann;
#if defined ENABLE_CHECKING
if (t == NULL_TREE
|| (t->common.ann
&& t->common.ann->common.type != EXPR_ANN))
abort ();
#endif
ann = ggc_alloc (sizeof (*ann));
memset ((void *) ann, 0, sizeof (*ann));
ann->common.type = EXPR_ANN;
t->common.ann = (tree_ann) ann;
return ann;
}
/* Build a temporary. Make sure and register it to be renamed. */ /* Build a temporary. Make sure and register it to be renamed. */
tree tree
......
...@@ -46,6 +46,47 @@ get_var_ann (tree var) ...@@ -46,6 +46,47 @@ get_var_ann (tree var)
return (ann) ? ann : create_var_ann (var); return (ann) ? ann : create_var_ann (var);
} }
static inline cst_ann_t
cst_ann (tree t)
{
#if defined ENABLE_CHECKING
if (TREE_CODE_CLASS (TREE_CODE (t)) != 'c'
|| (t->common.ann
&& t->common.ann->common.type != CST_ANN))
abort ();
#endif
return (cst_ann_t) t->common.ann;
}
static inline cst_ann_t
get_cst_ann (tree var)
{
cst_ann_t ann = cst_ann (var);
return (ann) ? ann : create_cst_ann (var);
}
static inline expr_ann_t
expr_ann (tree t)
{
#if defined ENABLE_CHECKING
if (!EXPR_P (t)
|| (t->common.ann
&& t->common.ann->common.type != EXPR_ANN))
abort ();
#endif
return (expr_ann_t) t->common.ann;
}
static inline expr_ann_t
get_expr_ann (tree var)
{
expr_ann_t ann = expr_ann (var);
return (ann) ? ann : create_expr_ann (var);
}
static inline stmt_ann_t static inline stmt_ann_t
stmt_ann (tree t) stmt_ann (tree t)
{ {
......
...@@ -40,12 +40,15 @@ typedef struct basic_block_def *basic_block; ...@@ -40,12 +40,15 @@ typedef struct basic_block_def *basic_block;
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
Tree annotations stored in tree_common.ann Tree annotations stored in tree_common.ann
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
enum tree_ann_type { TREE_ANN_COMMON, VAR_ANN, STMT_ANN }; enum tree_ann_type { TREE_ANN_COMMON, VAR_ANN, CST_ANN, EXPR_ANN, STMT_ANN };
struct tree_ann_common_d GTY(()) struct tree_ann_common_d GTY(())
{ {
/* Annotation type. */ /* Annotation type. */
enum tree_ann_type type; enum tree_ann_type type;
/* The value handle for this expression. Used by GVN-PRE. */
tree GTY((skip)) value_handle;
}; };
/* It is advantageous to avoid things like life analysis for variables which /* It is advantageous to avoid things like life analysis for variables which
...@@ -164,6 +167,11 @@ struct var_ann_d GTY(()) ...@@ -164,6 +167,11 @@ struct var_ann_d GTY(())
live at the same time and this can happen for each call to the live at the same time and this can happen for each call to the
dominator optimizer. */ dominator optimizer. */
tree current_def; tree current_def;
/* The set of expressions represented by this variable if it is a
value handle. This is used by GVN-PRE. */
PTR GTY ((skip)) expr_set;
}; };
...@@ -256,17 +264,38 @@ struct stmt_ann_d GTY(()) ...@@ -256,17 +264,38 @@ struct stmt_ann_d GTY(())
}; };
struct cst_ann_d GTY (())
{
struct tree_ann_common_d common;
};
struct expr_ann_d GTY(())
{
struct tree_ann_common_d common;
};
union tree_ann_d GTY((desc ("ann_type ((tree_ann)&%h)"))) union tree_ann_d GTY((desc ("ann_type ((tree_ann)&%h)")))
{ {
struct tree_ann_common_d GTY((tag ("TREE_ANN_COMMON"))) common; struct tree_ann_common_d GTY((tag ("TREE_ANN_COMMON"))) common;
struct var_ann_d GTY((tag ("VAR_ANN"))) decl; struct var_ann_d GTY((tag ("VAR_ANN"))) decl;
struct expr_ann_d GTY((tag ("EXPR_ANN"))) expr;
struct cst_ann_d GTY((tag ("CST_ANN"))) cst;
struct stmt_ann_d GTY((tag ("STMT_ANN"))) stmt; struct stmt_ann_d GTY((tag ("STMT_ANN"))) stmt;
}; };
typedef union tree_ann_d *tree_ann; typedef union tree_ann_d *tree_ann;
typedef struct var_ann_d *var_ann_t; typedef struct var_ann_d *var_ann_t;
typedef struct stmt_ann_d *stmt_ann_t; typedef struct stmt_ann_d *stmt_ann_t;
typedef struct expr_ann_d *expr_ann_t;
typedef struct cst_ann_d *cst_ann_t;
static inline cst_ann_t cst_ann (tree);
static inline cst_ann_t get_cst_ann (tree);
static inline expr_ann_t expr_ann (tree);
static inline expr_ann_t get_expr_ann (tree);
static inline var_ann_t var_ann (tree); static inline var_ann_t var_ann (tree);
static inline var_ann_t get_var_ann (tree); static inline var_ann_t get_var_ann (tree);
static inline stmt_ann_t stmt_ann (tree); static inline stmt_ann_t stmt_ann (tree);
...@@ -464,6 +493,8 @@ extern void dump_generic_bb (FILE *, basic_block, int, int); ...@@ -464,6 +493,8 @@ extern void dump_generic_bb (FILE *, basic_block, int, int);
/* In tree-dfa.c */ /* In tree-dfa.c */
extern var_ann_t create_var_ann (tree); extern var_ann_t create_var_ann (tree);
extern cst_ann_t create_cst_ann (tree);
extern expr_ann_t create_expr_ann (tree);
extern stmt_ann_t create_stmt_ann (tree); extern stmt_ann_t create_stmt_ann (tree);
extern tree create_phi_node (tree, basic_block); extern tree create_phi_node (tree, basic_block);
extern void add_phi_arg (tree *, tree, edge); extern void add_phi_arg (tree *, tree, edge);
...@@ -567,6 +598,12 @@ extern bool tree_can_throw_internal (tree); ...@@ -567,6 +598,12 @@ extern bool tree_can_throw_internal (tree);
extern bool tree_can_throw_external (tree); extern bool tree_can_throw_external (tree);
extern void add_stmt_to_eh_region (tree, int); extern void add_stmt_to_eh_region (tree, int);
/* In tree-ssa-pre.c */
tree get_value_handle (tree);
void set_value_handle (tree, tree);
void debug_value_expressions (tree);
void print_value_expressions (FILE *, tree);
#include "tree-flow-inline.h" #include "tree-flow-inline.h"
#endif /* _TREE_FLOW_H */ #endif /* _TREE_FLOW_H */
...@@ -482,6 +482,14 @@ mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el) ...@@ -482,6 +482,14 @@ mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el)
{ {
int edge_number; int edge_number;
#ifdef ENABLE_CHECKING
if (bb == EXIT_BLOCK_PTR)
abort ();
#endif
if (bb == ENTRY_BLOCK_PTR)
return;
EXECUTE_IF_CONTROL_DEPENDENT (bb->index, edge_number, EXECUTE_IF_CONTROL_DEPENDENT (bb->index, edge_number,
{ {
tree t; tree t;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -1184,6 +1184,10 @@ struct tree_exp GTY(()) ...@@ -1184,6 +1184,10 @@ struct tree_exp GTY(())
#define SSA_NAME_PTR_INFO(N) \ #define SSA_NAME_PTR_INFO(N) \
SSA_NAME_CHECK (N)->ssa_name.ptr_info SSA_NAME_CHECK (N)->ssa_name.ptr_info
/* Get the value of this SSA_NAME, if available. */
#define SSA_NAME_VALUE(N) \
SSA_NAME_CHECK (N)->ssa_name.value_handle
#ifndef GCC_BITMAP_H #ifndef GCC_BITMAP_H
struct bitmap_head_def; struct bitmap_head_def;
#endif #endif
...@@ -1223,6 +1227,9 @@ struct tree_ssa_name GTY(()) ...@@ -1223,6 +1227,9 @@ struct tree_ssa_name GTY(())
/* Pointer attributes used for alias analysis. */ /* Pointer attributes used for alias analysis. */
struct ptr_info_def *ptr_info; struct ptr_info_def *ptr_info;
/* Value for SSA name used by GVN. */
tree GTY((skip)) value_handle;
}; };
/* In a PHI_NODE node. */ /* In a PHI_NODE node. */
......
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