OSDN Git Service

* dwarf2out.c (def_cfa_1): After DW_CFA_def_cfa_expression
[pf3gnuchains/gcc-fork.git] / gcc / lto-streamer-in.c
index a0ead41..123a7a7 100644 (file)
@@ -1,6 +1,6 @@
 /* Read the GIMPLE representation from a file stream.
 
-   Copyright 2009 Free Software Foundation, Inc.
+   Copyright 2009, 2010 Free Software Foundation, Inc.
    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
    Re-implemented by Diego Novillo <dnovillo@google.com>
 
@@ -30,7 +30,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "params.h"
 #include "input.h"
-#include "varray.h"
 #include "hashtab.h"
 #include "basic-block.h"
 #include "tree-flow.h"
@@ -358,8 +357,6 @@ lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in,
     case LTO_label_decl_ref:
       ix_u = lto_input_uleb128 (ib);
       result = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u);
-      if (tag == LTO_global_decl_ref)
-       varpool_mark_needed_node (varpool_node (result));
       break;
 
     default:
@@ -578,6 +575,11 @@ fixup_eh_region_pointers (struct function *fn, HOST_WIDE_INT root_region)
 static void
 lto_init_eh (void)
 {
+  static bool eh_initialized_p = false;
+
+  if (eh_initialized_p)
+    return;
+
   /* Contrary to most other FEs, we only initialize EH support when at
      least one of the files in the set contains exception regions in
      it.  Since this happens much later than the call to init_eh in
@@ -593,6 +595,8 @@ lto_init_eh (void)
   if (dwarf2out_do_frame ())
     dwarf2out_frame_init ();
 #endif
+
+  eh_initialized_p = true;
 }
 
 
@@ -605,7 +609,6 @@ input_eh_regions (struct lto_input_block *ib, struct data_in *data_in,
 {
   HOST_WIDE_INT i, root_region, len;
   enum LTO_tags tag;
-  static bool eh_initialized_p = false;
 
   tag = input_record_start (ib);
   if (tag == LTO_null)
@@ -616,11 +619,7 @@ input_eh_regions (struct lto_input_block *ib, struct data_in *data_in,
   /* If the file contains EH regions, then it was compiled with
      -fexceptions.  In that case, initialize the backend EH
      machinery.  */
-  if (!eh_initialized_p)
-    {
-      lto_init_eh ();
-      eh_initialized_p = true;
-    }
+  lto_init_eh ();
 
   gcc_assert (fn->eh);
 
@@ -944,7 +943,8 @@ maybe_fixup_handled_component (tree op)
 }
 
 /* Fixup reference tree operands for substituted prevailing decls
-   with mismatched types in STMT.  */
+   with mismatched types in STMT.  This handles plain DECLs where
+   we need the stmt for context to lookup the required type.  */
 
 static void
 maybe_fixup_decls (gimple stmt)
@@ -965,8 +965,6 @@ maybe_fixup_decls (gimple stmt)
            gimple_assign_set_rhs1 (stmt, build1 (VIEW_CONVERT_EXPR,
                                                  TREE_TYPE (lhs), rhs));
        }
-      else if (handled_component_p (rhs))
-       maybe_fixup_handled_component (rhs);
       /* Then catch scalar stores.  */
       else if (TREE_CODE (lhs) == VAR_DECL)
        {
@@ -974,8 +972,6 @@ maybe_fixup_decls (gimple stmt)
            gimple_assign_set_lhs (stmt, build1 (VIEW_CONVERT_EXPR,
                                                 TREE_TYPE (rhs), lhs));
        }
-      else if (handled_component_p (lhs))
-       maybe_fixup_handled_component (lhs);
     }
   else if (is_gimple_call (stmt))
     {
@@ -989,8 +985,6 @@ maybe_fixup_decls (gimple stmt)
                                               gimple_call_return_type (stmt),
                                               lhs));
        }
-      else if (lhs && handled_component_p (lhs))
-       maybe_fixup_handled_component (lhs);
 
       /* Arguments, especially for varargs functions will be funny...  */
     }
@@ -1050,6 +1044,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
        stmt->gimple_asm.ni = lto_input_uleb128 (ib);
        stmt->gimple_asm.no = lto_input_uleb128 (ib);
        stmt->gimple_asm.nc = lto_input_uleb128 (ib);
+       stmt->gimple_asm.nl = lto_input_uleb128 (ib);
        str = input_string_cst (data_in, ib);
        stmt->gimple_asm.string = TREE_STRING_POINTER (str);
       }
@@ -1067,9 +1062,29 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
        {
          tree op = lto_input_tree (ib, data_in);
          gimple_set_op (stmt, i, op);
+         if (!op)
+           continue;
+
+         /* Fixup reference tree operands for substituted prevailing decls
+            with mismatched types.  For plain VAR_DECLs we need to look
+            at context to determine the wanted type - we do that below
+            after the stmt is completed.  */
+         if (TREE_CODE (op) == ADDR_EXPR
+             && TREE_CODE (TREE_OPERAND (op, 0)) == VAR_DECL
+             && !useless_type_conversion_p (TREE_TYPE (TREE_TYPE (op)),
+                                            TREE_TYPE (op)))
+           {
+             TREE_OPERAND (op, 0)
+               = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (TREE_TYPE (op)),
+                         TREE_OPERAND (op, 0));
+             continue;
+           }
 
-         /* Fixup FIELD_DECLs.  */
-         while (op && handled_component_p (op))
+         /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
+            by decl merging.  */
+         if (TREE_CODE (op) == ADDR_EXPR)
+           op = TREE_OPERAND (op, 0);
+         while (handled_component_p (op))
            {
              if (TREE_CODE (op) == COMPONENT_REF)
                {
@@ -1080,12 +1095,9 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
                    {
                      if (tem == field
                          || (TREE_TYPE (tem) == TREE_TYPE (field)
-                             && (DECL_FIELD_OFFSET (tem)
-                                 == DECL_FIELD_OFFSET (field))
-                             && (DECL_FIELD_BIT_OFFSET (tem)
-                                 == DECL_FIELD_BIT_OFFSET (field))
-                             && (DECL_OFFSET_ALIGN (tem)
-                                 == DECL_OFFSET_ALIGN (field))))
+                             && DECL_NONADDRESSABLE_P (tem)
+                                == DECL_NONADDRESSABLE_P (field)
+                             && gimple_compare_field_offset (tem, field)))
                        break;
                    }
                  /* In case of type mismatches across units we can fail
@@ -1099,8 +1111,17 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
                    TREE_OPERAND (op, 1) = tem;
                }
 
+             /* Preserve the last handled component for the fixup of
+                its operand below.  */
+             if (!handled_component_p (TREE_OPERAND (op, 0)))
+               break;
              op = TREE_OPERAND (op, 0);
            }
+
+         /* Fixup reference tree operands for substituted prevailing decls
+            with mismatched types.  */
+         if (handled_component_p (op))
+           maybe_fixup_handled_component (op);
        }
       break;
 
@@ -1136,6 +1157,10 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
        }
     }
 
+  /* Reset alias information.  */
+  if (code == GIMPLE_CALL)
+    gimple_call_reset_alias_info (stmt);
+
   /* Fixup reference tree operands for substituted prevailing decls
      with mismatched types.  */
   maybe_fixup_decls (stmt);
@@ -1223,6 +1248,8 @@ fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts)
   struct cgraph_edge *cedge;
   for (cedge = node->callees; cedge; cedge = cedge->next_callee)
     cedge->call_stmt = stmts[cedge->lto_stmt_uid];
+  for (cedge = node->indirect_calls; cedge; cedge = cedge->next_callee)
+    cedge->call_stmt = stmts[cedge->lto_stmt_uid];
 }
 
 /* Fixup call_stmt pointers in NODE and all clones.  */
@@ -1289,11 +1316,13 @@ input_function (tree fn_decl, struct data_in *data_in,
   fn->has_nonlocal_label = bp_unpack_value (bp, 1);
   fn->calls_alloca = bp_unpack_value (bp, 1);
   fn->calls_setjmp = bp_unpack_value (bp, 1);
-  fn->function_frequency = (enum function_frequency) bp_unpack_value (bp, 2);
   fn->va_list_fpr_size = bp_unpack_value (bp, 8);
   fn->va_list_gpr_size = bp_unpack_value (bp, 8);
   bitpack_delete (bp);
 
+  /* Input the current IL state of the function.  */
+  fn->curr_properties = lto_input_uleb128 (ib);
+
   /* Read the static chain and non-local goto save area.  */
   fn->static_chain_decl = lto_input_tree (ib, data_in);
   fn->nonlocal_goto_save_area = lto_input_tree (ib, data_in);
@@ -1469,14 +1498,6 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
       /* We should now be in SSA.  */
       cfun->gimple_df->in_ssa_p = true;
 
-      /* Fill in properties we know hold for the rebuilt CFG.  */
-      cfun->curr_properties = PROP_ssa
-                             | PROP_cfg
-                             | PROP_gimple_any
-                             | PROP_gimple_lcf
-                             | PROP_gimple_leh
-                             | PROP_referenced_vars;
-
       /* Restore decl state */
       file_data->current_decl_state = file_data->global_decl_state;
 
@@ -1523,12 +1544,15 @@ get_resolution (struct data_in *data_in, unsigned index)
   if (data_in->globals_resolution)
     {
       ld_plugin_symbol_resolution_t ret;
-      gcc_assert (index < VEC_length (ld_plugin_symbol_resolution_t,
-                                     data_in->globals_resolution));
+      /* We can have references to not emitted functions in
+        DECL_FUNCTION_PERSONALITY at least.  So we can and have
+        to indeed return LDPR_UNKNOWN in some cases.   */
+      if (VEC_length (ld_plugin_symbol_resolution_t,
+                     data_in->globals_resolution) <= index)
+       return LDPR_UNKNOWN;
       ret = VEC_index (ld_plugin_symbol_resolution_t,
                       data_in->globals_resolution,
                       index);
-      gcc_assert (ret != LDPR_UNKNOWN);
       return ret;
     }
   else
@@ -1696,6 +1720,7 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
     {
       DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1);
       DECL_IN_TEXT_SECTION (expr) = (unsigned) bp_unpack_value (bp, 1);
+      DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1);
       DECL_TLS_MODEL (expr) = (enum tls_model) bp_unpack_value (bp,  3);
     }
 
@@ -1749,9 +1774,9 @@ unpack_ts_type_value_fields (struct bitpack_d *bp, tree expr)
   SET_TYPE_MODE (expr, mode);
   TYPE_STRING_FLAG (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_NO_FORCE_BLK (expr) = (unsigned) bp_unpack_value (bp, 1);
-  TYPE_NEEDS_CONSTRUCTING(expr) = (unsigned) bp_unpack_value (bp, 1);
-  if (TREE_CODE (expr) == UNION_TYPE)
-    TYPE_TRANSPARENT_UNION (expr) = (unsigned) bp_unpack_value (bp, 1);
+  TYPE_NEEDS_CONSTRUCTING (expr) = (unsigned) bp_unpack_value (bp, 1);
+  if (RECORD_OR_UNION_TYPE_P (expr))
+    TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr)
@@ -2121,6 +2146,12 @@ lto_input_ts_function_decl_tree_pointers (struct lto_input_block *ib,
   DECL_FUNCTION_PERSONALITY (expr) = lto_input_tree (ib, data_in);
   DECL_FUNCTION_SPECIFIC_TARGET (expr) = lto_input_tree (ib, data_in);
   DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = lto_input_tree (ib, data_in);
+
+  /* If the file contains a function with an EH personality set,
+     then it was compiled with -fexceptions.  In that case, initialize
+     the backend EH machinery.  */
+  if (DECL_FUNCTION_PERSONALITY (expr))
+    lto_init_eh ();
 }
 
 
@@ -2136,9 +2167,10 @@ lto_input_ts_type_tree_pointers (struct lto_input_block *ib,
     TYPE_VALUES (expr) = lto_input_tree (ib, data_in);
   else if (TREE_CODE (expr) == ARRAY_TYPE)
     TYPE_DOMAIN (expr) = lto_input_tree (ib, data_in);
-  else if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE)
+  else if (RECORD_OR_UNION_TYPE_P (expr))
     TYPE_FIELDS (expr) = lto_input_tree (ib, data_in);
-  else if (TREE_CODE (expr) == FUNCTION_TYPE || TREE_CODE (expr) == METHOD_TYPE)
+  else if (TREE_CODE (expr) == FUNCTION_TYPE
+          || TREE_CODE (expr) == METHOD_TYPE)
     TYPE_ARG_TYPES (expr) = lto_input_tree (ib, data_in);
   else if (TREE_CODE (expr) == VECTOR_TYPE)
     TYPE_DEBUG_REPRESENTATION_TYPE (expr) = lto_input_tree (ib, data_in);
@@ -2159,6 +2191,7 @@ lto_input_ts_type_tree_pointers (struct lto_input_block *ib,
     TYPE_BINFO (expr) = lto_input_tree (ib, data_in);
   TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in);
   TYPE_CANONICAL (expr) = lto_input_tree (ib, data_in);
+  TYPE_STUB_DECL (expr) = lto_input_tree (ib, data_in);
 }
 
 
@@ -2583,6 +2616,8 @@ lto_get_builtin_tree (struct lto_input_block *ib, struct data_in *data_in)
       if (!result || result == error_mark_node)
        fatal_error ("target specific builtin not available");
     }
+  else
+    gcc_unreachable ();
 
   asmname = input_string (data_in, ib);
   if (asmname)