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:
parent
5878b92f9e
commit
910fdc79ea
@ -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
|
||||||
|
@ -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 \
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
3165
gcc/tree-ssa-structalias.c
Normal file
File diff suppressed because it is too large
Load Diff
33
gcc/tree-ssa-structalias.h
Normal file
33
gcc/tree-ssa-structalias.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user