]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/lto/lto.c
Makefile.in: Add ipa-fnsummary.o and ipa-fnsummary.h
[thirdparty/gcc.git] / gcc / lto / lto.c
index 2d80ffec61a897b3fd8a8070141e53326fa43dda..f5dbbedafcf9aa397b22936c8a135f1fac0fe8df 100644 (file)
@@ -1,5 +1,5 @@
 /* Top-level LTO routines.
-   Copyright (C) 2009-2015 Free Software Foundation, Inc.
+   Copyright (C) 2009-2017 Free Software Foundation, Inc.
    Contributed by CodeSourcery, Inc.
 
 This file is part of GCC.
@@ -21,45 +21,38 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "opts.h"
-#include "toplev.h"
-#include "alias.h"
 #include "tm.h"
 #include "function.h"
 #include "bitmap.h"
-#include "cfghooks.h"
 #include "basic-block.h"
 #include "tree.h"
 #include "gimple.h"
-#include "hard-reg-set.h"
-#include "options.h"
-#include "fold-const.h"
-#include "stor-layout.h"
-#include "diagnostic-core.h"
-#include "cgraph.h"
-#include "tree-ssa-operands.h"
-#include "tree-pass.h"
-#include "langhooks.h"
+#include "cfghooks.h"
 #include "alloc-pool.h"
+#include "tree-pass.h"
+#include "tree-streamer.h"
+#include "cgraph.h"
+#include "opts.h"
+#include "toplev.h"
+#include "stor-layout.h"
 #include "symbol-summary.h"
+#include "tree-vrp.h"
 #include "ipa-prop.h"
 #include "common.h"
 #include "debug.h"
-#include "internal-fn.h"
 #include "lto.h"
-#include "lto-tree.h"
-#include "lto-streamer.h"
 #include "lto-section-names.h"
-#include "tree-streamer.h"
 #include "splay-tree.h"
 #include "lto-partition.h"
-#include "data-streamer.h"
 #include "context.h"
 #include "pass_manager.h"
-#include "ipa-inline.h"
+#include "ipa-fnsummary.h"
 #include "params.h"
 #include "ipa-utils.h"
 #include "gomp-constants.h"
+#include "lto-symtab.h"
+#include "stringpool.h"
+#include "fold-const.h"
 
 
 /* Number of parallel tasks to run, -1 if we want to use GNU Make jobserver.  */
@@ -244,6 +237,8 @@ lto_read_in_decl_state (struct data_in *data_in, const uint32_t *data,
   uint32_t i, j;
 
   ix = *data++;
+  state->compressed = ix & 1;
+  ix /= 2;
   decl = streamer_tree_cache_get_tree (data_in->reader_cache, ix);
   if (!VAR_OR_FUNCTION_DECL_P (decl))
     {
@@ -290,6 +285,7 @@ static hashval_t
 hash_canonical_type (tree type)
 {
   inchash::hash hstate;
+  enum tree_code code;
 
   /* We compute alias sets only for types that needs them.
      Be sure we do not recurse to something else as we can not hash incomplete
@@ -301,7 +297,8 @@ hash_canonical_type (tree type)
      smaller sets; when searching for existing matching types to merge,
      only existing types having the same features as the new type will be
      checked.  */
-  hstate.add_int (tree_code_for_canonical_type_merging (TREE_CODE (type)));
+  code = tree_code_for_canonical_type_merging (TREE_CODE (type));
+  hstate.add_int (code);
   hstate.add_int (TYPE_MODE (type));
 
   /* Incorporate common features of numerical types.  */
@@ -311,8 +308,9 @@ hash_canonical_type (tree type)
       || TREE_CODE (type) == OFFSET_TYPE
       || POINTER_TYPE_P (type))
     {
-      hstate.add_int (TYPE_UNSIGNED (type));
       hstate.add_int (TYPE_PRECISION (type));
+      if (!type_with_interoperable_signedness (type))
+        hstate.add_int (TYPE_UNSIGNED (type));
     }
 
   if (VECTOR_TYPE_P (type))
@@ -375,7 +373,9 @@ hash_canonical_type (tree type)
       tree f;
 
       for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f))
-       if (TREE_CODE (f) == FIELD_DECL)
+       if (TREE_CODE (f) == FIELD_DECL
+           && (! DECL_SIZE (f)
+               || ! integer_zerop (DECL_SIZE (f))))
          {
            iterative_hash_canonical_type (TREE_TYPE (f), hstate);
            nf++;
@@ -396,8 +396,11 @@ iterative_hash_canonical_type (tree type, inchash::hash &hstate)
 
   /* All type variants have same TYPE_CANONICAL.  */
   type = TYPE_MAIN_VARIANT (type);
+
+  if (!canonical_type_used_p (type))
+    v = hash_canonical_type (type);
   /* An already processed type.  */
-  if (TYPE_CANONICAL (type))
+  else if (TYPE_CANONICAL (type))
     {
       type = TYPE_CANONICAL (type);
       v = gimple_canonical_type_hash (type);
@@ -445,7 +448,9 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
 {
   void **slot;
 
-  gcc_checking_assert (TYPE_P (t) && !TYPE_CANONICAL (t));
+  gcc_checking_assert (TYPE_P (t) && !TYPE_CANONICAL (t)
+                      && type_with_alias_set_p (t)
+                      && canonical_type_used_p (t));
 
   slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash, INSERT);
   if (*slot)
@@ -478,7 +483,8 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
 static void
 gimple_register_canonical_type (tree t)
 {
-  if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t))
+  if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t)
+      || !canonical_type_used_p (t))
     return;
 
   /* Canonical types are same among all complete variants.  */
@@ -1021,7 +1027,10 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
   compare_values (TREE_DEPRECATED);
   if (TYPE_P (t1))
     {
-      compare_values (TYPE_SATURATING);
+      if (AGGREGATE_TYPE_P (t1))
+       compare_values (TYPE_REVERSE_STORAGE_ORDER);
+      else
+       compare_values (TYPE_SATURATING);
       compare_values (TYPE_ADDR_SPACE);
     }
   else if (code == SSA_NAME)
@@ -1055,10 +1064,6 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
                        TREE_FIXED_CST_PTR (t1), TREE_FIXED_CST_PTR (t2)))
       return false;
 
-
-  /* We don't want to compare locations, so there is nothing do compare
-     for TS_DECL_MINIMAL.  */
-
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
     {
       compare_values (DECL_MODE);
@@ -1157,13 +1162,17 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
        }
       else if (code == ARRAY_TYPE)
        compare_values (TYPE_NONALIASED_COMPONENT);
+      if (AGGREGATE_TYPE_P (t1))
+       compare_values (TYPE_TYPELESS_STORAGE);
       compare_values (TYPE_PACKED);
       compare_values (TYPE_RESTRICT);
       compare_values (TYPE_USER_ALIGN);
       compare_values (TYPE_READONLY);
       compare_values (TYPE_PRECISION);
       compare_values (TYPE_ALIGN);
-      compare_values (TYPE_ALIAS_SET);
+      /* Do not compare TYPE_ALIAS_SET.  Doing so introduce ordering issues
+         with calls to get_alias_set which may initialize it for streamed
+        in types.  */
     }
 
   /* We don't want to compare locations, so there is nothing do compare
@@ -1305,6 +1314,7 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
       compare_tree_edges (DECL_SIZE (t1), DECL_SIZE (t2));
       compare_tree_edges (DECL_SIZE_UNIT (t1), DECL_SIZE_UNIT (t2));
       compare_tree_edges (DECL_ATTRIBUTES (t1), DECL_ATTRIBUTES (t2));
+      compare_tree_edges (DECL_ABSTRACT_ORIGIN (t1), DECL_ABSTRACT_ORIGIN (t2));
       if ((code == VAR_DECL
           || code == PARM_DECL)
          && DECL_HAS_VALUE_EXPR_P (t1))
@@ -1582,19 +1592,17 @@ unify_scc (struct data_in *data_in, unsigned from,
          num_sccs_merged++;
          total_scc_size_merged += len;
 
-#ifdef ENABLE_CHECKING
-         for (unsigned i = 0; i < len; ++i)
-           {
-             tree t = map[2*i+1];
-             enum tree_code code = TREE_CODE (t);
-             /* IDENTIFIER_NODEs should be singletons and are merged by the
-                streamer.  The others should be singletons, too, and we
-                should not merge them in any way.  */
-             gcc_assert (code != TRANSLATION_UNIT_DECL
-                         && code != IDENTIFIER_NODE
-                         && !streamer_handle_as_builtin_p (t));
-           }
-#endif
+         if (flag_checking)
+           for (unsigned i = 0; i < len; ++i)
+             {
+               tree t = map[2*i+1];
+               enum tree_code code = TREE_CODE (t);
+               /* IDENTIFIER_NODEs should be singletons and are merged by the
+                  streamer.  The others should be singletons, too, and we
+                  should not merge them in any way.  */
+               gcc_assert (code != TRANSLATION_UNIT_DECL
+                           && code != IDENTIFIER_NODE);
+             }
 
          /* Fixup the streamer cache with the prevailing nodes according
             to the tree node mapping computed by compare_tree_sccs.  */
@@ -1619,13 +1627,9 @@ unify_scc (struct data_in *data_in, unsigned from,
          data_in->location_cache.revert_location_cache ();
          for (unsigned i = 0; i < len; ++i)
            {
-             enum tree_code code;
              if (TYPE_P (scc->entries[i]))
                num_merged_types++;
-             code = TREE_CODE (scc->entries[i]);
-             if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
-               vec_free (CONSTRUCTOR_ELTS (scc->entries[i]));
-             ggc_free (scc->entries[i]);
+             free_node (scc->entries[i]);
            }
 
          break;
@@ -1704,8 +1708,7 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
          if (len == 1
              && (TREE_CODE (first) == IDENTIFIER_NODE
                  || TREE_CODE (first) == INTEGER_CST
-                 || TREE_CODE (first) == TRANSLATION_UNIT_DECL
-                 || streamer_handle_as_builtin_p (first)))
+                 || TREE_CODE (first) == TRANSLATION_UNIT_DECL))
            continue;
 
          /* Try to unify the SCC with already existing ones.  */
@@ -2287,6 +2290,8 @@ do_stream_out (char *temp_filename, lto_symtab_encoder_t encoder)
 
   ipa_write_optimization_summaries (encoder);
 
+  free (CONST_CAST (char *, file->filename));
+
   lto_set_current_out_file (NULL);
   lto_obj_file_close (file);
   free (file);
@@ -2515,7 +2520,7 @@ lto_wpa_write_files (void)
 
 /* Ensure that TT isn't a replacable var of function decl.  */
 #define LTO_NO_PREVAIL(tt) \
-  gcc_assert (!(tt) || !VAR_OR_FUNCTION_DECL_P (tt))
+  gcc_checking_assert (!(tt) || !VAR_OR_FUNCTION_DECL_P (tt))
 
 /* Given a tree T replace all fields referring to variables or functions
    with their prevailing variant.  */
@@ -2527,7 +2532,10 @@ lto_fixup_prevailing_decls (tree t)
 
   gcc_checking_assert (code != TREE_BINFO);
   LTO_NO_PREVAIL (TREE_TYPE (t));
-  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+  if (CODE_CONTAINS_STRUCT (code, TS_COMMON)
+      /* lto_symtab_prevail_decl use TREE_CHAIN to link to the prevailing decl.
+        in the case T is a prevailed declaration we would ICE here. */
+      && !VAR_OR_FUNCTION_DECL_P (t))
     LTO_NO_PREVAIL (TREE_CHAIN (t));
   if (DECL_P (t))
     {
@@ -2632,10 +2640,8 @@ lto_fixup_state (struct lto_in_decl_state *state)
       for (i = 0; i < vec_safe_length (trees); i++)
        {
          tree t = (*trees)[i];
-#ifdef ENABLE_CHECKING
-         if (TYPE_P (t))
+         if (flag_checking && TYPE_P (t))
            verify_type (t);
-#endif
          if (VAR_OR_FUNCTION_DECL_P (t)
              && (TREE_PUBLIC (t) || DECL_EXTERNAL (t)))
            (*trees)[i] = lto_symtab_prevailing_decl (t);
@@ -2848,7 +2854,7 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
   /* Read the symtab.  */
   input_symtab ();
 
-  input_offload_tables ();
+  input_offload_tables (!flag_ltrans);
 
   /* Store resolutions into the symbol table.  */
 
@@ -3092,14 +3098,17 @@ do_whole_program_analysis (void)
 
   execute_ipa_pass_list (g->get_passes ()->all_regular_ipa_passes);
 
+  /* When WPA analysis raises errors, do not bother to output anything.  */
+  if (seen_error ())
+    return;
+
   if (symtab->dump_file)
     {
       fprintf (symtab->dump_file, "Optimized ");
       symtab_node::dump_table (symtab->dump_file);
     }
-#ifdef ENABLE_CHECKING
-  symtab_node::verify_symtab_nodes ();
-#endif
+
+  symtab_node::checking_verify_symtab_nodes ();
   bitmap_obstack_release (NULL);
 
   /* We are about to launch the final LTRANS phase, stop the WPA timer.  */
@@ -3111,9 +3120,10 @@ do_whole_program_analysis (void)
   else if (flag_lto_partition == LTO_PARTITION_MAX)
     lto_max_map ();
   else if (flag_lto_partition == LTO_PARTITION_ONE)
-    lto_balanced_map (1);
+    lto_balanced_map (1, INT_MAX);
   else if (flag_lto_partition == LTO_PARTITION_BALANCED)
-    lto_balanced_map (PARAM_VALUE (PARAM_LTO_PARTITIONS));
+    lto_balanced_map (PARAM_VALUE (PARAM_LTO_PARTITIONS),
+                     PARAM_VALUE (MAX_PARTITION_SIZE));
   else
     gcc_unreachable ();
 
@@ -3222,6 +3232,37 @@ lto_init (void)
 #endif
 }
 
+/* Create artificial pointers for "omp declare target link" vars.  */
+
+static void
+offload_handle_link_vars (void)
+{
+#ifdef ACCEL_COMPILER
+  varpool_node *var;
+  FOR_EACH_VARIABLE (var)
+    if (lookup_attribute ("omp declare target link",
+                         DECL_ATTRIBUTES (var->decl)))
+      {
+       tree type = build_pointer_type (TREE_TYPE (var->decl));
+       tree link_ptr_var = make_node (VAR_DECL);
+       TREE_TYPE (link_ptr_var) = type;
+       TREE_USED (link_ptr_var) = 1;
+       TREE_STATIC (link_ptr_var) = 1;
+       SET_DECL_MODE (link_ptr_var, TYPE_MODE (type));
+       DECL_SIZE (link_ptr_var) = TYPE_SIZE (type);
+       DECL_SIZE_UNIT (link_ptr_var) = TYPE_SIZE_UNIT (type);
+       DECL_ARTIFICIAL (link_ptr_var) = 1;
+       tree var_name = DECL_ASSEMBLER_NAME (var->decl);
+       char *new_name
+         = ACONCAT ((IDENTIFIER_POINTER (var_name), "_linkptr", NULL));
+       DECL_NAME (link_ptr_var) = get_identifier (new_name);
+       SET_DECL_ASSEMBLER_NAME (link_ptr_var, DECL_NAME (link_ptr_var));
+       SET_DECL_VALUE_EXPR (var->decl, build_simple_mem_ref (link_ptr_var));
+       DECL_HAS_VALUE_EXPR_P (var->decl) = 1;
+      }
+#endif
+}
+
 
 /* Main entry point for the GIMPLE front end.  This front end has
    three main personalities:
@@ -3270,6 +3311,8 @@ lto_main (void)
 
   if (!seen_error ())
     {
+      offload_handle_link_vars ();
+
       /* If WPA is enabled analyze the whole call graph and create an
         optimization plan.  Otherwise, read in all the function
         bodies and continue with optimization.  */
@@ -3283,6 +3326,9 @@ lto_main (void)
          if (!flag_ltrans)
            lto_promote_statics_nonwpa ();
 
+         /* Annotate the CU DIE and mark the early debug phase as finished.  */
+         debug_hooks->early_finish ("<artificial>");
+
          /* Let the middle end know that we have read and merged all of
             the input files.  */ 
          symtab->compile ();