Makefile.in (OBJS-common): Add tree-ssa-structalias.o.

2005-06-08  Daniel Berlin  <dberlin@dberlin.org>

	* Makefile.in (OBJS-common): Add tree-ssa-structalias.o.
	* tree-flow.h (find_what_p_points_to): Add prototype.
	(push_fields_onto_fieldstack): Ditto.
	(sort_fieldstack): Ditto.
	* tree-optimize.c (init_tree_optimization_passes): Add
	pass_build_pta and pass_del_pta.
	* tree-pass.h (pass_build_pta): New structure.
	(pass_del_pta): Ditto.
	* tree-ssa-alias.c (compute_flow_sensitive_aliasing): Disambiguate
	using new alias analyzer.
	(push_fields_onto_fieldstack): Removed from here.
	(bitpos_of_field): Ditto.
	(fieldoff_compare): Ditto.
	* tree-ssa-structalias.c: New file.
	* tree-ssa-structalias.h: Ditto.

From-SVN: r100800
This commit is contained in:
Daniel Berlin 2005-06-09 13:05:39 +00:00 committed by Daniel Berlin
parent 5878b92f9e
commit 910fdc79ea
8 changed files with 3260 additions and 99 deletions

View File

@ -1,3 +1,21 @@
2005-06-08 Daniel Berlin <dberlin@dberlin.org>
* Makefile.in (OBJS-common): Add tree-ssa-structalias.o.
* tree-flow.h (find_what_p_points_to): Add prototype.
(push_fields_onto_fieldstack): Ditto.
(sort_fieldstack): Ditto.
* tree-optimize.c (init_tree_optimization_passes): Add
pass_build_pta and pass_del_pta.
* tree-pass.h (pass_build_pta): New structure.
(pass_del_pta): Ditto.
* tree-ssa-alias.c (compute_flow_sensitive_aliasing): Disambiguate
using new alias analyzer.
(push_fields_onto_fieldstack): Removed from here.
(bitpos_of_field): Ditto.
(fieldoff_compare): Ditto.
* tree-ssa-structalias.c: New file.
* tree-ssa-structalias.h: Ditto.
2005-06-09 Nathan Sidwell <nathan@codesourcery.com> 2005-06-09 Nathan Sidwell <nathan@codesourcery.com>
* c-typeck.c (build_c_cast): Check type punning on COMPONENT_REF * c-typeck.c (build_c_cast): Check type punning on COMPONENT_REF

View File

@ -962,8 +962,10 @@ OBJS-common = \
varasm.o varray.o vec.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \ varasm.o varray.o vec.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \
et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \ et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \
rtl-profile.o tree-profile.o rtlhooks.o cfgexpand.o lambda-mat.o \ rtl-profile.o tree-profile.o rtlhooks.o cfgexpand.o lambda-mat.o \
lambda-trans.o lambda-code.o tree-loop-linear.o tree-ssa-sink.o \
lambda-trans.o lambda-code.o tree-loop-linear.o tree-ssa-sink.o \ lambda-trans.o lambda-code.o tree-loop-linear.o tree-ssa-sink.o \
tree-vrp.o tree-stdarg.o tree-cfgcleanup.o tree-ssa-reassoc.o tree-vrp.o tree-stdarg.o tree-cfgcleanup.o tree-ssa-reassoc.o \
tree-ssa-structalias.o
OBJS-md = $(out_object_file) OBJS-md = $(out_object_file)
@ -1661,6 +1663,9 @@ stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(PARAMS_H) $(FLAGS_H) function.h $(EXPR_H) $(RTL_H) \ $(TREE_H) $(PARAMS_H) $(FLAGS_H) function.h $(EXPR_H) $(RTL_H) \
$(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.h \ $(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.h \
toplev.h toplev.h
tree-ssa-structalias.o: tree-ssa-structalias.c tree-ssa-structalias.h \
$(SYSTEM_H) $(CONFIG_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \
$(TM_H) coretypes.h cgraph.h tree-pass.h $(TIMEVAR_H)
tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
toplev.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \ toplev.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \

View File

@ -748,6 +748,9 @@ extern bool thread_through_all_blocks (bitmap);
tree force_gimple_operand (tree, tree *, bool, tree); tree force_gimple_operand (tree, tree *, bool, tree);
tree force_gimple_operand_bsi (block_stmt_iterator *, tree, bool, tree); tree force_gimple_operand_bsi (block_stmt_iterator *, tree, bool, tree);
/* In tree-ssa-structalias.c */
bool find_what_p_points_to (tree);
/* In tree-ssa-address.c */ /* In tree-ssa-address.c */
/* Affine combination of trees. We keep track of at most MAX_AFF_ELTS elements /* Affine combination of trees. We keep track of at most MAX_AFF_ELTS elements
@ -789,6 +792,23 @@ tree create_mem_ref (block_stmt_iterator *, tree,
rtx addr_for_mem_ref (struct mem_address *, bool); rtx addr_for_mem_ref (struct mem_address *, bool);
void get_address_description (tree, struct mem_address *); void get_address_description (tree, struct mem_address *);
tree maybe_fold_tmr (tree); tree maybe_fold_tmr (tree);
/* This structure is simply used during pushing fields onto the fieldstack
to track the offset of the field, since bitpos_of_field gives it relative
to its immediate containing type, and we want it relative to the ultimate
containing object. */
struct fieldoff
{
tree field;
HOST_WIDE_INT offset;
};
typedef struct fieldoff fieldoff_s;
DEF_VEC_O(fieldoff_s);
DEF_VEC_ALLOC_O(fieldoff_s,heap);
int push_fields_onto_fieldstack (tree, VEC(fieldoff_s,heap) **,
HOST_WIDE_INT, bool *);
void sort_fieldstack (VEC(fieldoff_s,heap) *);
#include "tree-flow-inline.h" #include "tree-flow-inline.h"

View File

@ -396,7 +396,9 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_referenced_vars); NEXT_PASS (pass_referenced_vars);
NEXT_PASS (pass_create_structure_vars); NEXT_PASS (pass_create_structure_vars);
NEXT_PASS (pass_build_ssa); NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_build_pta);
NEXT_PASS (pass_may_alias); NEXT_PASS (pass_may_alias);
NEXT_PASS (pass_del_pta);
NEXT_PASS (pass_rename_ssa_copies); NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_early_warn_uninitialized); NEXT_PASS (pass_early_warn_uninitialized);
@ -412,7 +414,9 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_dominator); NEXT_PASS (pass_dominator);
NEXT_PASS (pass_phiopt); NEXT_PASS (pass_phiopt);
NEXT_PASS (pass_build_pta);
NEXT_PASS (pass_may_alias); NEXT_PASS (pass_may_alias);
NEXT_PASS (pass_del_pta);
NEXT_PASS (pass_tail_recursion); NEXT_PASS (pass_tail_recursion);
NEXT_PASS (pass_profile); NEXT_PASS (pass_profile);
NEXT_PASS (pass_ch); NEXT_PASS (pass_ch);

View File

@ -221,6 +221,8 @@ extern struct tree_opt_pass pass_store_ccp;
extern struct tree_opt_pass pass_store_copy_prop; extern struct tree_opt_pass pass_store_copy_prop;
extern struct tree_opt_pass pass_vrp; extern struct tree_opt_pass pass_vrp;
extern struct tree_opt_pass pass_create_structure_vars; extern struct tree_opt_pass pass_create_structure_vars;
extern struct tree_opt_pass pass_build_pta;
extern struct tree_opt_pass pass_del_pta;
extern struct tree_opt_pass pass_uncprop; extern struct tree_opt_pass pass_uncprop;
extern struct tree_opt_pass pass_reassoc; extern struct tree_opt_pass pass_reassoc;

View File

@ -875,6 +875,15 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
{ {
size_t i; size_t i;
for (i = 0; i < VARRAY_ACTIVE_SIZE (ai->processed_ptrs); i++)
{
tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
if (pi->pt_anything || pi->pt_vars == NULL)
{
find_what_p_points_to (ptr);
}
}
create_name_tags (ai); create_name_tags (ai);
for (i = 0; i < VARRAY_ACTIVE_SIZE (ai->processed_ptrs); i++) for (i = 0; i < VARRAY_ACTIVE_SIZE (ai->processed_ptrs); i++)
@ -2810,82 +2819,6 @@ new_type_alias (tree ptr, tree var)
/* Note, TAG and its set of aliases are not marked for renaming. */ /* Note, TAG and its set of aliases are not marked for renaming. */
} }
/* This structure is simply used during pushing fields onto the fieldstack
to track the offset of the field, since bitpos_of_field gives it relative
to its immediate containing type, and we want it relative to the ultimate
containing object. */
typedef struct fieldoff
{
tree field;
HOST_WIDE_INT offset;
} fieldoff_s;
DEF_VEC_O (fieldoff_s);
DEF_VEC_ALLOC_O(fieldoff_s,heap);
/* Return the position, in bits, of FIELD_DECL from the beginning of its
structure.
Return -1 if the position is conditional or otherwise non-constant
integer. */
static HOST_WIDE_INT
bitpos_of_field (const tree fdecl)
{
if (TREE_CODE (DECL_FIELD_OFFSET (fdecl)) != INTEGER_CST
|| TREE_CODE (DECL_FIELD_BIT_OFFSET (fdecl)) != INTEGER_CST)
return -1;
return (tree_low_cst (DECL_FIELD_OFFSET (fdecl), 1) * 8)
+ tree_low_cst (DECL_FIELD_BIT_OFFSET (fdecl), 1);
}
/* Given a TYPE, and a vector of field offsets FIELDSTACK, push all the fields
of TYPE onto fieldstack, recording their offsets along the way.
OFFSET is used to keep track of the offset in this entire structure, rather
than just the immediately containing structure. Returns the number
of fields pushed. */
static int
push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
HOST_WIDE_INT offset)
{
tree field;
int count = 0;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL)
{
bool push = false;
if (!var_can_have_subvars (field))
push = true;
else if (!(push_fields_onto_fieldstack
(TREE_TYPE (field), fieldstack,
offset + bitpos_of_field (field)))
&& DECL_SIZE (field)
&& !integer_zerop (DECL_SIZE (field)))
/* Empty structures may have actual size, like in C++. So
see if we didn't push any subfields and the size is
nonzero, push the field onto the stack */
push = true;
if (push)
{
fieldoff_s *pair;
pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
pair->field = field;
pair->offset = offset + bitpos_of_field (field);
count++;
}
}
return count;
}
/* This represents the used range of a variable. */ /* This represents the used range of a variable. */
typedef struct used_part typedef struct used_part
@ -2925,22 +2858,6 @@ get_or_create_used_part_for (size_t uid)
return up; return up;
} }
/* qsort comparison function for two fieldoff's PA and PB */
static int
fieldoff_compare (const void *pa, const void *pb)
{
const fieldoff_s *foa = (const fieldoff_s *)pa;
const fieldoff_s *fob = (const fieldoff_s *)pb;
HOST_WIDE_INT foasize, fobsize;
if (foa->offset != fob->offset)
return foa->offset - fob->offset;
foasize = TREE_INT_CST_LOW (DECL_SIZE (foa->field));
fobsize = TREE_INT_CST_LOW (DECL_SIZE (fob->field));
return foasize - fobsize;
}
/* Given an aggregate VAR, create the subvariables that represent its /* Given an aggregate VAR, create the subvariables that represent its
fields. */ fields. */
@ -2956,7 +2873,7 @@ create_overlap_variables_for (tree var)
return; return;
up = used_portions[uid]; up = used_portions[uid];
push_fields_onto_fieldstack (TREE_TYPE (var), &fieldstack, 0); push_fields_onto_fieldstack (TREE_TYPE (var), &fieldstack, 0, NULL);
if (VEC_length (fieldoff_s, fieldstack) != 0) if (VEC_length (fieldoff_s, fieldstack) != 0)
{ {
subvar_t *subvars; subvar_t *subvars;
@ -3024,10 +2941,7 @@ create_overlap_variables_for (tree var)
/* Otherwise, create the variables. */ /* Otherwise, create the variables. */
subvars = lookup_subvars_for_var (var); subvars = lookup_subvars_for_var (var);
qsort (VEC_address (fieldoff_s, fieldstack), sort_fieldstack (fieldstack);
VEC_length (fieldoff_s, fieldstack),
sizeof (fieldoff_s),
fieldoff_compare);
for (i = VEC_length (fieldoff_s, fieldstack); for (i = VEC_length (fieldoff_s, fieldstack);
VEC_iterate (fieldoff_s, fieldstack, --i, fo);) VEC_iterate (fieldoff_s, fieldstack, --i, fo);)

3165
gcc/tree-ssa-structalias.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
/* Tree based points-to analysis
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Daniel Berlin <dberlin@dberlin.org>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TREE_ALIAS_COMMON
#define TREE_ALIAS_COMMON
struct constraint;
typedef struct constraint *constraint_t;
extern void dump_constraint (FILE *, constraint_t);
extern void dump_constraints (FILE *);
extern void debug_constraint (constraint_t);
extern void debug_constraints (void);
extern void dump_solution_for_var (FILE *, unsigned int);
extern void debug_solution_for_var (unsigned int);
#endif /* TREE_ALIAS_COMMON */