OSDN Git Service

2010-04-12 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Apr 2010 15:20:48 +0000 (15:20 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 05:31:41 +0000 (14:31 +0900)
* gsstruct.def (GSS_CALL): New.
* gimple.def (GIMPLE_CALL): Change to GSS_CALL.
* gimple.h: Include tree-ssa-alias.h.
(struct gimple_statement_call): New.
(union gimple_statement_struct_d): Add gimple_call member.
(gimple_call_reset_alias_info): Declare.
(gimple_call_use_set): New function.
(gimple_call_clobber_set): Likewise.
* Makefile.in (GIMPLE_H): Add tree-ssa-alias.h.
* gimple.c (gimple_call_reset_alias_info): New function.
(gimple_build_call_1): Call it.
* lto-streamer-in.c (input_gimple_stmt): Likewise.
* tree-inline.c (remap_gimple_stmt): Likewise.
(expand_call_inline): Remove callused handling.
* cfgexpand.c (update_alias_info_with_stack_vars): Likewise.
* tree-dfa.c (dump_variable): Likewise.
* tree-parloops.c (parallelize_loops): Likewise.
* tree-ssa.c (init_tree_ssa): Likewise.
(delete_tree_ssa): Likewise.
* tree-flow-inline.h (is_call_used): Remove.
* tree-flow.h (struct gimple_df): Remove callused member.
* tree-nrv.c (dest_safe_for_nrv_p): Adjust predicate.
* tree-ssa-alias.c (dump_alias_info): Remove callused handling.
(ref_maybe_used_by_call_p_1): Simplify.
(call_may_clobber_ref_p_1): Likewise.
* tree-ssa-structalias.c (compute_points_to_sets): Set
the call stmt used and clobbered sets.
* tree-tailcall.c (suitable_for_tail_opt_p): Adjust predicate.
(find_tail_calls): Verify the tail call.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158226 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/gimple.h
gcc/tree-dfa.c
gcc/tree-flow-inline.h
gcc/tree-inline.c
gcc/tree-nrv.c
gcc/tree-ssa-structalias.c
gcc/tree-tailcall.c

index 464ca7e..016992a 100644 (file)
@@ -1,5 +1,37 @@
 2010-04-12  Richard Guenther  <rguenther@suse.de>
 
+       * gsstruct.def (GSS_CALL): New.
+       * gimple.def (GIMPLE_CALL): Change to GSS_CALL.
+       * gimple.h: Include tree-ssa-alias.h.
+       (struct gimple_statement_call): New.
+       (union gimple_statement_struct_d): Add gimple_call member.
+       (gimple_call_reset_alias_info): Declare.
+       (gimple_call_use_set): New function.
+       (gimple_call_clobber_set): Likewise.
+       * Makefile.in (GIMPLE_H): Add tree-ssa-alias.h.
+       * gimple.c (gimple_call_reset_alias_info): New function.
+       (gimple_build_call_1): Call it.
+       * lto-streamer-in.c (input_gimple_stmt): Likewise.
+       * tree-inline.c (remap_gimple_stmt): Likewise.
+       (expand_call_inline): Remove callused handling.
+       * cfgexpand.c (update_alias_info_with_stack_vars): Likewise.
+       * tree-dfa.c (dump_variable): Likewise.
+       * tree-parloops.c (parallelize_loops): Likewise.
+       * tree-ssa.c (init_tree_ssa): Likewise.
+       (delete_tree_ssa): Likewise.
+       * tree-flow-inline.h (is_call_used): Remove.
+       * tree-flow.h (struct gimple_df): Remove callused member.
+       * tree-nrv.c (dest_safe_for_nrv_p): Adjust predicate.
+       * tree-ssa-alias.c (dump_alias_info): Remove callused handling.
+       (ref_maybe_used_by_call_p_1): Simplify.
+       (call_may_clobber_ref_p_1): Likewise.
+       * tree-ssa-structalias.c (compute_points_to_sets): Set
+       the call stmt used and clobbered sets.
+       * tree-tailcall.c (suitable_for_tail_opt_p): Adjust predicate.
+       (find_tail_calls): Verify the tail call.
+
+2010-04-12  Richard Guenther  <rguenther@suse.de>
+
        * ipa.c (cgraph_postorder): Adjust postorder to guarantee
        single-iteration always-inline inlining.
        * ipa-inline.c (cgraph_mark_inline): Do not return anything.
index 18b0758..7324e5b 100644 (file)
@@ -881,7 +881,7 @@ BASIC_BLOCK_H = basic-block.h $(BITMAP_H) sbitmap.h $(PARTITION_H) \
           cfghooks.h $(OBSTACK_H)
 GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h vec.h \
        $(GGC_H) $(BASIC_BLOCK_H) $(TM_H) $(TARGET_H) tree-ssa-operands.h \
-       tree-ssa-alias.h vecir.h
+       tree-ssa-alias.h
 GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
 COVERAGE_H = coverage.h $(GCOV_IO_H)
 DEMANGLE_H = $(srcdir)/../include/demangle.h
index baa839f..22955d2 100644 (file)
@@ -33,6 +33,18 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-operands.h"
 #include "tree-ssa-alias.h"
 
+DEF_VEC_P(gimple);
+DEF_VEC_ALLOC_P(gimple,heap);
+DEF_VEC_ALLOC_P(gimple,gc);
+
+typedef gimple *gimple_p;
+DEF_VEC_P(gimple_p);
+DEF_VEC_ALLOC_P(gimple_p,heap);
+
+DEF_VEC_P(gimple_seq);
+DEF_VEC_ALLOC_P(gimple_seq,gc);
+DEF_VEC_ALLOC_P(gimple_seq,heap);
+
 /* For each block, the PHI nodes that need to be rewritten are stored into
    these vectors.  */
 typedef VEC(gimple, heap) *gimple_vec;
@@ -855,8 +867,6 @@ void gimple_seq_free (gimple_seq);
 void gimple_seq_add_seq (gimple_seq *, gimple_seq);
 gimple_seq gimple_seq_copy (gimple_seq);
 int gimple_call_flags (const_gimple);
-int gimple_call_return_flags (const_gimple);
-int gimple_call_arg_flags (const_gimple, unsigned);
 void gimple_call_reset_alias_info (gimple);
 bool gimple_assign_copy_p (gimple);
 bool gimple_assign_ssa_name_copy_p (gimple);
index d5a56e5..5f9262f 100644 (file)
@@ -280,6 +280,9 @@ dump_variable (FILE *file, tree var)
   if (TREE_THIS_VOLATILE (var))
     fprintf (file, ", is volatile");
 
+  if (is_call_clobbered (var))
+    fprintf (file, ", call clobbered");
+
   if (ann && ann->noalias_state == NO_ALIAS)
     fprintf (file, ", NO_ALIAS (does not alias other NO_ALIAS symbols)");
   else if (ann && ann->noalias_state == NO_ALIAS_GLOBAL)
index f7609ea..2430f03 100644 (file)
@@ -624,6 +624,15 @@ loop_containing_stmt (gimple stmt)
 }
 
 
+/* Return true if VAR is clobbered by function calls.  */
+static inline bool
+is_call_clobbered (const_tree var)
+{
+  return (is_global_var (var)
+         || (may_be_aliased (var)
+             && pt_solution_includes (&cfun->gimple_df->escaped, var)));
+}
+
 /*  -----------------------------------------------------------------------  */
 
 /* The following set of routines are used to iterator over various type of
index bb2ee23..64d29c6 100644 (file)
@@ -1411,11 +1411,12 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
                    break;
                  }
 
-             /* Reset alias info if we didn't apply measures to
-                keep it valid over inlining by setting DECL_PT_UID.  */
-             if (!id->src_cfun->gimple_df
-                 || !id->src_cfun->gimple_df->ipa_pta)
-               gimple_call_reset_alias_info (copy);
+             /* Reset alias info.
+                ???  By maintaining DECL_PT_UID this should not
+                be necessary, but the plan is to only maintain
+                it when IPA-PTA was run.  It's not too easy to
+                detect this here ...  */
+             gimple_call_reset_alias_info (copy);
            }
            break;
 
index c2e49d3..1844002 100644 (file)
@@ -305,7 +305,7 @@ dest_safe_for_nrv_p (gimple call)
   if (TREE_CODE (dest) == SSA_NAME)
     return true;
 
-  if (call_may_clobber_ref_p (call, dest))
+  if (is_call_clobbered (dest))
     return false;
 
   return true;
index a45c6d5..a065e64 100644 (file)
@@ -6366,6 +6366,7 @@ compute_points_to_sets (void)
   basic_block bb;
   unsigned i;
   varinfo_t vi;
+  struct pt_solution callused;
 
   timevar_push (TV_TREE_PTA);
 
@@ -6407,6 +6408,7 @@ compute_points_to_sets (void)
   /* Compute the points-to set for ESCAPED used for call-clobber analysis.  */
   find_what_var_points_to (get_varinfo (escaped_id),
                           &cfun->gimple_df->escaped);
+  find_what_var_points_to (get_varinfo (callused_id), &callused);
 
   /* Make sure the ESCAPED solution (which is used as placeholder in
      other solutions) does not reference itself.  This simplifies
@@ -6445,11 +6447,11 @@ compute_points_to_sets (void)
          pt = gimple_call_use_set (stmt);
          if (gimple_call_flags (stmt) & ECF_CONST)
            memset (pt, 0, sizeof (struct pt_solution));
-         else if ((vi = lookup_call_use_vi (stmt)) != NULL)
+         else if (gimple_call_flags (stmt) & ECF_PURE)
            {
-             find_what_var_points_to (vi, pt);
-             /* Escaped (and thus nonlocal) variables are always
-                implicitly used by calls.  */
+             /* For const calls we should now be able to compute the
+                call-used set per function.  */
+             *pt = callused;
              /* ???  ESCAPED can be empty even though NONLOCAL
                 always escaped.  */
              pt->nonlocal = 1;
@@ -6457,8 +6459,6 @@ compute_points_to_sets (void)
            }
          else
            {
-             /* If there is nothing special about this call then
-                we have made everything that is used also escape.  */
              *pt = cfun->gimple_df->escaped;
              pt->nonlocal = 1;
            }
index ec6d2fd..969e07d 100644 (file)
@@ -133,6 +133,26 @@ suitable_for_tail_opt_p (void)
   if (cfun->stdarg)
     return false;
 
+  /* No local variable nor structure field should escape to callees.  */
+  FOR_EACH_REFERENCED_VAR (var, rvi)
+    {
+      if (!is_global_var (var)
+         /* ???  We do not have a suitable predicate for escaping to
+            callees.  With IPA-PTA the following might be incorrect.
+            We want to catch
+              foo {
+                int i;
+                bar (&i);
+                foo ();
+              }
+            where bar might store &i somewhere and in the next
+            recursion should not be able to tell if it got the
+            same (with tail-recursion applied) or a different
+            address.  */
+         && is_call_clobbered (var))
+       return false;
+    }
+
   return true;
 }
 /* Returns false when the function is not suitable for tail call optimization
@@ -421,7 +441,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
   func = gimple_call_fndecl (call);
   if (func == current_function_decl)
     {
-      tree arg;
+      tree arg, var;
+      referenced_var_iterator rvi;
 
       for (param = DECL_ARGUMENTS (func), idx = 0;
           param && idx < gimple_call_num_args (call);
@@ -452,6 +473,15 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
        }
       if (idx == gimple_call_num_args (call) && !param)
        tail_recursion = true;
+
+      /* Make sure the tail invocation of this function does not refer
+        to local variables.  */
+      FOR_EACH_REFERENCED_VAR (var, rvi)
+       {
+         if (!is_global_var (var)
+             && ref_maybe_used_by_stmt_p (call, var))
+           return;
+       }
     }
 
   /* Make sure the tail invocation of this function does not refer