diff options
-rw-r--r-- | gcc/ChangeLog | 35 | ||||
-rw-r--r-- | gcc/Makefile.in | 7 | ||||
-rw-r--r-- | gcc/alias.c | 114 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 129 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 58 | ||||
-rw-r--r-- | gcc/final.c | 3 | ||||
-rw-r--r-- | gcc/print-rtl.c | 54 | ||||
-rw-r--r-- | gcc/tree-dfa.c | 2 | ||||
-rw-r--r-- | gcc/tree-flow.h | 4 | ||||
-rw-r--r-- | gcc/tree-optimize.c | 4 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.h | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 22 | ||||
-rw-r--r-- | gcc/tree-ssa.c | 46 |
14 files changed, 319 insertions, 163 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cabfbe6..519c7cf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,38 @@ +2009-07-14 Richard Guenther <rguenther@suse.de> + Andrey Belevantsev <abel@ispras.ru> + + * tree-ssa-alias.h (refs_may_alias_p_1): Declare. + (pt_solution_set): Likewise. + * tree-ssa-alias.c (refs_may_alias_p_1): Export. + * tree-ssa-structalias.c (pt_solution_set): New function. + * final.c (rest_of_clean_state): Free SSA data structures. + * print-rtl.c (print_decl_name): Remove. + (print_mem_expr): Implement in terms of print_generic_expr. + * alias.c (ao_ref_from_mem): New function. + (rtx_refs_may_alias_p): Likewise. + (true_dependence): Query alias-export info. + (canon_true_dependence): Likewise. + (write_dependence_p): Likewise. + * tree-dfa.c (get_ref_base_and_extent): For void types leave + size unknown. + * emit-rtl.c (component_ref_for_mem_expr): Remove. + (mem_expr_equal_p): Use operand_equal_p. + (set_mem_attributes_minus_bitpos): Do not use + component_ref_for_mem_expr. + * cfgexpand.c (add_partitioned_vars_to_ptset): New function. + (update_alias_info_with_stack_vars): Likewise. + (partition_stack_vars): Call update_alias_info_with_stack_vars. + * tree-ssa.c (delete_tree_ssa): Do not release SSA names + explicitly nor clear stmt operands. + Free the decl-to-pointer map. + * tree-optimize.c (execute_free_datastructures): Do not free + SSA data structures here. + * tree-flow.h (struct gimple_df): Add decls_to_pointers member. + * Makefile.in (emit-rtl.o): Add pointer-set.h dependency. + (alias.o): Add tree-ssa-alias.h, pointer-set.h and $(TREE_FLOW_H) + dependencies. + (print-rtl.o): Add $(DIAGNOSTIC_H) dependency. + 2009-07-13 DJ Delorie <dj@redhat.com> * config/mep/mep.h (CC1_SPEC): Tweak parameters to trigger diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 9cdf6a2..9567dfe 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2565,7 +2565,7 @@ rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \ - $(BCONFIG_H) $(REAL_H) + $(BCONFIG_H) $(REAL_H) $(DIAGNOSTIC_H) rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \ $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \ $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \ @@ -2653,7 +2653,7 @@ emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \ $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \ $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h $(TREE_PASS_H) gt-emit-rtl.h \ - $(REAL_H) $(DF_H) + $(REAL_H) $(DF_H) pointer-set.h real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ @@ -2978,7 +2978,8 @@ alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) $(TOPLEV_H) output.h \ $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \ langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) \ - $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) $(TREE_PASS_H) + $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) $(TREE_PASS_H) \ + tree-ssa-alias.h pointer-set.h $(TREE_FLOW_H) stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) $(TREE_PASS_H) \ $(BASIC_BLOCK_H) $(FLAGS_H) output.h $(DF_H) diff --git a/gcc/alias.c b/gcc/alias.c index 2486001..e9cc2d8 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -46,6 +46,9 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "ipa-type-escape.h" #include "df.h" +#include "tree-ssa-alias.h" +#include "pointer-set.h" +#include "tree-flow.h" /* The aliasing API provided here solves related but different problems: @@ -249,6 +252,98 @@ DEF_VEC_ALLOC_P(alias_set_entry,gc); /* The splay-tree used to store the various alias set entries. */ static GTY (()) VEC(alias_set_entry,gc) *alias_sets; +/* Build a decomposed reference object for querying the alias-oracle + from the MEM rtx and store it in *REF. + Returns false if MEM is not suitable for the alias-oracle. */ + +static bool +ao_ref_from_mem (ao_ref *ref, const_rtx mem) +{ + tree expr = MEM_EXPR (mem); + tree base; + + if (!expr) + return false; + + ao_ref_init (ref, expr); + + /* Get the base of the reference and see if we have to reject or + adjust it. */ + base = ao_ref_base (ref); + if (base == NULL_TREE) + return false; + + /* If this is a pointer dereference of a non-SSA_NAME punt. + ??? We could replace it with a pointer to anything. */ + if (INDIRECT_REF_P (base) + && TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME) + return false; + + /* If this is a reference based on a partitioned decl replace the + base with an INDIRECT_REF of the pointer representative we + created during stack slot partitioning. */ + if (TREE_CODE (base) == VAR_DECL + && ! TREE_STATIC (base) + && cfun->gimple_df->decls_to_pointers != NULL) + { + void *namep; + namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base); + if (namep) + { + ref->base_alias_set = get_alias_set (base); + ref->base = build1 (INDIRECT_REF, TREE_TYPE (base), *(tree *)namep); + } + } + + ref->ref_alias_set = MEM_ALIAS_SET (mem); + + /* For NULL MEM_OFFSET the MEM_EXPR may have been stripped arbitrarily + without recording offset or extent adjustments properly. */ + if (MEM_OFFSET (mem) == NULL_RTX) + { + ref->offset = 0; + ref->max_size = -1; + } + else + { + ref->offset += INTVAL (MEM_OFFSET (mem)) * BITS_PER_UNIT; + } + + /* NULL MEM_SIZE should not really happen with a non-NULL MEM_EXPR, + but just play safe here. The size may have been adjusted together + with the offset, so we need to take it if it is set and not rely + on MEM_EXPR here (which has the size determining parts potentially + stripped anyway). We lose precision for max_size which is only + available from the remaining MEM_EXPR. */ + if (MEM_SIZE (mem) == NULL_RTX) + { + ref->size = -1; + ref->max_size = -1; + } + else + { + ref->size = INTVAL (MEM_SIZE (mem)) * BITS_PER_UNIT; + } + + return true; +} + +/* Query the alias-oracle on whether the two memory rtx X and MEM may + alias. If TBAA_P is set also apply TBAA. Returns true if the + two rtxen may alias, false otherwise. */ + +static bool +rtx_refs_may_alias_p (const_rtx x, const_rtx mem, bool tbaa_p) +{ + ao_ref ref1, ref2; + + if (!ao_ref_from_mem (&ref1, x) + || !ao_ref_from_mem (&ref2, mem)) + return true; + + return refs_may_alias_p_1 (&ref1, &ref2, tbaa_p); +} + /* Returns a pointer to the alias set entry for ALIAS_SET, if there is such an entry, or NULL otherwise. */ @@ -2191,8 +2286,10 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x, if (mem_mode == BLKmode || GET_MODE (x) == BLKmode) return 1; - return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, - varies); + if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies)) + return 0; + + return rtx_refs_may_alias_p (x, mem, true); } /* Canonical true dependence: X is read after store in MEM takes place. @@ -2255,8 +2352,10 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, if (mem_mode == BLKmode || GET_MODE (x) == BLKmode) return 1; - return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, - varies); + if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies)) + return 0; + + return rtx_refs_may_alias_p (x, mem, true); } /* Returns nonzero if a write to X might alias a previous read from @@ -2316,8 +2415,11 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep) = fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, rtx_addr_varies_p); - return (!(fixed_scalar == mem && !aliases_everything_p (x)) - && !(fixed_scalar == x && !aliases_everything_p (mem))); + if ((fixed_scalar == mem && !aliases_everything_p (x)) + || (fixed_scalar == x && !aliases_everything_p (mem))) + return 0; + + return rtx_refs_may_alias_p (x, mem, false); } /* Anti dependence: X is written after read in MEM takes place. */ diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index c8d19fb1..89a7363 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -784,6 +784,133 @@ stack_var_size_cmp (const void *a, const void *b) return 0; } + +/* If the points-to solution *PI points to variables that are in a partition + together with other variables add all partition members to the pointed-to + variables bitmap. */ + +static void +add_partitioned_vars_to_ptset (struct pt_solution *pt, + struct pointer_map_t *decls_to_partitions, + struct pointer_set_t *visited, bitmap temp) +{ + bitmap_iterator bi; + unsigned i; + bitmap *part; + + if (pt->anything + || pt->vars == NULL + /* The pointed-to vars bitmap is shared, it is enough to + visit it once. */ + || pointer_set_insert(visited, pt->vars)) + return; + + bitmap_clear (temp); + + /* By using a temporary bitmap to store all members of the partitions + we have to add we make sure to visit each of the partitions only + once. */ + EXECUTE_IF_SET_IN_BITMAP (pt->vars, 0, i, bi) + if ((!temp + || !bitmap_bit_p (temp, i)) + && (part = (bitmap *) pointer_map_contains (decls_to_partitions, + (void *)(size_t) i))) + bitmap_ior_into (temp, *part); + if (!bitmap_empty_p (temp)) + bitmap_ior_into (pt->vars, temp); +} + +/* Update points-to sets based on partition info, so we can use them on RTL. + The bitmaps representing stack partitions will be saved until expand, + where partitioned decls used as bases in memory expressions will be + rewritten. */ + +static void +update_alias_info_with_stack_vars (void) +{ + struct pointer_map_t *decls_to_partitions = NULL; + size_t i, j; + tree var = NULL_TREE; + + for (i = 0; i < stack_vars_num; i++) + { + bitmap part = NULL; + tree name; + struct ptr_info_def *pi; + + /* Not interested in partitions with single variable. */ + if (stack_vars[i].representative != i + || stack_vars[i].next == EOC) + continue; + + if (!decls_to_partitions) + { + decls_to_partitions = pointer_map_create (); + cfun->gimple_df->decls_to_pointers = pointer_map_create (); + } + + /* Create an SSA_NAME that points to the partition for use + as base during alias-oracle queries on RTL for bases that + have been partitioned. */ + if (var == NULL_TREE) + var = create_tmp_var (ptr_type_node, NULL); + name = make_ssa_name (var, NULL); + + /* Create bitmaps representing partitions. They will be used for + points-to sets later, so use GGC alloc. */ + part = BITMAP_GGC_ALLOC (); + for (j = i; j != EOC; j = stack_vars[j].next) + { + tree decl = stack_vars[j].decl; + unsigned int uid = DECL_UID (decl); + /* We should never end up partitioning SSA names (though they + may end up on the stack). Neither should we allocate stack + space to something that is unused and thus unreferenced. */ + gcc_assert (DECL_P (decl) + && referenced_var_lookup (uid)); + bitmap_set_bit (part, uid); + *((bitmap *) pointer_map_insert (decls_to_partitions, + (void *)(size_t) uid)) = part; + *((tree *) pointer_map_insert (cfun->gimple_df->decls_to_pointers, + decl)) = name; + } + + /* Make the SSA name point to all partition members. */ + pi = get_ptr_info (name); + pt_solution_set (&pi->pt, part); + } + + /* Make all points-to sets that contain one member of a partition + contain all members of the partition. */ + if (decls_to_partitions) + { + unsigned i; + struct pointer_set_t *visited = pointer_set_create (); + bitmap temp = BITMAP_ALLOC (NULL); + + for (i = 1; i < num_ssa_names; i++) + { + tree name = ssa_name (i); + struct ptr_info_def *pi; + + if (name + && POINTER_TYPE_P (TREE_TYPE (name)) + && ((pi = SSA_NAME_PTR_INFO (name)) != NULL)) + add_partitioned_vars_to_ptset (&pi->pt, decls_to_partitions, + visited, temp); + } + + add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped, + decls_to_partitions, visited, temp); + add_partitioned_vars_to_ptset (&cfun->gimple_df->callused, + decls_to_partitions, visited, temp); + + pointer_set_destroy (visited); + pointer_map_destroy (decls_to_partitions); + BITMAP_FREE (temp); + } +} + /* A subroutine of partition_stack_vars. The UNION portion of a UNION/FIND partitioning algorithm. Partitions A and B are known to be non-conflicting. Merge them into a single partition A. @@ -903,6 +1030,8 @@ partition_stack_vars (void) break; } } + + update_alias_info_with_stack_vars (); } /* A debugging aid for expand_used_vars. Dump the generated partitions. */ diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index d20f2b5..5b42f4a 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -197,7 +197,6 @@ static mem_attrs *get_mem_attrs (alias_set_type, tree, rtx, rtx, unsigned int, static hashval_t reg_attrs_htab_hash (const void *); static int reg_attrs_htab_eq (const void *, const void *); static reg_attrs *get_reg_attrs (tree, int); -static tree component_ref_for_mem_expr (tree); static rtx gen_const_vector (enum machine_mode, int); static void copy_rtx_if_shared_1 (rtx *orig); @@ -1429,40 +1428,6 @@ operand_subword_force (rtx op, unsigned int offset, enum machine_mode mode) return result; } -/* Within a MEM_EXPR, we care about either (1) a component ref of a decl, - or (2) a component ref of something variable. Represent the later with - a NULL expression. */ - -static tree -component_ref_for_mem_expr (tree ref) -{ - tree inner = TREE_OPERAND (ref, 0); - - if (TREE_CODE (inner) == COMPONENT_REF) - inner = component_ref_for_mem_expr (inner); - else - { - /* Now remove any conversions: they don't change what the underlying - object is. Likewise for SAVE_EXPR. */ - while (CONVERT_EXPR_P (inner) - || TREE_CODE (inner) == VIEW_CONVERT_EXPR - || TREE_CODE (inner) == SAVE_EXPR) - inner = TREE_OPERAND (inner, 0); - - if (! DECL_P (inner)) - inner = NULL_TREE; - } - - if (inner == TREE_OPERAND (ref, 0) - /* Don't leak SSA-names in the third operand. */ - && (!TREE_OPERAND (ref, 2) - || TREE_CODE (TREE_OPERAND (ref, 2)) != SSA_NAME)) - return ref; - else - return build3 (COMPONENT_REF, TREE_TYPE (ref), inner, - TREE_OPERAND (ref, 1), NULL_TREE); -} - /* Returns 1 if both MEM_EXPR can be considered equal and 0 otherwise. */ @@ -1478,23 +1443,7 @@ mem_expr_equal_p (const_tree expr1, const_tree expr2) if (TREE_CODE (expr1) != TREE_CODE (expr2)) return 0; - if (TREE_CODE (expr1) == COMPONENT_REF) - return - mem_expr_equal_p (TREE_OPERAND (expr1, 0), - TREE_OPERAND (expr2, 0)) - && mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */ - TREE_OPERAND (expr2, 1)); - - if (INDIRECT_REF_P (expr1)) - return mem_expr_equal_p (TREE_OPERAND (expr1, 0), - TREE_OPERAND (expr2, 0)); - - /* ARRAY_REFs, ARRAY_RANGE_REFs and BIT_FIELD_REFs should already - have been resolved here. */ - gcc_assert (DECL_P (expr1)); - - /* Decls with different pointers can't be equal. */ - return 0; + return operand_equal_p (expr1, expr2, 0); } /* Return OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN @@ -1732,7 +1681,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, else if (TREE_CODE (t) == COMPONENT_REF && ! DECL_BIT_FIELD (TREE_OPERAND (t, 1))) { - expr = component_ref_for_mem_expr (t); + expr = t; offset = const0_rtx; apply_bitpos = bitpos; /* ??? Any reason the field size would be different than @@ -1789,7 +1738,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, } else if (TREE_CODE (t2) == COMPONENT_REF) { - expr = component_ref_for_mem_expr (t2); + expr = t2; + offset = NULL; if (host_integerp (off_tree, 1)) { offset = GEN_INT (tree_low_cst (off_tree, 1)); diff --git a/gcc/final.c b/gcc/final.c index 2508443..e84c2ca 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see #include "expr.h" #include "cfglayout.h" #include "tree-pass.h" +#include "tree-flow.h" #include "timevar.h" #include "cgraph.h" #include "coverage.h" @@ -4422,6 +4423,8 @@ rest_of_clean_state (void) free_bb_for_insn (); + delete_tree_ssa (); + if (targetm.binds_local_p (current_function_decl)) { unsigned int pref = crtl->preferred_stack_boundary; diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index 7f8a6c9..fa02699 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "hard-reg-set.h" #include "basic-block.h" +#include "diagnostic.h" #endif static FILE *outfile; @@ -72,60 +73,11 @@ int flag_simple = 0; int dump_for_graph; #ifndef GENERATOR_FILE -static void -print_decl_name (FILE *outfile, const_tree node) -{ - if (DECL_NAME (node)) - fputs (IDENTIFIER_POINTER (DECL_NAME (node)), outfile); - else - { - if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1) - fprintf (outfile, "L.%d", (int) LABEL_DECL_UID (node)); - else - { - char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D'; - fprintf (outfile, "%c.%u", c, DECL_UID (node)); - } - } -} - void print_mem_expr (FILE *outfile, const_tree expr) { - if (TREE_CODE (expr) == COMPONENT_REF) - { - if (TREE_OPERAND (expr, 0)) - print_mem_expr (outfile, TREE_OPERAND (expr, 0)); - else - fputs (" <variable>", outfile); - fputc ('.', outfile); - print_decl_name (outfile, TREE_OPERAND (expr, 1)); - } - else if (TREE_CODE (expr) == INDIRECT_REF) - { - fputs (" (*", outfile); - print_mem_expr (outfile, TREE_OPERAND (expr, 0)); - fputs (")", outfile); - } - else if (TREE_CODE (expr) == ALIGN_INDIRECT_REF) - { - fputs (" (A*", outfile); - print_mem_expr (outfile, TREE_OPERAND (expr, 0)); - fputs (")", outfile); - } - else if (TREE_CODE (expr) == MISALIGNED_INDIRECT_REF) - { - fputs (" (M*", outfile); - print_mem_expr (outfile, TREE_OPERAND (expr, 0)); - fputs (")", outfile); - } - else if (TREE_CODE (expr) == RESULT_DECL) - fputs (" <result>", outfile); - else - { - fputc (' ', outfile); - print_decl_name (outfile, expr); - } + fputc (' ', outfile); + print_generic_expr (outfile, CONST_CAST_TREE (expr), 0); } #endif diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 64c5e26..1067a43 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -729,7 +729,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, size_tree = DECL_SIZE (TREE_OPERAND (exp, 1)); else if (TREE_CODE (exp) == BIT_FIELD_REF) size_tree = TREE_OPERAND (exp, 1); - else + else if (!VOID_TYPE_P (TREE_TYPE (exp))) { enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); if (mode == BLKmode) diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index c773310..cec5ed7 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -63,6 +63,10 @@ struct GTY(()) gimple_df { /* The PTA solution for the CALLUSED artificial variable. */ struct pt_solution callused; + /* A map of decls to artificial ssa-names that point to the partition + of the decl. */ + struct pointer_map_t * GTY((skip(""))) decls_to_pointers; + /* Free list of SSA_NAMEs. */ tree free_ssanames; diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 765e021..7a9d2bd 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -226,10 +226,6 @@ execute_free_datastructures (void) free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); - /* Remove the ssa structures. */ - if (cfun->gimple_df) - delete_tree_ssa (); - /* And get rid of annotations we no longer need. */ delete_tree_cfg_annotations (); diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 4d72187..92297fc 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -724,7 +724,7 @@ indirect_refs_may_alias_p (tree ref1, tree ptr1, /* Return true, if the two memory references REF1 and REF2 may alias. */ -static bool +bool refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) { tree base1, base2; diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index 2be903f..3a08750 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -92,6 +92,7 @@ extern tree ao_ref_base (ao_ref *); extern alias_set_type ao_ref_alias_set (ao_ref *); extern bool ptr_deref_may_alias_global_p (tree); extern bool refs_may_alias_p (tree, tree); +extern bool refs_may_alias_p_1 (ao_ref *, ao_ref *, bool); extern bool refs_anti_dependent_p (tree, tree); extern bool refs_output_dependent_p (tree, tree); extern bool ref_maybe_used_by_stmt_p (gimple, tree); @@ -121,6 +122,7 @@ extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution *); extern bool pt_solutions_same_restrict_base (struct pt_solution *, struct pt_solution *); extern void pt_solution_reset (struct pt_solution *); +extern void pt_solution_set (struct pt_solution *, bitmap); extern void dump_pta_stats (FILE *); diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 303bd1f..7e7e8e4 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4886,6 +4886,28 @@ pt_solution_reset (struct pt_solution *pt) pt->anything = true; } +/* Set the points-to solution *PT to point only to the variables + in VARS. */ + +void +pt_solution_set (struct pt_solution *pt, bitmap vars) +{ + bitmap_iterator bi; + unsigned i; + + memset (pt, 0, sizeof (struct pt_solution)); + pt->vars = vars; + EXECUTE_IF_SET_IN_BITMAP (vars, 0, i, bi) + { + tree var = referenced_var_lookup (i); + if (is_global_var (var)) + { + pt->vars_contains_global = true; + break; + } + } +} + /* Return true if the points-to solution *PT is empty. */ static bool diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index c8a48a3..7ec04f7 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -802,52 +802,9 @@ init_tree_ssa (struct function *fn) void delete_tree_ssa (void) { - size_t i; - basic_block bb; - gimple_stmt_iterator gsi; referenced_var_iterator rvi; tree var; - /* Release any ssa_names still in use. */ - for (i = 0; i < num_ssa_names; i++) - { - tree var = ssa_name (i); - if (var && TREE_CODE (var) == SSA_NAME) - { - SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var)); - SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var)); - } - release_ssa_name (var); - } - - /* FIXME. This may not be necessary. We will release all this - memory en masse in free_ssa_operands. This clearing used to be - necessary to avoid problems with the inliner, but it may not be - needed anymore. */ - FOR_EACH_BB (bb) - { - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - - if (gimple_has_ops (stmt)) - { - gimple_set_def_ops (stmt, NULL); - gimple_set_use_ops (stmt, NULL); - } - - if (gimple_has_mem_ops (stmt)) - { - gimple_set_vdef (stmt, NULL_TREE); - gimple_set_vuse (stmt, NULL_TREE); - } - - gimple_set_modified (stmt, true); - } - if (!(bb->flags & BB_RTL)) - set_phi_nodes (bb, NULL); - } - /* Remove annotations from every referenced local variable. */ FOR_EACH_REFERENCED_VAR (var, rvi) { @@ -873,6 +830,9 @@ delete_tree_ssa (void) cfun->gimple_df->default_defs = NULL; pt_solution_reset (&cfun->gimple_df->escaped); pt_solution_reset (&cfun->gimple_df->callused); + if (cfun->gimple_df->decls_to_pointers != NULL) + pointer_map_destroy (cfun->gimple_df->decls_to_pointers); + cfun->gimple_df->decls_to_pointers = NULL; cfun->gimple_df->modified_noreturn_calls = NULL; cfun->gimple_df = NULL; |