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>
|
||||
|
||||
* 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 \
|
||||
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 \
|
||||
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)
|
||||
|
@ -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) \
|
||||
$(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.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) \
|
||||
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_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_bsi (block_stmt_iterator *, tree, bool, tree);
|
||||
|
||||
/* In tree-ssa-structalias.c */
|
||||
bool find_what_p_points_to (tree);
|
||||
|
||||
/* In tree-ssa-address.c */
|
||||
|
||||
/* 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);
|
||||
void get_address_description (tree, struct mem_address *);
|
||||
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"
|
||||
|
||||
|
|
|
@ -396,7 +396,9 @@ init_tree_optimization_passes (void)
|
|||
NEXT_PASS (pass_referenced_vars);
|
||||
NEXT_PASS (pass_create_structure_vars);
|
||||
NEXT_PASS (pass_build_ssa);
|
||||
NEXT_PASS (pass_build_pta);
|
||||
NEXT_PASS (pass_may_alias);
|
||||
NEXT_PASS (pass_del_pta);
|
||||
NEXT_PASS (pass_rename_ssa_copies);
|
||||
NEXT_PASS (pass_early_warn_uninitialized);
|
||||
|
||||
|
@ -412,7 +414,9 @@ init_tree_optimization_passes (void)
|
|||
NEXT_PASS (pass_dominator);
|
||||
|
||||
NEXT_PASS (pass_phiopt);
|
||||
NEXT_PASS (pass_build_pta);
|
||||
NEXT_PASS (pass_may_alias);
|
||||
NEXT_PASS (pass_del_pta);
|
||||
NEXT_PASS (pass_tail_recursion);
|
||||
NEXT_PASS (pass_profile);
|
||||
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_vrp;
|
||||
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_reassoc;
|
||||
|
||||
|
|
|
@ -874,7 +874,16 @@ static void
|
|||
compute_flow_sensitive_aliasing (struct alias_info *ai)
|
||||
{
|
||||
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);
|
||||
|
||||
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. */
|
||||
}
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
||||
typedef struct used_part
|
||||
|
@ -2925,22 +2858,6 @@ get_or_create_used_part_for (size_t uid)
|
|||
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
|
||||
fields. */
|
||||
|
@ -2956,7 +2873,7 @@ create_overlap_variables_for (tree var)
|
|||
return;
|
||||
|
||||
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)
|
||||
{
|
||||
subvar_t *subvars;
|
||||
|
@ -3024,10 +2941,7 @@ create_overlap_variables_for (tree var)
|
|||
/* Otherwise, create the variables. */
|
||||
subvars = lookup_subvars_for_var (var);
|
||||
|
||||
qsort (VEC_address (fieldoff_s, fieldstack),
|
||||
VEC_length (fieldoff_s, fieldstack),
|
||||
sizeof (fieldoff_s),
|
||||
fieldoff_compare);
|
||||
sort_fieldstack (fieldstack);
|
||||
|
||||
for (i = VEC_length (fieldoff_s, fieldstack);
|
||||
VEC_iterate (fieldoff_s, fieldstack, --i, fo);)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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