re PR target/54061 (gcc.c-torture/compile/mipscop-*.c ICEs with -g)
[gcc.git] / gcc / ipa-prop.c
index 3150bd6db15ca5684dff7c1d595893f53f0f4d75..55bd372e0a848b09a1b8f7b603d95cbba96a9a0e 100644 (file)
@@ -2187,49 +2187,46 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
 /* Try to find a destination for indirect edge IE that corresponds to a simple
    call or a call of a member function pointer and where the destination is a
    pointer formal parameter described by jump function JFUNC.  If it can be
-   determined, return the newly direct edge, otherwise return NULL.  */
+   determined, return the newly direct edge, otherwise return NULL.
+   NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.  */
 
 static struct cgraph_edge *
 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
-                                 struct ipa_jump_func *jfunc)
+                                 struct ipa_jump_func *jfunc,
+                                 struct ipa_node_params *new_root_info)
 {
   tree target;
 
   if (ie->indirect_info->agg_contents)
-    {
-      target = ipa_find_agg_cst_for_param (&jfunc->agg,
-                                          ie->indirect_info->offset,
-                                          ie->indirect_info->by_ref);
-      if (!target)
-       return NULL;
-    }
+    target = ipa_find_agg_cst_for_param (&jfunc->agg,
+                                        ie->indirect_info->offset,
+                                        ie->indirect_info->by_ref);
   else
-    {
-      if (jfunc->type != IPA_JF_CONST)
-       return NULL;
-      target = ipa_get_jf_constant (jfunc);
-    }
+    target = ipa_value_from_jfunc (new_root_info, jfunc);
+  if (!target)
+    return NULL;
   return ipa_make_edge_direct_to_target (ie, target);
 }
 
-/* Try to find a destination for indirect edge IE that corresponds to a
-   virtual call based on a formal parameter which is described by jump
-   function JFUNC and if it can be determined, make it direct and return the
-   direct edge.  Otherwise, return NULL.  */
+/* Try to find a destination for indirect edge IE that corresponds to a virtual
+   call based on a formal parameter which is described by jump function JFUNC
+   and if it can be determined, make it direct and return the direct edge.
+   Otherwise, return NULL.  NEW_ROOT_INFO is the node info that JFUNC lattices
+   are relative to.  */
 
 static struct cgraph_edge *
 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
-                                  struct ipa_jump_func *jfunc)
+                                  struct ipa_jump_func *jfunc,
+                                  struct ipa_node_params *new_root_info)
 {
   tree binfo, target;
 
-  if (jfunc->type != IPA_JF_KNOWN_TYPE)
+  binfo = ipa_value_from_jfunc (new_root_info, jfunc);
+
+  if (!binfo || TREE_CODE (binfo) != TREE_BINFO)
     return NULL;
 
-  binfo = TYPE_BINFO (ipa_get_jf_known_type_base_type (jfunc));
-  gcc_checking_assert (binfo);
-  binfo = get_binfo_at_offset (binfo, ipa_get_jf_known_type_offset (jfunc)
-                              + ie->indirect_info->offset,
+  binfo = get_binfo_at_offset (binfo, ie->indirect_info->offset,
                               ie->indirect_info->otr_type);
   if (binfo)
     target = gimple_get_virt_method_for_binfo (ie->indirect_info->otr_token,
@@ -2256,10 +2253,14 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
 {
   struct ipa_edge_args *top;
   struct cgraph_edge *ie, *next_ie, *new_direct_edge;
+  struct ipa_node_params *new_root_info;
   bool res = false;
 
   ipa_check_create_edge_args ();
   top = IPA_EDGE_REF (cs);
+  new_root_info = IPA_NODE_REF (cs->caller->global.inlined_to
+                               ? cs->caller->global.inlined_to
+                               : cs->caller);
 
   for (ie = node->indirect_calls; ie; ie = next_ie)
     {
@@ -2309,9 +2310,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
        continue;
 
       if (ici->polymorphic)
-       new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc);
+       new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc,
+                                                            new_root_info);
       else
-       new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc);
+       new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
+                                                           new_root_info);
 
       if (new_direct_edge)
        {
@@ -2888,6 +2891,8 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
        {
          tree expr, base, off;
          location_t loc;
+         unsigned int deref_align;
+         bool deref_base = false;
 
          /* We create a new parameter out of the value of the old one, we can
             do the following kind of transformations:
@@ -2910,7 +2915,8 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
 
          gcc_checking_assert (adj->offset % BITS_PER_UNIT == 0);
          base = gimple_call_arg (stmt, adj->base_index);
-         loc = EXPR_LOCATION (base);
+         loc = DECL_P (base) ? DECL_SOURCE_LOCATION (base)
+                             : EXPR_LOCATION (base);
 
          if (TREE_CODE (base) != ADDR_EXPR
              && POINTER_TYPE_P (TREE_TYPE (base)))
@@ -2920,9 +2926,15 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
            {
              HOST_WIDE_INT base_offset;
              tree prev_base;
+             bool addrof;
 
              if (TREE_CODE (base) == ADDR_EXPR)
-               base = TREE_OPERAND (base, 0);
+               {
+                 base = TREE_OPERAND (base, 0);
+                 addrof = true;
+               }
+             else
+               addrof = false;
              prev_base = base;
              base = get_addr_base_and_unit_offset (base, &base_offset);
              /* Aggregate arguments can have non-invariant addresses.  */
@@ -2934,6 +2946,11 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
                }
              else if (TREE_CODE (base) == MEM_REF)
                {
+                 if (!addrof)
+                   {
+                     deref_base = true;
+                     deref_align = TYPE_ALIGN (TREE_TYPE (base));
+                   }
                  off = build_int_cst (adj->alias_ptr_type,
                                       base_offset
                                       + adj->offset / BITS_PER_UNIT);
@@ -2956,7 +2973,17 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
              unsigned int align;
              unsigned HOST_WIDE_INT misalign;
 
-             get_pointer_alignment_1 (base, &align, &misalign);
+             if (deref_base)
+               {
+                 align = deref_align;
+                 misalign = 0;
+               }
+             else
+               {
+                 get_pointer_alignment_1 (base, &align, &misalign);
+                 if (TYPE_ALIGN (type) > align)
+                   align = TYPE_ALIGN (type);
+               }
              misalign += (tree_to_double_int (off)
                           .sext (TYPE_PRECISION (TREE_TYPE (off))).low
                           * BITS_PER_UNIT);
@@ -3534,8 +3561,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
 
   data_in =
     lto_data_in_create (file_data, (const char *) data + string_offset,
-                       header->string_size,
-                       vec<ld_plugin_symbol_resolution_t>());
+                       header->string_size, vNULL);
   count = streamer_read_uhwi (&ib_main);
 
   for (i = 0; i < count; i++)
@@ -3708,8 +3734,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
                        header->main_size);
 
   data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
-                               header->string_size,
-                               vec<ld_plugin_symbol_resolution>());
+                               header->string_size, vNULL);
   count = streamer_read_uhwi (&ib_main);
 
   for (i = 0; i < count; i++)
@@ -3790,7 +3815,7 @@ adjust_agg_replacement_values (struct cgraph_node *node,
 unsigned int
 ipcp_transform_function (struct cgraph_node *node)
 {
-  vec<ipa_param_descriptor_t> descriptors = vec<ipa_param_descriptor_t>();
+  vec<ipa_param_descriptor_t> descriptors = vNULL;
   struct param_analysis_info *parms_ainfo;
   struct ipa_agg_replacement_value *aggval;
   gimple_stmt_iterator gsi;