2009-03-30 Martin Jambor <mjambor@suse.cz>
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 30 Mar 2009 13:06:52 +0000 (13:06 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 30 Mar 2009 13:06:52 +0000 (13:06 +0000)
* ipa-prop.h (jump_func_type): Rename IPA_UNKNOWN, IPA_CONST,
IPA_CONST_MEMBER_PTR, and IPA_PASS_THROUGH to IPA_JF_UNKNOWN,
IPA_JF_CONST, IPA_JF_CONST_MEMBER_PTR, and IPA_JF_PASS_THROUGH
respectively.

* tree-dfa.c (get_ref_base_and_extent): Return -1 maxsize if
seen_variable_array_ref while also traversing a union.

* tree-inline.c (optimize_inline_calls): Do not call
cgraph_node_remove_callees.
* cgraphbuild.c (remove_cgraph_callee_edges): New function.
(pass_remove_cgraph_callee_edges): New variable.
* passes.c (init_optimization_passes): Add
pass_remove_cgraph_callee_edges after early inlining and before all
late intraprocedural passes.

* omp-low.c (expand_omp_taskreg): Always set current_function_decl.

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

gcc/ChangeLog
gcc/cgraphbuild.c
gcc/ipa-cp.c
gcc/ipa-prop.c
gcc/ipa-prop.h
gcc/omp-low.c
gcc/passes.c
gcc/tree-dfa.c
gcc/tree-inline.c
gcc/tree-pass.h

index 8f69691..1215863 100644 (file)
@@ -1,3 +1,23 @@
+2009-03-30  Martin Jambor  <mjambor@suse.cz>
+
+       * ipa-prop.h (jump_func_type): Rename IPA_UNKNOWN, IPA_CONST,
+       IPA_CONST_MEMBER_PTR, and IPA_PASS_THROUGH to IPA_JF_UNKNOWN,
+       IPA_JF_CONST, IPA_JF_CONST_MEMBER_PTR, and IPA_JF_PASS_THROUGH
+       respectively.
+
+       * tree-dfa.c (get_ref_base_and_extent): Return -1 maxsize if
+       seen_variable_array_ref while also traversing a union.
+
+       * tree-inline.c (optimize_inline_calls): Do not call
+       cgraph_node_remove_callees.
+       * cgraphbuild.c (remove_cgraph_callee_edges): New function.
+       (pass_remove_cgraph_callee_edges): New variable.
+       * passes.c (init_optimization_passes): Add
+       pass_remove_cgraph_callee_edges after early inlining and before all
+       late intraprocedural passes.
+
+       * omp-low.c (expand_omp_taskreg): Always set current_function_decl.
+
 2009-03-30  Paolo Bonzini  <bonzini@gnu.org>
 
        * config/sparc/sparc.md (*nand<V64mode>_vis, *nand<V32mode>_vis):
index 3868712..c7d6aa7 100644 (file)
@@ -251,3 +251,30 @@ struct gimple_opt_pass pass_rebuild_cgraph_edges =
   0,                                   /* todo_flags_finish */
  }
 };
+
+
+static unsigned int
+remove_cgraph_callee_edges (void)
+{
+  cgraph_node_remove_callees (cgraph_node (current_function_decl));
+  return 0;
+}
+
+struct gimple_opt_pass pass_remove_cgraph_callee_edges =
+{
+ {
+  GIMPLE_PASS,
+  NULL,                                        /* name */
+  NULL,                                        /* gate */
+  remove_cgraph_callee_edges,          /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  0,                                   /* tv_id */
+  0,                                   /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  0,                                   /* todo_flags_finish */
+ }
+};
index f6864bb..3fae029 100644 (file)
@@ -310,12 +310,12 @@ static void
 ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
                         struct ipa_jump_func *jfunc)
 {
-  if (jfunc->type == IPA_CONST)
+  if (jfunc->type == IPA_JF_CONST)
     {
       lat->type = IPA_CONST_VALUE;
       lat->constant = jfunc->value.constant;
     }
-  else if (jfunc->type == IPA_PASS_THROUGH)
+  else if (jfunc->type == IPA_JF_PASS_THROUGH)
     {
       struct ipcp_lattice *caller_lat;
 
@@ -916,7 +916,7 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
       if (ipcp_lat_is_const (lat))
        {
          jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
-         if (jump_func->type != IPA_CONST)
+         if (jump_func->type != IPA_JF_CONST)
            return true;
        }
     }
index c8db7d2..eab3aa7 100644 (file)
@@ -293,16 +293,16 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
          type = jump_func->type;
 
          fprintf (f, "       param %d: ", i);
-         if (type == IPA_UNKNOWN)
+         if (type == IPA_JF_UNKNOWN)
            fprintf (f, "UNKNOWN\n");
-         else if (type == IPA_CONST)
+         else if (type == IPA_JF_CONST)
            {
              tree val = jump_func->value.constant;
              fprintf (f, "CONST: ");
              print_generic_expr (f, val, 0);
              fprintf (f, "\n");
            }
-         else if (type == IPA_CONST_MEMBER_PTR)
+         else if (type == IPA_JF_CONST_MEMBER_PTR)
            {
              fprintf (f, "CONST MEMBER PTR: ");
              print_generic_expr (f, jump_func->value.member_cst.pfn, 0);
@@ -310,7 +310,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
              print_generic_expr (f, jump_func->value.member_cst.delta, 0);
              fprintf (f, "\n");
            }
-         else if (type == IPA_PASS_THROUGH)
+         else if (type == IPA_JF_PASS_THROUGH)
            {
              fprintf (f, "PASS THROUGH: ");
              fprintf (f, "%d\n", jump_func->value.formal_id);
@@ -353,7 +353,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info,
 
       if (is_gimple_ip_invariant (arg))
        {
-         functions[num].type = IPA_CONST;
+         functions[num].type = IPA_JF_CONST;
          functions[num].value.constant = arg;
        }
       else if ((TREE_CODE (arg) == SSA_NAME) && SSA_NAME_IS_DEFAULT_DEF (arg))
@@ -362,7 +362,7 @@ compute_scalar_jump_functions (struct ipa_node_params *info,
 
          if (index >= 0)
            {
-             functions[num].type = IPA_PASS_THROUGH;
+             functions[num].type = IPA_JF_PASS_THROUGH;
              functions[num].value.formal_id = index;
            }
        }
@@ -430,7 +430,7 @@ compute_pass_through_member_ptrs (struct ipa_node_params *info,
              gcc_assert (index >=0);
              if (!ipa_is_param_modified (info, index))
                {
-                 functions[num].type = IPA_PASS_THROUGH;
+                 functions[num].type = IPA_JF_PASS_THROUGH;
                  functions[num].value.formal_id = index;
                }
              else
@@ -451,7 +451,7 @@ static void
 fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
                                   tree pfn, tree delta)
 {
-  jfunc->type = IPA_CONST_MEMBER_PTR;
+  jfunc->type = IPA_JF_CONST_MEMBER_PTR;
   jfunc->value.member_cst.pfn = pfn;
   jfunc->value.member_cst.delta = delta;
 }
@@ -545,7 +545,7 @@ compute_cst_member_ptr_arguments (struct ipa_jump_func *functions,
     {
       arg = gimple_call_arg (call, num);
 
-      if (functions[num].type == IPA_UNKNOWN
+      if (functions[num].type == IPA_JF_UNKNOWN
          && type_like_member_ptr_p (TREE_TYPE (arg), &method_field,
                                     &delta_field))
        determine_cst_member_ptr (call, arg, method_field, delta_field,
@@ -885,7 +885,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
     {
       struct ipa_jump_func *src, *dst = ipa_get_ith_jump_func (args, i);
 
-      if (dst->type != IPA_PASS_THROUGH)
+      if (dst->type != IPA_JF_PASS_THROUGH)
        continue;
 
       /* We must check range due to calls with variable number of arguments:  */
@@ -910,7 +910,7 @@ print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt,
                             struct cgraph_node *node)
 {
   fprintf (f, "ipa-prop: Discovered an indirect call to a known target (");
-  if (jfunc->type == IPA_CONST_MEMBER_PTR)
+  if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
     {
       print_node_brief (f, "", jfunc->value.member_cst.pfn, 0);
       print_node_brief (f, ", ", jfunc->value.member_cst.delta, 0);
@@ -953,16 +953,17 @@ update_call_notes_after_inlining (struct cgraph_edge *cs,
        }
 
       jfunc = ipa_get_ith_jump_func (top, nt->formal_id);
-      if (jfunc->type == IPA_PASS_THROUGH)
+      if (jfunc->type == IPA_JF_PASS_THROUGH)
        nt->formal_id = jfunc->value.formal_id;
-      else if (jfunc->type == IPA_CONST || jfunc->type == IPA_CONST_MEMBER_PTR)
+      else if (jfunc->type == IPA_JF_CONST
+              || jfunc->type == IPA_JF_CONST_MEMBER_PTR)
        {
          struct cgraph_node *callee;
          struct cgraph_edge *new_indirect_edge;
          tree decl;
 
          nt->processed = true;
-         if (jfunc->type == IPA_CONST_MEMBER_PTR)
+         if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
            decl = jfunc->value.member_cst.pfn;
          else
            decl = jfunc->value.constant;
index aca7bf8..5943a2a 100644 (file)
@@ -25,21 +25,24 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 
 /* The following definitions and interfaces are used by
-   interprocedural analyses.  */
+   interprocedural analyses or parameters.  */
+
+/* ipa-prop.c stuff (ipa-cp, indirect inlining):  */
 
 /* A jump function for a callsite represents the values passed as actual
    arguments of the callsite. There are three main types of values :
    Formal - the caller's formal parameter is passed as an actual argument.
    Constant - a constant is passed as an actual argument.
    Unknown - neither of the above.
-   Integer and real constants are represented as IPA_CONST.
-   Finally, IPA_CONST_MEMBER_PTR stands for C++ member pointers constants.  */
+   Integer and real constants are represented as IPA_JF_CONST.
+   Finally, IPA_JF_CONST_MEMBER_PTR stands for C++ member pointers
+   constants.  */
 enum jump_func_type
 {
-  IPA_UNKNOWN = 0,     /* newly allocated and zeroed jump functions default */
-  IPA_CONST,
-  IPA_CONST_MEMBER_PTR,
-  IPA_PASS_THROUGH
+  IPA_JF_UNKNOWN = 0,  /* newly allocated and zeroed jump functions default */
+  IPA_JF_CONST,
+  IPA_JF_CONST_MEMBER_PTR,
+  IPA_JF_PASS_THROUGH
 };
 
 /* All formal parameters in the program have a lattice associated with it
@@ -50,7 +53,7 @@ enum jump_func_type
    IPA_CONST_VALUE - simple scalar constant,
    Cval of formal f will have a constant value if all callsites to this
    function have the same constant value passed to f.
-   Integer and real constants are represented as IPA_CONST.  */
+   Integer and real constants are represented as IPA_CONST_VALUE.  */
 enum ipa_lattice_type
 {
   IPA_BOTTOM,
index c56915f..4065876 100644 (file)
@@ -3244,6 +3244,7 @@ expand_omp_taskreg (struct omp_region *region)
   basic_block entry_bb, exit_bb, new_bb;
   struct function *child_cfun;
   tree child_fn, block, t, ws_args, *tp;
+  tree save_current;
   gimple_stmt_iterator gsi;
   gimple entry_stmt, stmt;
   edge e;
@@ -3429,6 +3430,8 @@ expand_omp_taskreg (struct omp_region *region)
       /* Fix the callgraph edges for child_cfun.  Those for cfun will be
         fixed in a following pass.  */
       push_cfun (child_cfun);
+      save_current = current_function_decl;
+      current_function_decl = child_fn;
       if (optimize)
        optimize_omp_library_calls (entry_stmt);
       rebuild_cgraph_edges ();
@@ -3440,16 +3443,14 @@ expand_omp_taskreg (struct omp_region *region)
       if (flag_exceptions)
        {
          basic_block bb;
-         tree save_current = current_function_decl;
          bool changed = false;
 
-         current_function_decl = child_fn;
          FOR_EACH_BB (bb)
            changed |= gimple_purge_dead_eh_edges (bb);
          if (changed)
            cleanup_tree_cfg ();
-         current_function_decl = save_current;
        }
+      current_function_decl = save_current;
       pop_cfun ();
     }
   
index bf312f9..4e8944a 100644 (file)
@@ -551,6 +551,7 @@ init_optimization_passes (void)
          struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
          NEXT_PASS (pass_rebuild_cgraph_edges);
          NEXT_PASS (pass_early_inline);
+         NEXT_PASS (pass_remove_cgraph_callee_edges);
          NEXT_PASS (pass_rename_ssa_copies);
          NEXT_PASS (pass_ccp);
          NEXT_PASS (pass_forwprop);
@@ -587,6 +588,7 @@ init_optimization_passes (void)
   NEXT_PASS (pass_all_optimizations);
     {
       struct opt_pass **p = &pass_all_optimizations.pass.sub;
+      NEXT_PASS (pass_remove_cgraph_callee_edges);
       /* Initial scalar cleanups before alias computation.
         They ensure memory accesses are not indirect wherever possible.  */
       NEXT_PASS (pass_strip_predict_hints);
index 5241e64..082ac08 100644 (file)
@@ -801,6 +801,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
   tree size_tree = NULL_TREE;
   HOST_WIDE_INT bit_offset = 0;
   bool seen_variable_array_ref = false;
+  bool seen_union = false;
 
   gcc_assert (!SSA_VAR_P (exp));
 
@@ -844,6 +845,9 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
            tree field = TREE_OPERAND (exp, 1);
            tree this_offset = component_ref_field_offset (exp);
 
+           if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == UNION_TYPE)
+             seen_union = true;
+
            if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
              {
                HOST_WIDE_INT hthis_offset = tree_low_cst (this_offset, 0);
@@ -934,12 +938,22 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
      where we do not know maxsize for variable index accesses to
      the array.  The simplest way to conservatively deal with this
      is to punt in the case that offset + maxsize reaches the
-     base type boundary.  */
+     base type boundary.
+
+     Unfortunately this is difficult to determine reliably when unions are
+     involved and so we are conservative in such cases.
+
+     FIXME: This approach may be too conservative, we probably want to at least
+     check that the union is the last field/element at its level or even
+     propagate the calculated offsets back up the access chain and check
+     there.  */
+
   if (seen_variable_array_ref
-      && maxsize != -1
-      && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
-      && bit_offset + maxsize
-          == (signed)TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))
+      && (seen_union
+         || (maxsize != -1
+             && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
+             && bit_offset + maxsize
+             == (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
     maxsize = -1;
 
   /* ???  Due to negative offsets in ARRAY_REF we can end up with
index 37d9098..609a081 100644 (file)
@@ -3639,10 +3639,6 @@ optimize_inline_calls (tree fn)
   /* Renumber the lexical scoping (non-code) blocks consecutively.  */
   number_blocks (fn);
 
-  /* We are not going to maintain the cgraph edges up to date.
-     Kill it so it won't confuse us.  */
-  cgraph_node_remove_callees (id.dst_node);
-
   fold_cond_expr_cond ();
 
   /* It would be nice to check SSA/CFG/statement consistency here, but it is
index 96239c4..2db0f22 100644 (file)
@@ -389,6 +389,7 @@ extern struct gimple_opt_pass pass_uncprop;
 extern struct gimple_opt_pass pass_return_slot;
 extern struct gimple_opt_pass pass_reassoc;
 extern struct gimple_opt_pass pass_rebuild_cgraph_edges;
+extern struct gimple_opt_pass pass_remove_cgraph_callee_edges;
 extern struct gimple_opt_pass pass_build_cgraph_edges;
 extern struct gimple_opt_pass pass_reset_cc_flags;
 extern struct gimple_opt_pass pass_local_pure_const;