Merge branch 'vendor/GCC50'
authorJohn Marino <draco@marino.st>
Fri, 20 Feb 2015 17:01:04 +0000 (18:01 +0100)
committerJohn Marino <draco@marino.st>
Fri, 20 Feb 2015 17:01:04 +0000 (18:01 +0100)
73 files changed:
contrib/gcc-5.0/LAST_UPDATED
contrib/gcc-5.0/gcc/DATESTAMP
contrib/gcc-5.0/gcc/c-family/c-format.c
contrib/gcc-5.0/gcc/c/c-decl.c
contrib/gcc-5.0/gcc/cgraph.c
contrib/gcc-5.0/gcc/cgraph.h
contrib/gcc-5.0/gcc/cgraphclones.c
contrib/gcc-5.0/gcc/common.opt
contrib/gcc-5.0/gcc/cp/call.c
contrib/gcc-5.0/gcc/cp/constexpr.c
contrib/gcc-5.0/gcc/cp/decl.c
contrib/gcc-5.0/gcc/cp/parser.c
contrib/gcc-5.0/gcc/cp/pt.c
contrib/gcc-5.0/gcc/cp/tree.c
contrib/gcc-5.0/gcc/doc/bugreport.texi
contrib/gcc-5.0/gcc/doc/extend.texi
contrib/gcc-5.0/gcc/doc/gcov.texi
contrib/gcc-5.0/gcc/doc/implement-c.texi
contrib/gcc-5.0/gcc/doc/implement-cxx.texi
contrib/gcc-5.0/gcc/doc/invoke.texi
contrib/gcc-5.0/gcc/doc/objc.texi
contrib/gcc-5.0/gcc/doc/standards.texi
contrib/gcc-5.0/gcc/doc/trouble.texi
contrib/gcc-5.0/gcc/dwarf2out.c
contrib/gcc-5.0/gcc/haifa-sched.c
contrib/gcc-5.0/gcc/ipa-chkp.c
contrib/gcc-5.0/gcc/ipa-comdats.c
contrib/gcc-5.0/gcc/ipa-cp.c
contrib/gcc-5.0/gcc/ipa-devirt.c
contrib/gcc-5.0/gcc/ipa-icf.c
contrib/gcc-5.0/gcc/ipa-icf.h
contrib/gcc-5.0/gcc/ipa-inline-analysis.c
contrib/gcc-5.0/gcc/ipa-inline-transform.c
contrib/gcc-5.0/gcc/ipa-inline.c
contrib/gcc-5.0/gcc/ipa-profile.c
contrib/gcc-5.0/gcc/ipa-prop.c
contrib/gcc-5.0/gcc/ipa-visibility.c
contrib/gcc-5.0/gcc/ipa.c
contrib/gcc-5.0/gcc/lto-cgraph.c
contrib/gcc-5.0/gcc/lto-streamer.c
contrib/gcc-5.0/gcc/lto/lto-partition.c
contrib/gcc-5.0/gcc/match.pd
contrib/gcc-5.0/gcc/opts.c
contrib/gcc-5.0/gcc/sched-int.h
contrib/gcc-5.0/gcc/stmt.c
contrib/gcc-5.0/gcc/symtab.c
contrib/gcc-5.0/gcc/trans-mem.c
contrib/gcc-5.0/gcc/tree-cfg.c
contrib/gcc-5.0/gcc/tree-eh.c
contrib/gcc-5.0/gcc/tree-emutls.c
contrib/gcc-5.0/gcc/tree-predcom.c
contrib/gcc-5.0/gcc/tree-sra.c
contrib/gcc-5.0/gcc/tree-ssa-dom.c
contrib/gcc-5.0/gcc/tree-ssa-phiopt.c
contrib/gcc-5.0/gcc/tree-ssa-reassoc.c
contrib/gcc-5.0/gcc/tree-ssa-structalias.c
contrib/gcc-5.0/gcc/tree-ssa-threadedge.c
contrib/gcc-5.0/gcc/tree-stdarg.c
contrib/gcc-5.0/gcc/tree-streamer.c
contrib/gcc-5.0/gcc/tree-vrp.c
contrib/gcc-5.0/gcc/tree.c
contrib/gcc-5.0/gcc/ubsan.c
contrib/gcc-5.0/gcc/varasm.c
contrib/gcc-5.0/gcc/varpool.c
contrib/gcc-5.0/include/floatformat.h
contrib/gcc-5.0/libgcc/config/nvptx/realloc.c
contrib/gcc-5.0/libgomp/libgomp-plugin.c
contrib/gcc-5.0/libgomp/oacc-ptx.h
contrib/gcc-5.0/libgomp/target.c
contrib/gcc-5.0/libstdc++-v3/include/bits/algorithmfwd.h
contrib/gcc-5.0/libstdc++-v3/include/bits/basic_string.h
contrib/gcc-5.0/libstdc++-v3/include/bits/stl_algo.h
contrib/gcc-5.0/libstdc++-v3/src/c++11/codecvt.cc

index 9851ac7..cf7d741 100644 (file)
@@ -1,2 +1,2 @@
-220677
-Last Changed Date: 2015-02-13 08:56:14 +0100 (Fri, 13 Feb 2015)
+220871
+Last Changed Date: 2015-02-20 15:40:00 +0100 (Fri, 20 Feb 2015)
index 5b7dacb..fb2af0d 100644 (file)
@@ -2505,6 +2505,7 @@ check_format_types (location_t loc, format_wanted_type *types)
          && TREE_CODE (cur_type) == INTEGER_TYPE
          && warn_format_signedness
          && TYPE_UNSIGNED (wanted_type)
+         && cur_param != NULL_TREE
          && TREE_CODE (cur_param) == NOP_EXPR)
        {
          tree t = TREE_TYPE (TREE_OPERAND (cur_param, 0));
index 48c2bcb..8eeee9c 100644 (file)
@@ -5962,7 +5962,8 @@ grokdeclarator (const struct c_declarator *declarator,
            /* Complain about arrays of incomplete types.  */
            if (!COMPLETE_TYPE_P (type))
              {
-               error_at (loc, "array type has incomplete element type");
+               error_at (loc, "array type has incomplete element type %qT",
+                         type);
                type = error_mark_node;
              }
            else
@@ -6514,6 +6515,19 @@ grokdeclarator (const struct c_declarator *declarator,
              error_at (loc, "unnamed field has incomplete type");
            type = error_mark_node;
          }
+       else if (TREE_CODE (type) == ARRAY_TYPE
+                && TYPE_DOMAIN (type) == NULL_TREE)
+         {
+           /* We have a flexible array member through a typedef.
+              Set suitable range.  Whether this is a correct position
+              for a flexible array member will be determined elsewhere.  */
+           if (!in_system_header_at (input_location))
+             pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not "
+                          "support flexible array members");
+           type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
+           TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node,
+                                                  NULL_TREE);
+         }
        type = c_build_qualified_type (type, type_quals);
        decl = build_decl (declarator->id_loc,
                           FIELD_DECL, declarator->u.id, type);
index a71f68c..1ad08dc 100644 (file)
@@ -2191,6 +2191,16 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
 
   if (callback (this, data))
     return true;
+  FOR_EACH_ALIAS (this, ref)
+    {
+      cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+      if (include_overwritable
+         || alias->get_availability () > AVAIL_INTERPOSABLE)
+       if (alias->call_for_symbol_thunks_and_aliases (callback, data,
+                                                    include_overwritable,
+                                                    exclude_virtual_thunks))
+         return true;
+    }
   for (e = callers; e; e = e->next_caller)
     if (e->caller->thunk.thunk_p
        && (include_overwritable
@@ -2202,43 +2212,6 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
                                                       exclude_virtual_thunks))
        return true;
 
-  FOR_EACH_ALIAS (this, ref)
-    {
-      cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
-      if (include_overwritable
-         || alias->get_availability () > AVAIL_INTERPOSABLE)
-       if (alias->call_for_symbol_thunks_and_aliases (callback, data,
-                                                    include_overwritable,
-                                                    exclude_virtual_thunks))
-         return true;
-    }
-  return false;
-}
-
-/* Call callback on function and aliases associated to the function.
-   When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
-   skipped.  */
-
-bool
-cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
-                                                           void *),
-                                         void *data,
-                                         bool include_overwritable)
-{
-  ipa_ref *ref;
-
-  if (callback (this, data))
-    return true;
-
-  FOR_EACH_ALIAS (this, ref)
-    {
-      cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
-      if (include_overwritable
-         || alias->get_availability () > AVAIL_INTERPOSABLE)
-       if (alias->call_for_symbol_and_aliases (callback, data,
-                                               include_overwritable))
-         return true;
-    }
   return false;
 }
 
@@ -2430,37 +2403,6 @@ cgraph_edge::maybe_hot_p (void)
   return true;
 }
 
-/* Return true when function can be removed from callgraph
-   if all direct calls are eliminated.  */
-
-bool
-cgraph_node::can_remove_if_no_direct_calls_and_refs_p (void)
-{
-  gcc_assert (!global.inlined_to);
-  /* Instrumentation clones should not be removed before
-     instrumentation happens.  New callers may appear after
-     instrumentation.  */
-  if (instrumentation_clone
-      && !chkp_function_instrumented_p (decl))
-    return false;
-  /* Extern inlines can always go, we will use the external definition.  */
-  if (DECL_EXTERNAL (decl))
-    return true;
-  /* When function is needed, we can not remove it.  */
-  if (force_output || used_from_other_partition)
-    return false;
-  if (DECL_STATIC_CONSTRUCTOR (decl)
-      || DECL_STATIC_DESTRUCTOR (decl))
-    return false;
-  /* Only COMDAT functions can be removed if externally visible.  */
-  if (externally_visible
-      && (!DECL_COMDAT (decl)
-         || forced_by_abi
-         || used_from_object_file_p ()))
-    return false;
-  return true;
-}
-
 /* Worker for cgraph_can_remove_if_no_direct_calls_p.  */
 
 static bool
@@ -3363,4 +3305,24 @@ cgraph_c_finalize (void)
   version_info_node = NULL;
 }
 
+/* A wroker for call_for_symbol_and_aliases.  */
+
+bool
+cgraph_node::call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
+                                                             void *),
+                                           void *data,
+                                           bool include_overwritable)
+{
+  ipa_ref *ref;
+  FOR_EACH_ALIAS (this, ref)
+    {
+      cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+      if (include_overwritable
+         || alias->get_availability () > AVAIL_INTERPOSABLE)
+       if (alias->call_for_symbol_and_aliases (callback, data,
+                                               include_overwritable))
+         return true;
+    }
+  return false;
+}
 #include "gt-cgraph.h"
index b9a276c..ec3cccd 100644 (file)
@@ -377,10 +377,6 @@ public:
   /* Verify symbol table for internal consistency.  */
   static DEBUG_FUNCTION void verify_symtab_nodes (void);
 
-  /* Return true when NODE is known to be used from other (non-LTO)
-     object file. Known only when doing LTO via linker plugin.  */
-  static bool used_from_object_file_p_worker (symtab_node *node);
-
   /* Type of the symbol.  */
   ENUM_BITFIELD (symtab_type) type : 8;
 
@@ -523,6 +519,10 @@ protected:
      allocated structure is returned.  */
   struct symbol_priority_map *priority_info (void);
 
+  /* Worker for call_for_symbol_and_aliases_1.  */
+  bool call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *, void *),
+                                     void *data,
+                                     bool include_overwrite);
 private:
   /* Worker for set_section.  */
   static bool set_section (symtab_node *n, void *s);
@@ -532,6 +532,9 @@ private:
 
   /* Worker searching noninterposable alias.  */
   static bool noninterposable_alias (symtab_node *node, void *data);
+
+  /* Worker for ultimate_alias_target.  */
+  symtab_node *ultimate_alias_target_1 (enum availability *avail = NULL);
 };
 
 /* Walk all aliases for NODE.  */
@@ -1291,6 +1294,12 @@ public:
   unsigned nonfreeing_fn : 1;
   /* True if there was multiple COMDAT bodies merged by lto-symtab.  */
   unsigned merged : 1;
+
+private:
+  /* Worker for call_for_symbol_and_aliases.  */
+  bool call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
+                                                       void *),
+                                     void *data, bool include_overwritable);
 };
 
 /* A cgraph node set is a collection of cgraph nodes.  A cgraph node
@@ -1670,9 +1679,9 @@ public:
   /* Call calback on varpool symbol and aliases associated to varpool symbol.
      When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
      skipped. */
-  bool call_for_node_and_aliases (bool (*callback) (varpool_node *, void *),
-                                 void *data,
-                                  bool include_overwritable);
+  bool call_for_symbol_and_aliases (bool (*callback) (varpool_node *, void *),
+                                   void *data,
+                                   bool include_overwritable);
 
   /* Return true when variable should be considered externally visible.  */
   bool externally_visible_p (void);
@@ -1747,6 +1756,11 @@ public:
 private:
   /* Assemble thunks and aliases associated to varpool node.  */
   void assemble_aliases (void);
+
+  /* Worker for call_for_node_and_aliases.  */
+  bool call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *, void *),
+                                     void *data,
+                                     bool include_overwritable);
 };
 
 /* Every top level asm statement is put into a asm_node.  */
@@ -2181,7 +2195,6 @@ bool cgraph_function_possibly_inlined_p (tree);
 const char* cgraph_inline_failed_string (cgraph_inline_failed_t);
 cgraph_inline_failed_type_t cgraph_inline_failed_type (cgraph_inline_failed_t);
 
-bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution);
 extern bool gimple_check_call_matching_types (gimple, tree, bool);
 
 /* In cgraphunit.c  */
@@ -2193,6 +2206,7 @@ basic_block init_lowered_empty_function (tree, bool, gcov_type);
 
 /* In cgraphclones.c  */
 
+tree clone_function_name_1 (const char *, const char *);
 tree clone_function_name (tree decl, const char *);
 
 void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *,
@@ -2209,6 +2223,9 @@ bool ipa_discover_readonly_nonaddressable_vars (void);
 /* In varpool.c  */
 tree ctor_for_folding (tree);
 
+/* In tree-chkp.c  */
+extern bool chkp_function_instrumented_p (tree fndecl);
+
 /* Return true when the symbol is real symbol, i.e. it is not inline clone
    or abstract function kept for debug info purposes only.  */
 inline bool
@@ -2270,6 +2287,7 @@ symtab_node::get_alias_target (void)
 }
 
 /* Return next reachable static symbol with initializer after the node.  */
+
 inline symtab_node *
 symtab_node::next_defined_symbol (void)
 {
@@ -2282,6 +2300,74 @@ symtab_node::next_defined_symbol (void)
   return NULL;
 }
 
+/* Iterates I-th reference in the list, REF is also set.  */
+
+inline ipa_ref *
+symtab_node::iterate_reference (unsigned i, ipa_ref *&ref)
+{
+  vec_safe_iterate (ref_list.references, i, &ref);
+
+  return ref;
+}
+
+/* Iterates I-th referring item in the list, REF is also set.  */
+
+inline ipa_ref *
+symtab_node::iterate_referring (unsigned i, ipa_ref *&ref)
+{
+  ref_list.referring.iterate (i, &ref);
+
+  return ref;
+}
+
+/* Iterates I-th referring alias item in the list, REF is also set.  */
+
+inline ipa_ref *
+symtab_node::iterate_direct_aliases (unsigned i, ipa_ref *&ref)
+{
+  ref_list.referring.iterate (i, &ref);
+
+  if (ref && ref->use != IPA_REF_ALIAS)
+    return NULL;
+
+  return ref;
+}
+
+/* Return true if list contains an alias.  */
+
+inline bool
+symtab_node::has_aliases_p (void)
+{
+  ipa_ref *ref = NULL;
+
+  return (iterate_direct_aliases (0, ref) != NULL);
+}
+
+/* Return true when RESOLUTION indicate that linker will use
+   the symbol from non-LTO object files.  */
+
+inline bool
+resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
+{
+  return (resolution == LDPR_PREVAILING_DEF
+         || resolution == LDPR_PREEMPTED_REG
+         || resolution == LDPR_RESOLVED_EXEC
+         || resolution == LDPR_RESOLVED_DYN);
+}
+
+/* Return true when symtab_node is known to be used from other (non-LTO)
+   object file. Known only when doing LTO via linker plugin.  */
+
+inline bool
+symtab_node::used_from_object_file_p (void)
+{
+  if (!TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
+    return false;
+  if (resolution_used_from_other_file_p (resolution))
+    return true;
+  return false;
+}
+
 /* Return varpool node for given symbol and check it is a function. */
 
 inline varpool_node *
@@ -2644,6 +2730,37 @@ cgraph_node::only_called_directly_or_aliased_p (void)
          && !externally_visible);
 }
 
+/* Return true when function can be removed from callgraph
+   if all direct calls are eliminated.  */
+
+inline bool
+cgraph_node::can_remove_if_no_direct_calls_and_refs_p (void)
+{
+  gcc_checking_assert (!global.inlined_to);
+  /* Instrumentation clones should not be removed before
+     instrumentation happens.  New callers may appear after
+     instrumentation.  */
+  if (instrumentation_clone
+      && !chkp_function_instrumented_p (decl))
+    return false;
+  /* Extern inlines can always go, we will use the external definition.  */
+  if (DECL_EXTERNAL (decl))
+    return true;
+  /* When function is needed, we can not remove it.  */
+  if (force_output || used_from_other_partition)
+    return false;
+  if (DECL_STATIC_CONSTRUCTOR (decl)
+      || DECL_STATIC_DESTRUCTOR (decl))
+    return false;
+  /* Only COMDAT functions can be removed if externally visible.  */
+  if (externally_visible
+      && (!DECL_COMDAT (decl)
+         || forced_by_abi
+         || used_from_object_file_p ()))
+    return false;
+  return true;
+}
+
 /* Return true when variable can be removed from variable pool
    if all direct calls are eliminated.  */
 
@@ -2699,6 +2816,23 @@ varpool_node::get_alias_target (void)
   return dyn_cast <varpool_node *> (symtab_node::get_alias_target ());
 }
 
+/* Walk the alias chain to return the symbol NODE is alias of.
+   If NODE is not an alias, return NODE.
+   When AVAILABILITY is non-NULL, get minimal availability in the chain.  */
+
+inline symtab_node *
+symtab_node::ultimate_alias_target (enum availability *availability)
+{
+  if (!alias)
+    {
+      if (availability)
+       *availability = get_availability ();
+      return this;
+    }
+
+  return ultimate_alias_target_1 (availability);
+}
+
 /* Given function symbol, walk the alias chain to return the function node
    is alias of. Do not walk through thunks.
    When AVAILABILITY is non-NULL, get minimal availability in the chain.  */
@@ -2706,8 +2840,8 @@ varpool_node::get_alias_target (void)
 inline cgraph_node *
 cgraph_node::ultimate_alias_target (enum availability *availability)
 {
-  cgraph_node *n = dyn_cast <cgraph_node *> (symtab_node::ultimate_alias_target
-    (availability));
+  cgraph_node *n = dyn_cast <cgraph_node *>
+    (symtab_node::ultimate_alias_target (availability));
   if (!n && availability)
     *availability = AVAIL_NOT_AVAILABLE;
   return n;
@@ -2756,6 +2890,7 @@ cgraph_edge::redirect_callee (cgraph_node *n)
 }
 
 /* Return true when the edge represents a direct recursion.  */
+
 inline bool
 cgraph_edge::recursive_p (void)
 {
@@ -2813,7 +2948,11 @@ cgraph_node::optimize_for_size_p (void)
     return false;
 }
 
-inline symtab_node * symtab_node::get_create (tree node)
+/* Return symtab_node for NODE or create one if it is not present
+   in symtab.  */
+
+inline symtab_node *
+symtab_node::get_create (tree node)
 {
   if (TREE_CODE (node) == VAR_DECL)
     return varpool_node::get_create (node);
@@ -2821,6 +2960,68 @@ inline symtab_node * symtab_node::get_create (tree node)
     return cgraph_node::get_create (node);
 }
 
+/* Return availability of NODE.  */
+
+inline enum availability
+symtab_node::get_availability (void)
+{
+  if (is_a <cgraph_node *> (this))
+    return dyn_cast <cgraph_node *> (this)->get_availability ();
+  else
+    return dyn_cast <varpool_node *> (this)->get_availability ();;
+}
+
+/* Call calback on symtab node and aliases associated to this node.
+   When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+   skipped. */
+
+inline bool
+symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
+                                                           void *),
+                                         void *data,
+                                         bool include_overwritable)
+{
+  if (callback (this, data))
+    return true;
+  if (has_aliases_p ())
+    return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
+  return false;
+}
+
+/* Call callback on function and aliases associated to the function.
+   When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+   skipped.  */
+
+inline bool
+cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
+                                                           void *),
+                                         void *data,
+                                         bool include_overwritable)
+{
+  if (callback (this, data))
+    return true;
+  if (has_aliases_p ())
+    return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
+  return false;
+}
+
+/* Call calback on varpool symbol and aliases associated to varpool symbol.
+   When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+   skipped. */
+
+inline bool
+varpool_node::call_for_symbol_and_aliases (bool (*callback) (varpool_node *,
+                                                            void *),
+                                          void *data,
+                                          bool include_overwritable)
+{
+  if (callback (this, data))
+    return true;
+  if (has_aliases_p ())
+    return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
+  return false;
+}
+
 /* Build polymorphic call context for indirect call E.  */
 
 inline
index 2a7de2e..d0a5f70 100644 (file)
@@ -533,19 +533,19 @@ cgraph_node::create_clone (tree decl, gcov_type gcov_count, int freq,
   return new_node;
 }
 
-/* Return a new assembler name for a clone of DECL with SUFFIX.  */
-
 static GTY(()) unsigned int clone_fn_id_num;
 
+/* Return a new assembler name for a clone with SUFFIX of a decl named
+   NAME.  */
+
 tree
-clone_function_name (tree decl, const char *suffix)
+clone_function_name_1 (const char *name, const char *suffix)
 {
-  tree name = DECL_ASSEMBLER_NAME (decl);
-  size_t len = IDENTIFIER_LENGTH (name);
+  size_t len = strlen (name);
   char *tmp_name, *prefix;
 
   prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
-  memcpy (prefix, IDENTIFIER_POINTER (name), len);
+  memcpy (prefix, name, len);
   strcpy (prefix + len + 1, suffix);
 #ifndef NO_DOT_IN_LABEL
   prefix[len] = '.';
@@ -558,6 +558,16 @@ clone_function_name (tree decl, const char *suffix)
   return get_identifier (tmp_name);
 }
 
+/* Return a new assembler name for a clone of DECL with SUFFIX.  */
+
+tree
+clone_function_name (tree decl, const char *suffix)
+{
+  tree name = DECL_ASSEMBLER_NAME (decl);
+  return clone_function_name_1 (IDENTIFIER_POINTER (name), suffix);
+}
+
+
 /* Create callgraph node clone with new declaration.  The actual body will
    be copied later at compilation stage.
 
@@ -577,7 +587,7 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
   char *name;
 
   if (!in_lto_p)
-    gcc_checking_assert  (tree_versionable_function_p (old_decl));
+    gcc_checking_assert (tree_versionable_function_p (old_decl));
 
   gcc_assert (local.can_change_signature || !args_to_skip);
 
@@ -617,6 +627,8 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
      ABI support for this.  */
   set_new_clone_decl_and_node_flags (new_node);
   new_node->clone.tree_map = tree_map;
+  if (!implicit_section)
+    new_node->set_section (get_section ());
 
   /* Clones of global symbols or symbols with unique names are unique.  */
   if ((TREE_PUBLIC (old_decl)
@@ -1009,6 +1021,8 @@ cgraph_node::create_version_clone_with_body
   new_version_node->externally_visible = 0;
   new_version_node->local.local = 1;
   new_version_node->lowered = true;
+  if (!implicit_section)
+    new_version_node->set_section (get_section ());
   /* Clones of global symbols or symbols with unique names are unique.  */
   if ((TREE_PUBLIC (old_decl)
        && !DECL_EXTERNAL (old_decl)
index 0c60e84..4fa12f5 100644 (file)
@@ -1458,6 +1458,10 @@ fipa-cp-clone
 Common Report Var(flag_ipa_cp_clone) Optimization
 Perform cloning to make Interprocedural constant propagation stronger
 
+fipa-cp-alignment
+Common Report Var(flag_ipa_cp_alignment) Optimization
+Perform alignment discovery and propagation to make Interprocedural constant propagation stronger
+
 fipa-profile
 Common Report Var(flag_ipa_profile) Init(0) Optimization
 Perform interprocedural profile propagation
@@ -2065,6 +2069,10 @@ fssa-phiopt
 Common Report Var(flag_ssa_phiopt) Optimization
 Optimize conditional patterns using SSA PHI nodes
 
+fstdarg-opt
+Common Report Var(flag_stdarg_opt) Init(1) Optimization
+Optimize amount of stdarg registers saved to stack at start of function
+
 fvariable-expansion-in-unroller
 Common Report Var(flag_variable_expansion_in_unroller) Optimization
 Apply variable expansion when loops are unrolled
index f2076c6..2b15185 100644 (file)
@@ -1694,6 +1694,19 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
      difference in top-level cv-qualification is subsumed by the
      initialization itself and does not constitute a conversion.  */
 
+  /* [dcl.init.ref]
+
+     Otherwise, the reference shall be an lvalue reference to a
+     non-volatile const type, or the reference shall be an rvalue
+     reference.
+
+     We try below to treat this as a bad conversion to improve diagnostics,
+     but if TO is an incomplete class, we need to reject this conversion
+     now to avoid unnecessary instantiation.  */
+  if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto)
+      && !COMPLETE_TYPE_P (to))
+    return NULL;
+
   /* We're generating a temporary now, but don't bind any more in the
      conversion (specifically, don't slice the temporary returned by a
      conversion operator).  */
index 2b56cb2..32a23ff 100644 (file)
@@ -416,7 +416,8 @@ check_constexpr_bind_expr_vars (tree t)
 
   for (tree var = BIND_EXPR_VARS (t); var; var = DECL_CHAIN (var))
     if (TREE_CODE (var) == TYPE_DECL
-       && DECL_IMPLICIT_TYPEDEF_P (var))
+       && DECL_IMPLICIT_TYPEDEF_P (var)
+       && !LAMBDA_TYPE_P (TREE_TYPE (var)))
       return false;
   return true;
 }
@@ -3638,7 +3639,6 @@ maybe_constant_value (tree t, tree decl)
 
   r = cxx_eval_outermost_constant_expr (t, true, true, decl);
 #ifdef ENABLE_CHECKING
-  /* cp_tree_equal looks through NOPs, so allow them.  */
   gcc_assert (r == t
              || CONVERT_EXPR_P (t)
              || TREE_CODE (t) == VIEW_CONVERT_EXPR
index 810acd5..67c5ae7 100644 (file)
@@ -3569,7 +3569,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
     return lookup_template_class (t, TREE_OPERAND (fullname, 1),
                                  NULL_TREE, context,
                                  /*entering_scope=*/0,
-                                 tf_warning_or_error | tf_user);
+                                 complain | tf_user);
   
   if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
     t = TREE_TYPE (t);
@@ -12205,6 +12205,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
       /* First try ordinary name lookup, ignoring hidden class name
         injected via friend declaration.  */
       decl = lookup_name_prefer_type (name, 2);
+      decl = strip_using_decl (decl);
       /* If that fails, the name will be placed in the smallest
         non-class, non-function-prototype scope according to 3.3.1/5.
         We may already have a hidden name declared as friend in this
@@ -13721,7 +13722,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
          && targetm.cxx.cdtor_returns_this ()))
     {
       cdtor_label = build_decl (input_location, 
-                               LABEL_DECL, NULL_TREE, NULL_TREE);
+                               LABEL_DECL, NULL_TREE, void_type_node);
       DECL_CONTEXT (cdtor_label) = current_function_decl;
     }
 
index e81e9d3..e0b455c 100644 (file)
@@ -33060,6 +33060,12 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
 
     case PRAGMA_IVDEP:
       {
+       if (context == pragma_external)
+         {
+           error_at (pragma_tok->location,
+                     "%<#pragma GCC ivdep%> must be inside a function");
+           break;
+         }
        cp_parser_skip_to_pragma_eol (parser, pragma_tok);
        cp_token *tok;
        tok = cp_lexer_peek_token (the_parser->lexer);
index 3317dad..9a00d0d 100644 (file)
@@ -7324,7 +7324,22 @@ template_args_equal (tree ot, tree nt)
   else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
     return 0;
   else
-    return cp_tree_equal (ot, nt);
+    {
+      /* Try to treat a template non-type argument that has been converted
+        to the parameter type as equivalent to one that hasn't yet.  */
+      for (enum tree_code code1 = TREE_CODE (ot);
+          CONVERT_EXPR_CODE_P (code1)
+            || code1 == NON_LVALUE_EXPR;
+          code1 = TREE_CODE (ot))
+       ot = TREE_OPERAND (ot, 0);
+      for (enum tree_code code2 = TREE_CODE (nt);
+          CONVERT_EXPR_CODE_P (code2)
+            || code2 == NON_LVALUE_EXPR;
+          code2 = TREE_CODE (nt))
+       nt = TREE_OPERAND (nt, 0);
+
+      return cp_tree_equal (ot, nt);
+    }
 }
 
 /* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets of
index c51e42d..c8e6f0c 100644 (file)
@@ -2745,20 +2745,8 @@ cp_tree_equal (tree t1, tree t2)
   if (!t1 || !t2)
     return false;
 
-  for (code1 = TREE_CODE (t1);
-       CONVERT_EXPR_CODE_P (code1)
-        || code1 == NON_LVALUE_EXPR;
-       code1 = TREE_CODE (t1))
-    t1 = TREE_OPERAND (t1, 0);
-  for (code2 = TREE_CODE (t2);
-       CONVERT_EXPR_CODE_P (code2)
-        || code2 == NON_LVALUE_EXPR;
-       code2 = TREE_CODE (t2))
-    t2 = TREE_OPERAND (t2, 0);
-
-  /* They might have become equal now.  */
-  if (t1 == t2)
-    return true;
+  code1 = TREE_CODE (t1);
+  code2 = TREE_CODE (t2);
 
   if (code1 != code2)
     return false;
@@ -2996,6 +2984,9 @@ cp_tree_equal (tree t1, tree t2)
     case DYNAMIC_CAST_EXPR:
     case IMPLICIT_CONV_EXPR:
     case NEW_EXPR:
+    CASE_CONVERT:
+    case NON_LVALUE_EXPR:
+    case VIEW_CONVERT_EXPR:
       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
        return false;
       /* Now compare operands as usual.  */
index 4368c73..6e02534 100644 (file)
@@ -82,7 +82,7 @@ suggestions for improvement of GCC are welcome in any case.
 @end itemize
 
 @node Bug Reporting
-@section How and where to Report Bugs
+@section How and Where to Report Bugs
 @cindex compiler bugs, reporting
 
 Bugs should be reported to the bug database at @value{BUGURL}.
index b06661e..54c1941 100644 (file)
@@ -845,7 +845,7 @@ the middle operand uses the value already computed without the undesirable
 effects of recomputing it.
 
 @node __int128
-@section 128-bit integers
+@section 128-bit Integers
 @cindex @code{__int128} data types
 
 As an extension the integer scalar type @code{__int128} is supported for
@@ -1548,7 +1548,7 @@ struct foo d[1] = @{ @{ 1, @{ 2, 3, 4 @} @} @};  // @r{Invalid.}
 @end smallexample
 
 @node Empty Structures
-@section Structures With No Members
+@section Structures with No Members
 @cindex empty structures
 @cindex zero-size structures
 
@@ -1786,7 +1786,7 @@ The option @option{-Wpointer-arith} requests a warning if these extensions
 are used.
 
 @node Pointers to Arrays
-@section Pointers to arrays with qualifiers work as expected
+@section Pointers to Arrays with Qualifiers Work as Expected
 @cindex pointers to arrays
 @cindex const qualifier
 
@@ -8154,7 +8154,7 @@ You cannot operate between vectors of different lengths or different
 signedness without a cast.
 
 @node Offsetof
-@section Offsetof
+@section Support for @code{offsetof}
 @findex __builtin_offsetof
 
 GCC implements for both C and C++ a syntactic extension to implement
@@ -8182,7 +8182,7 @@ may be dependent.  In either case, @var{member} may consist of a single
 identifier, or a sequence of member accesses and array references.
 
 @node __sync Builtins
-@section Legacy __sync Built-in Functions for Atomic Memory Access
+@section Legacy @code{__sync} Built-in Functions for Atomic Memory Access
 
 The following built-in functions
 are intended to be compatible with those described
@@ -8322,7 +8322,7 @@ are not prevented from being speculated to before the barrier.
 @end table
 
 @node __atomic Builtins
-@section Built-in functions for memory model aware atomic operations
+@section Built-in Functions for Memory Model Aware Atomic Operations
 
 The following built-in functions approximately match the requirements for
 C++11 memory model. Many are similar to the @samp{__sync} prefixed built-in
@@ -8591,7 +8591,7 @@ compiler may also ignore this parameter.
 @end deftypefn
 
 @node Integer Overflow Builtins
-@section Built-in functions to perform arithmetics and arithmetic overflow checking.
+@section Built-in Functions to Perform Arithmetic with Overflow Checking
 
 The following built-in functions allow performing simple arithmetic operations
 together with checking whether the operations overflowed.
@@ -8650,7 +8650,7 @@ functions above, except they perform multiplication, instead of addition.
 @end deftypefn
 
 @node x86 specific memory model extensions for transactional memory
-@section x86 specific memory model extensions for transactional memory
+@section x86-Specific Memory Model Extensions for Transactional Memory
 
 The x86 architecture supports additional memory ordering flags
 to mark lock critical sections for hardware lock elision. 
@@ -8986,7 +8986,7 @@ returns -1.
 @end deftypefn
 
 @node Cilk Plus Builtins
-@section Cilk Plus C/C++ language extension Built-in Functions.
+@section Cilk Plus C/C++ Language Extension Built-in Functions
 
 GCC provides support for the following built-in reduction funtions if Cilk Plus
 is enabled. Cilk Plus can be enabled using the @option{-fcilkplus} flag.
@@ -11178,7 +11178,7 @@ number of an IACC register.  See @pxref{Other Built-in Functions}
 for more details.
 
 @node Directly-mapped Integer Functions
-@subsubsection Directly-mapped Integer Functions
+@subsubsection Directly-Mapped Integer Functions
 
 The functions listed below map directly to FR-V I-type instructions.
 
@@ -11217,7 +11217,7 @@ The functions listed below map directly to FR-V I-type instructions.
 @end multitable
 
 @node Directly-mapped Media Functions
-@subsubsection Directly-mapped Media Functions
+@subsubsection Directly-Mapped Media Functions
 
 The functions listed below map directly to FR-V M-type instructions.
 
@@ -11490,7 +11490,7 @@ The functions listed below map directly to FR-V M-type instructions.
 @end multitable
 
 @node Raw read/write Functions
-@subsubsection Raw read/write Functions
+@subsubsection Raw Read/Write Functions
 
 This sections describes built-in functions related to read and write
 instructions to access memory.  These functions generate
@@ -17255,12 +17255,13 @@ int __builtin_ia32_xtest ()
 @end smallexample
 
 @node x86 transactional memory intrinsics
-@subsection x86 transaction memory intrinsics
+@subsection x86 Transactional Memory Intrinsics
 
-Hardware transactional memory intrinsics for x86. These allow to use
+These hardware transactional memory intrinsics for x86 allow you to use
 memory transactions with RTM (Restricted Transactional Memory).
-For using HLE (Hardware Lock Elision) see @ref{x86 specific memory model extensions for transactional memory} instead.
 This support is enabled with the @option{-mrtm} option.
+For using HLE (Hardware Lock Elision) see 
+@ref{x86 specific memory model extensions for transactional memory} instead.
 
 A memory transaction commits all changes to memory in an atomic way,
 as visible to other threads. If the transaction fails it is rolled back
@@ -17271,12 +17272,12 @@ and suitable fallback code always needs to be supplied.
 
 @deftypefn {RTM Function} {unsigned} _xbegin ()
 Start a RTM (Restricted Transactional Memory) transaction. 
-Returns _XBEGIN_STARTED when the transaction
+Returns @code{_XBEGIN_STARTED} when the transaction
 started successfully (note this is not 0, so the constant has to be 
-explicitely tested). When the transaction aborts all side effects
+explicitly tested).  If the transaction aborts, all side-effects
 are undone and an abort code is returned. There is no guarantee
 any transaction ever succeeds, so there always needs to be a valid
-tested fallback path.
+fallback path.
 @end deftypefn
 
 @smallexample
@@ -17290,38 +17291,38 @@ if ((status = _xbegin ()) == _XBEGIN_STARTED) @{
 @}
 @end smallexample
 
-Valid abort status bits (when the value is not @code{_XBEGIN_STARTED}) are:
+If the transaction aborts, the return value is one of:
 
 @table @code
 @item _XABORT_EXPLICIT
-Transaction explicitely aborted with @code{_xabort}. The parameter passed
-to @code{_xabort} is available with @code{_XABORT_CODE(status)}
+Transaction was explicitly aborted with @code{_xabort}.  The parameter passed
+to @code{_xabort} is available with @code{_XABORT_CODE(status)}.
 @item _XABORT_RETRY
 Transaction retry is possible.
 @item _XABORT_CONFLICT
-Transaction abort due to a memory conflict with another thread
+Transaction abort due to a memory conflict with another thread.
 @item _XABORT_CAPACITY
-Transaction abort due to the transaction using too much memory
+Transaction abort due to the transaction using too much memory.
 @item _XABORT_DEBUG
-Transaction abort due to a debug trap
+Transaction abort due to a debug trap.
 @item _XABORT_NESTED
-Transaction abort in a inner nested transaction
+Transaction abort in an inner nested transaction.
 @end table
 
 @deftypefn {RTM Function} {void} _xend ()
-Commit the current transaction. When no transaction is active this will
-fault. All memory side effects of the transactions will become visible
-to other threads in an atomic matter.
+Commit the current transaction. When no transaction is active this faults.
+All memory side-effects of the transaction become visible
+to other threads in an atomic manner.
 @end deftypefn
 
 @deftypefn {RTM Function} {int} _xtest ()
-Return a value not zero when a transaction is currently active, otherwise 0.
+Return a nonzero value if a transaction is currently active, otherwise 0.
 @end deftypefn
 
 @deftypefn {RTM Function} {void} _xabort (status)
 Abort the current transaction. When no transaction is active this is a no-op.
-status must be a 8bit constant, that is included in the status code returned
-by @code{_xbegin}
+The @var{status} is an 8-bit constant; its value is encoded in the return 
+value from @code{_xbegin}.
 @end deftypefn
 
 @node Target Format Checks
@@ -17946,7 +17947,7 @@ void ignore_vec_dep (int *a, int k, int c, int m)
 
 
 @node Unnamed Fields
-@section Unnamed struct/union fields within structs/unions
+@section Unnamed Structure and Union Fields
 @cindex @code{struct}
 @cindex @code{union}
 
@@ -18287,7 +18288,7 @@ Non-@code{static} members shall not be @code{__thread}.
 @end itemize
 
 @node Binary constants
-@section Binary constants using the @samp{0b} prefix
+@section Binary Constants using the @samp{0b} Prefix
 @cindex Binary constants using the @samp{0b} prefix
 
 Integer constants can be written as binary constants, consisting of a
@@ -18522,7 +18523,7 @@ almost certainly breaks things.
 another way to control placement of these constructs.
 
 @node C++ Interface
-@section #pragma interface and implementation
+@section C++ Interface and Implementation Pragmas
 
 @cindex interface and implementation headers, C++
 @cindex C++ interface and implementation headers
@@ -18757,7 +18758,7 @@ duplication.
 @end enumerate
 
 @node Bound member functions
-@section Extracting the function pointer from a bound pointer to member function
+@section Extracting the Function Pointer from a Bound Pointer to Member Function
 @cindex pmf
 @cindex pointer to member function
 @cindex bound pointer to member function
index 935cb68..dba36e0 100644 (file)
@@ -591,7 +591,7 @@ collected at that point to be dumped to @file{.gcda} output files.
 @c man end
 
 @node Gcov Data Files
-@section Brief description of @command{gcov} data files
+@section Brief Description of @command{gcov} Data Files
 
 @command{gcov} uses two files for profiling.  The names of these files
 are derived from the original @emph{object} file by substituting the
@@ -618,7 +618,7 @@ and functions provided in that header file should be used to access the
 coverage files.
 
 @node Cross-profiling
-@section Data file relocation to support cross-profiling
+@section Data File Relocation to Support Cross-Profiling
 
 Running the program will cause profile output to be generated.  For each
 source file compiled with @option{-fprofile-arcs}, an accompanying @file{.gcda}
index 39361e0..333651f 100644 (file)
@@ -3,7 +3,7 @@
 @c For copying conditions, see the file gcc.texi.
 
 @node C Implementation
-@chapter C Implementation-defined behavior
+@chapter C Implementation-Defined Behavior
 @cindex implementation-defined behavior, C language
 
 A conforming implementation of ISO C is required to document its
@@ -279,7 +279,7 @@ truncated towards zero.
 @end itemize
 
 @node Floating point implementation
-@section Floating point
+@section Floating Point
 
 @itemize @bullet
 @item
@@ -375,7 +375,7 @@ defined by GCC itself.
 @end itemize
 
 @node Arrays and pointers implementation
-@section Arrays and pointers
+@section Arrays and Pointers
 
 @itemize @bullet
 @item
@@ -455,7 +455,7 @@ used to determine if a function has not been inlined and why not.
 @end itemize
 
 @node Structures unions enumerations and bit-fields implementation
-@section Structures, unions, enumerations, and bit-fields
+@section Structures, Unions, Enumerations, and Bit-Fields
 
 @itemize @bullet
 @item
@@ -601,7 +601,7 @@ GCC is only limited by available memory.
 @end itemize
 
 @node Preprocessing directives implementation
-@section Preprocessing directives
+@section Preprocessing Directives
 
 @xref{Implementation-defined behavior, , Implementation-defined
 behavior, cpp, The C Preprocessor}, for details of these aspects of
@@ -665,7 +665,7 @@ respectively, the date and time of translation are not available (C90
 @end itemize
 
 @node Library functions implementation
-@section Library functions
+@section Library Functions
 
 The behavior of most of these points are dependent on the implementation
 of the C library, and are not defined by GCC itself.
@@ -732,7 +732,7 @@ Determined by ABI@.
 @end itemize
 
 @node Locale-specific behavior implementation
-@section Locale-specific behavior
+@section Locale-Specific Behavior
 
 The behavior of these points are dependent on the implementation
 of the C library, and are not defined by GCC itself.
index 54e33a8..66176e5 100644 (file)
@@ -3,7 +3,7 @@
 @c For copying conditions, see the file gcc.texi.
 
 @node C++ Implementation
-@chapter C++ Implementation-defined behavior
+@chapter C++ Implementation-Defined Behavior
 @cindex implementation-defined behavior, C++ language
 
 A conforming implementation of ISO C++ is required to document its
@@ -31,7 +31,7 @@ environment); refer to their documentation for details.
 @end menu
 
 @node Conditionally-supported behavior
-@section Conditionally-supported behavior
+@section Conditionally-Supported Behavior
 
 @cite{Each implementation shall include documentation that identifies
 all conditionally-supported constructs that it does not support (C++0x
@@ -49,7 +49,7 @@ arguments of such types.
 @end itemize
 
 @node Exception handling
-@section Exception handling
+@section Exception Handling
 
 @itemize @bullet
 @item
index 5cce4f7..ef4cc75 100644 (file)
@@ -387,7 +387,7 @@ Objective-C and Objective-C++ Dialects}.
 -fgcse-sm -fhoist-adjacent-loads -fif-conversion @gol
 -fif-conversion2 -findirect-inlining @gol
 -finline-functions -finline-functions-called-once -finline-limit=@var{n} @gol
--finline-small-functions -fipa-cp -fipa-cp-clone @gol
+-finline-small-functions -fipa-cp -fipa-cp-clone -fipa-cp-alignment @gol
 -fipa-pta -fipa-profile -fipa-pure-const -fipa-reference -fipa-icf @gol
 -fira-algorithm=@var{algorithm} @gol
 -fira-region=@var{region} -fira-hoist-pressure @gol
@@ -430,7 +430,7 @@ Objective-C and Objective-C++ Dialects}.
 -fshrink-wrap -fsignaling-nans -fsingle-precision-constant @gol
 -fsplit-ivs-in-unroller -fsplit-wide-types -fssa-phiopt @gol
 -fstack-protector -fstack-protector-all -fstack-protector-strong @gol
--fstack-protector-explicit -fstrict-aliasing @gol
+-fstack-protector-explicit -fstdarg-opt -fstrict-aliasing @gol
 -fstrict-overflow -fthread-jumps -ftracer -ftree-bit-ccp @gol
 -ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
 -ftree-coalesce-inline-vars -ftree-coalesce-vars -ftree-copy-prop @gol
@@ -840,6 +840,9 @@ Objective-C and Objective-C++ Dialects}.
 -mcustom-fpu-cfg=@var{name} @gol
 -mhal -msmallc -msys-crt0=@var{name} -msys-lib=@var{name}}
 
+@emph{Nvidia PTX Options}
+@gccoptlist{-m32 -m64 -mmainkernel}
+
 @emph{PDP-11 Options}
 @gccoptlist{-mfpu  -msoft-float  -mac0  -mno-ac0  -m40  -m45  -m10 @gol
 -mbcopy  -mbcopy-builtin  -mint32  -mno-int16 @gol
@@ -965,6 +968,7 @@ See RS/6000 and PowerPC Options.
 -maccumulate-outgoing-args -minvalid-symbols @gol
 -matomic-model=@var{atomic-model} @gol
 -mbranch-cost=@var{num} -mzdcbranch -mno-zdcbranch @gol
+-mcbranch-force-delay-slot @gol
 -mfused-madd -mno-fused-madd -mfsca -mno-fsca -mfsrra -mno-fsrra @gol
 -mpretend-cmove -mtas}
 
@@ -7323,6 +7327,7 @@ also turns on the following optimization flags:
 -finline-small-functions @gol
 -findirect-inlining @gol
 -fipa-cp @gol
+-fipa-cp-alignment @gol
 -fipa-sra @gol
 -fipa-icf @gol
 -fisolate-erroneous-paths-dereference @gol
@@ -8302,6 +8307,14 @@ it may significantly increase code size
 (see @option{--param ipcp-unit-growth=@var{value}}).
 This flag is enabled by default at @option{-O3}.
 
+@item -fipa-cp-alignment
+@opindex -fipa-cp-alignment
+When enabled, this optimization propagates alignment of function
+parameters to support better vectorization and string operations.
+
+This flag is enabled by default at @option{-O2} and @option{-Os}.  It
+requires that @option{-fipa-cp} is enabled.
+
 @item -fipa-icf
 @opindex fipa-icf
 Perform Identical Code Folding for functions and read-only variables.
@@ -9854,6 +9867,11 @@ references to local frame addresses.
 Like @option{-fstack-protector} but only protects those functions which
 have the @code{stack_protect} attribute
 
+@item -fstdarg-opt
+@opindex fstdarg-opt
+Optimize the prologue of variadic argument functions with respect to usage of
+those arguments.
+
 @item -fsection-anchors
 @opindex fsection-anchors
 Try to reduce the number of symbolic address calculations by using
@@ -11334,7 +11352,7 @@ independent.
 @c man end
 
 @node Spec Files
-@section Specifying subprocesses and the switches to pass to them
+@section Specifying Subprocesses and the Switches to Pass to Them
 @cindex Spec Files
 
 @command{gcc} is a driver program.  It performs its job by invoking a
@@ -11979,6 +11997,7 @@ platform.
 * MSP430 Options::
 * NDS32 Options::
 * Nios II Options::
+* Nvidia PTX Options::
 * PDP-11 Options::
 * picoChip Options::
 * PowerPC Options::
@@ -12145,7 +12164,7 @@ with @option{-march} or @option{-mtune}, those options take precedence
 over the appropriate part of this option.
 @end table
 
-@subsubsection @option{-march} and @option{-mcpu} feature modifiers
+@subsubsection @option{-march} and @option{-mcpu} Feature Modifiers
 @cindex @option{-march} feature modifiers
 @cindex @option{-mcpu} feature modifiers
 Feature modifiers used with @option{-march} and @option{-mcpu} can be one
@@ -13386,7 +13405,7 @@ Warn about conversions between address spaces in the case where the
 resulting address space is not contained in the incoming address space.
 @end table
 
-@subsubsection @code{EIND} and Devices with more than 128 Ki Bytes of Flash
+@subsubsection @code{EIND} and Devices with More Than 128 Ki Bytes of Flash
 @cindex @code{EIND}
 Pointers in the implementation are 16@tie{}bits wide.
 The address of a function or label is represented as word address so
@@ -18291,6 +18310,28 @@ This option is typically used to link with a library provided by a HAL BSP.
 
 @end table
 
+@node Nvidia PTX Options
+@subsection Nvidia PTX Options
+@cindex Nvidia PTX options
+@cindex nvptx options
+
+These options are defined for Nvidia PTX:
+
+@table @gcctabopt
+
+@item -m32
+@itemx -m64
+@opindex m32
+@opindex m64
+Generate code for 32-bit or 64-bit ABI.
+
+@item -mmainkernel
+@opindex mmainkernel
+Link in code for a __main kernel.  This is for stand-alone instead of
+offloading execution.
+
+@end table
+
 @node PDP-11 Options
 @subsection PDP-11 Options
 @cindex PDP-11 Options
@@ -20584,6 +20625,13 @@ compiler prefers zero displacement branch code sequences.  This is
 enabled by default when generating code for SH4 and SH4A.  It can be explicitly
 disabled by specifying @option{-mno-zdcbranch}.
 
+@item -mcbranch-force-delay-slot
+@opindex mcbranch-force-delay-slot
+Force the usage of delay slots for conditional branches, which stuffs the delay
+slot with a @code{nop} if a suitable instruction can't be found.  By default
+this option is disabled.  It can be enabled to work around hardware bugs as
+found in the original SH7055.
+
 @item -mfused-madd
 @itemx -mno-fused-madd
 @opindex mfused-madd
index dba4916..5588f67 100644 (file)
@@ -5,7 +5,7 @@
 @node Objective-C
 @comment  node-name,  next,  previous,  up
 
-@chapter GNU Objective-C features
+@chapter GNU Objective-C Features
 
 This document is meant to describe some of the GNU Objective-C
 features.  It is not intended to teach you Objective-C.  There are
@@ -26,7 +26,7 @@ several resources on the Internet that present the language.
 
 @c =========================================================================
 @node GNU Objective-C runtime API
-@section GNU Objective-C runtime API
+@section GNU Objective-C Runtime API
 
 This section is specific for the GNU Objective-C runtime.  If you are
 using a different runtime, you can skip it.
@@ -50,7 +50,7 @@ to the GNU Objective-C runtime API to define new classes or methods.
 
 @c =========================================================================
 @node Modern GNU Objective-C runtime API
-@subsection Modern GNU Objective-C runtime API
+@subsection Modern GNU Objective-C Runtime API
 
 The GNU Objective-C runtime provides an API which is similar to the
 one provided by the ``Objective-C 2.0'' Apple/NeXT Objective-C
@@ -109,7 +109,7 @@ the GNU Objective-C runtime API.
 
 @c =========================================================================
 @node Traditional GNU Objective-C runtime API
-@subsection Traditional GNU Objective-C runtime API
+@subsection Traditional GNU Objective-C Runtime API
 
 The GNU Objective-C runtime used to provide a different API, which we
 call the ``traditional'' GNU Objective-C runtime API.  Functions
@@ -124,7 +124,7 @@ available.
 
 @c =========================================================================
 @node Executing code before main
-@section @code{+load}: Executing code before main
+@section @code{+load}: Executing Code before @code{main}
 
 This section is specific for the GNU Objective-C runtime.  If you are
 using a different runtime, you can skip it.
@@ -208,7 +208,7 @@ instead of @code{+initialize}.
 
 
 @node What you can and what you cannot do in +load
-@subsection What you can and what you cannot do in @code{+load}
+@subsection What You Can and Cannot Do in @code{+load}
 
 @code{+load} is to be used only as a last resort.  Because it is
 executed very early, most of the Objective-C runtime machinery will
@@ -279,7 +279,7 @@ above apply to classes defined in bundle.
 
 
 @node Type encoding
-@section Type encoding
+@section Type Encoding
 
 This is an advanced section.  Type encodings are used extensively by
 the compiler and by the runtime, but you generally do not need to know
@@ -487,7 +487,7 @@ as @code{*}, and the @code{const} is lost.
 @end menu
 
 @node Legacy type encoding
-@subsection Legacy type encoding
+@subsection Legacy Type Encoding
 
 Unfortunately, historically GCC used to have a number of bugs in its
 encoding code.  The NeXT runtime expects GCC to emit type encodings in
@@ -518,7 +518,7 @@ bitfields.  It encodes them as @code{b} followed by the size, without
 a bit offset or the underlying field type.
 
 @node @@encode
-@subsection @@encode
+@subsection @code{@@encode}
 
 GNU Objective-C supports the @code{@@encode} syntax that allows you to
 create a type encoding from a C/Objective-C type.  For example,
@@ -530,7 +530,7 @@ is compiled into @code{"r*"}, while @code{@@encode(bycopy char *)} is
 invalid and will cause a compilation error.
 
 @node Method signatures
-@subsection Method signatures
+@subsection Method Signatures
 
 This section documents the encoding of method types, which is rarely
 needed to use Objective-C.  You should skip it at a first reading; the
@@ -660,7 +660,7 @@ as argument.
 
 @c =========================================================================
 @node Constant string objects
-@section Constant string objects
+@section Constant String Objects
 
 GNU Objective-C provides constant string objects that are generated
 directly by the compiler.  You declare a constant string object by
@@ -721,7 +721,7 @@ restrictions in doing this.
 
 @c =========================================================================
 @node compatibility_alias
-@section compatibility_alias
+@section @code{compatibility_alias}
 
 The keyword @code{@@compatibility_alias} allows you to define a class name
 as equivalent to another class name.  For example:
@@ -858,7 +858,7 @@ exceptions enabled, that is with the command line option
 
 @c =========================================================================
 @node Fast enumeration
-@section Fast enumeration
+@section Fast Enumeration
 
 @menu
 * Using fast enumeration::
@@ -869,7 +869,7 @@ exceptions enabled, that is with the command line option
 
 @c ================================
 @node Using fast enumeration
-@subsection Using fast enumeration
+@subsection Using Fast Enumeration
 
 GNU Objective-C provides support for the fast enumeration syntax:
 
@@ -909,7 +909,7 @@ provides the implementation of @code{NSArray}, @code{NSString} and
 
 @c ================================
 @node c99-like fast enumeration syntax
-@subsection c99-like fast enumeration syntax
+@subsection C99-Like Fast Enumeration Syntax
 
 A c99-like declaration syntax is also allowed:
 
@@ -943,7 +943,7 @@ syntax in Objective-C.
 
 @c ================================
 @node Fast enumeration details
-@subsection Fast enumeration details
+@subsection Fast Enumeration Details
 
 Here is a more technical description with the gory details.  Consider the code
 
@@ -1006,7 +1006,7 @@ something different, such as raising an exception.
 
 @c ================================
 @node Fast enumeration protocol
-@subsection Fast enumeration protocol
+@subsection Fast Enumeration Protocol
 
 If you want your own collection object to be usable with fast
 enumeration, you need to have it implement the method
@@ -1076,7 +1076,7 @@ to be of type @code{unsigned int} and everything would still work.
 
 @c =========================================================================
 @node Messaging with the GNU Objective-C runtime
-@section Messaging with the GNU Objective-C runtime
+@section Messaging with the GNU Objective-C Runtime
 
 This section is specific for the GNU Objective-C runtime.  If you are
 using a different runtime, you can skip it.
@@ -1107,7 +1107,7 @@ then it calls it.
 
 @c =========================================================================
 @node Dynamically registering methods
-@subsection Dynamically registering methods
+@subsection Dynamically Registering Methods
 
 If @code{objc_msg_lookup()} does not find a suitable method
 implementation, because the receiver does not implement the required
@@ -1153,7 +1153,7 @@ GCC version 4.6.
 
 @c =========================================================================
 @node Forwarding hook
-@subsection Forwarding hook
+@subsection Forwarding Hook
 
 The GNU Objective-C runtime provides a hook, called
 @code{__objc_msg_forward2}, which is called by
index c791f59..f55e24c 100644 (file)
@@ -9,7 +9,7 @@ For each language compiled by GCC for which there is a standard, GCC
 attempts to follow one or more versions of that standard, possibly
 with some exceptions, and possibly with some extensions.
 
-@section C language
+@section C Language
 @cindex C standard
 @cindex C standards
 @cindex ANSI C standard
@@ -169,7 +169,7 @@ For references to Technical Corrigenda, Rationale documents and
 information concerning the history of C that is available online, see
 @uref{http://gcc.gnu.org/readings.html}
 
-@section C++ language
+@section C++ Language
 
 GCC supports the original ISO C++ standard (1998) and contains
 experimental support for the second ISO C++ standard (2011).
@@ -208,7 +208,7 @@ may also select an extended version of the C++ language explicitly with
 @option{-std=gnu++11} (for C++11 with GNU extensions).  The default, if
 no C++ language dialect options are given, is @option{-std=gnu++98}.
 
-@section Objective-C and Objective-C++ languages
+@section Objective-C and Objective-C++ Languages
 @cindex Objective-C
 @cindex Objective-C++
 
@@ -275,12 +275,12 @@ The authoritative manual on Objective-C 2.0 is available from Apple:
 For more information concerning the history of Objective-C that is
 available online, see @uref{http://gcc.gnu.org/readings.html}
 
-@section Go language
+@section Go Language
 
 As of the GCC 4.7.1 release, GCC supports the Go 1 language standard,
 described at @uref{http://golang.org/doc/go1.html}.
 
-@section References for other languages
+@section References for Other Languages
 
 @xref{Top, GNAT Reference Manual, About This Guide, gnat_rm,
 GNAT Reference Manual}, for information on standard
index f42a782..f2baff4 100644 (file)
@@ -676,7 +676,7 @@ symbols any static data members that lack definitions.
 
 
 @node Name lookup
-@subsection Name lookup, templates, and accessing members of base classes
+@subsection Name Lookup, Templates, and Accessing Members of Base Classes
 
 @cindex base class members
 @cindex two-stage name lookup
index 4492f8a..ebf41c8 100644 (file)
@@ -24527,8 +24527,13 @@ dwarf2out_finish (const char *filename)
   gen_remaining_tmpl_value_param_die_attribute ();
 
   /* Add the name for the main input file now.  We delayed this from
-     dwarf2out_init to avoid complications with PCH.  */
-  add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
+     dwarf2out_init to avoid complications with PCH.
+     For LTO produced units use a fixed artificial name to avoid
+     leaking tempfile names into the dwarf.  */
+  if (!in_lto_p)
+    add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
+  else
+    add_name_attribute (comp_unit_die (), "<artificial>");
   if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir)
     add_comp_dir_attribute (comp_unit_die ());
   else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
index 64c8c9c..ad2450b 100644 (file)
@@ -1233,6 +1233,11 @@ recompute_todo_spec (rtx_insn *next, bool for_backtrack)
   if (!sd_lists_empty_p (next, SD_LIST_HARD_BACK))
     return HARD_DEP;
 
+  /* If NEXT is intended to sit adjacent to this instruction, we don't
+     want to try to break any dependencies.  Treat it as a HARD_DEP.  */
+  if (SCHED_GROUP_P (next))
+    return HARD_DEP;
+
   /* Now we've got NEXT with speculative deps only.
      1. Look at the deps to see what we have to do.
      2. Check if we can do 'todo'.  */
@@ -2568,7 +2573,7 @@ model_set_excess_costs (rtx_insn **insns, int count)
 
 /* Enum of rank_for_schedule heuristic decisions.  */
 enum rfs_decision {
-  RFS_DEBUG, RFS_LIVE_RANGE_SHRINK1, RFS_LIVE_RANGE_SHRINK2,
+  RFS_LIVE_RANGE_SHRINK1, RFS_LIVE_RANGE_SHRINK2,
   RFS_SCHED_GROUP, RFS_PRESSURE_DELAY, RFS_PRESSURE_TICK,
   RFS_FEEDS_BACKTRACK_INSN, RFS_PRIORITY, RFS_SPECULATION,
   RFS_SCHED_RANK, RFS_LAST_INSN, RFS_PRESSURE_INDEX,
@@ -2576,7 +2581,7 @@ enum rfs_decision {
 
 /* Corresponding strings for print outs.  */
 static const char *rfs_str[RFS_N] = {
-  "RFS_DEBUG", "RFS_LIVE_RANGE_SHRINK1", "RFS_LIVE_RANGE_SHRINK2",
+  "RFS_LIVE_RANGE_SHRINK1", "RFS_LIVE_RANGE_SHRINK2",
   "RFS_SCHED_GROUP", "RFS_PRESSURE_DELAY", "RFS_PRESSURE_TICK",
   "RFS_FEEDS_BACKTRACK_INSN", "RFS_PRIORITY", "RFS_SPECULATION",
   "RFS_SCHED_RANK", "RFS_LAST_INSN", "RFS_PRESSURE_INDEX",
@@ -2612,12 +2617,11 @@ rank_for_schedule_debug (const void *x, const void *y)
 
   /* Schedule debug insns as early as possible.  */
   if (DEBUG_INSN_P (tmp) && !DEBUG_INSN_P (tmp2))
-    return rfs_result (RFS_DEBUG, -1, tmp, tmp2);
+    return -1;
   else if (!DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
-    return rfs_result (RFS_DEBUG, 1, tmp, tmp2);
+    return 1;
   else if (DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
-    return rfs_result (RFS_DEBUG, INSN_LUID (tmp) - INSN_LUID (tmp2),
-                      tmp, tmp2);
+    return INSN_LUID (tmp) - INSN_LUID (tmp2);
   else
     return INSN_RFS_DEBUG_ORIG_ORDER (tmp2) - INSN_RFS_DEBUG_ORIG_ORDER (tmp);
 }
@@ -3080,48 +3084,45 @@ print_rank_for_schedule_stats (const char *prefix,
       }
 }
 
-/* Sort the ready list READY by ascending priority, using the SCHED_SORT
-   macro.  */
-
-void
-ready_sort (struct ready_list *ready)
+/* Separate DEBUG_INSNS from normal insns.  DEBUG_INSNs go to the end
+   of array.  */
+static void
+ready_sort_debug (struct ready_list *ready)
 {
   int i;
   rtx_insn **first = ready_lastpos (ready);
-  int n_ready_non_debug = ready->n_ready;
 
   for (i = 0; i < ready->n_ready; ++i)
-    {
-      if (DEBUG_INSN_P (first[i]))
-       --n_ready_non_debug;
-      else
-       {
-         INSN_RFS_DEBUG_ORIG_ORDER (first[i]) = i;
+    if (!DEBUG_INSN_P (first[i]))
+      INSN_RFS_DEBUG_ORIG_ORDER (first[i]) = i;
 
-         if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
-           setup_insn_reg_pressure_info (first[i]);
-       }
-    }
+  qsort (first, ready->n_ready, sizeof (rtx), rank_for_schedule_debug);
+}
 
-  if (sched_pressure == SCHED_PRESSURE_MODEL
-      && model_curr_point < model_num_insns)
-    model_set_excess_costs (first, ready->n_ready);
+/* Sort non-debug insns in the ready list READY by ascending priority.
+   Assumes that all debug insns are separated from the real insns.  */
+static void
+ready_sort_real (struct ready_list *ready)
+{
+  int i;
+  rtx_insn **first = ready_lastpos (ready);
+  int n_ready_real = ready->n_ready - ready->n_debug;
+
+  if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
+    for (i = 0; i < n_ready_real; ++i)
+      setup_insn_reg_pressure_info (first[i]);
+  else if (sched_pressure == SCHED_PRESSURE_MODEL
+          && model_curr_point < model_num_insns)
+    model_set_excess_costs (first, n_ready_real);
 
   rank_for_schedule_stats_t stats1;
   if (sched_verbose >= 4)
     stats1 = rank_for_schedule_stats;
 
-  if (n_ready_non_debug < ready->n_ready)
-    /* Separate DEBUG_INSNS from normal insns.  DEBUG_INSNs go to the end
-       of array.  */
-    qsort (first, ready->n_ready, sizeof (rtx), rank_for_schedule_debug);
-  else
-    {
-      if (n_ready_non_debug == 2)
-       swap_sort (first, n_ready_non_debug);
-      else if (n_ready_non_debug > 2)
-       qsort (first, n_ready_non_debug, sizeof (rtx), rank_for_schedule);
-    }
+  if (n_ready_real == 2)
+    swap_sort (first, n_ready_real);
+  else if (n_ready_real > 2)
+    qsort (first, n_ready_real, sizeof (rtx), rank_for_schedule);
 
   if (sched_verbose >= 4)
     {
@@ -3130,6 +3131,16 @@ ready_sort (struct ready_list *ready)
     }
 }
 
+/* Sort the ready list READY by ascending priority.  */
+static void
+ready_sort (struct ready_list *ready)
+{
+  if (ready->n_debug > 0)
+    ready_sort_debug (ready);
+  else
+    ready_sort_real (ready);
+}
+
 /* PREV is an insn that is ready to execute.  Adjust its priority if that
    will help shorten or lengthen register lifetimes as appropriate.  Also
    provide a hook for the target to tweak itself.  */
@@ -6490,7 +6501,8 @@ schedule_block (basic_block *target_bb, state_t init_state)
   if (!reload_completed
       && ready.n_ready - ready.n_debug > MAX_SCHED_READY_INSNS)
     {
-      ready_sort (&ready);
+      ready_sort_debug (&ready);
+      ready_sort_real (&ready);
 
       /* Find first free-standing insn past MAX_SCHED_READY_INSNS.
          If there are debug insns, we know they're first.  */
@@ -6501,7 +6513,8 @@ schedule_block (basic_block *target_bb, state_t init_state)
       if (sched_verbose >= 2)
        {
          fprintf (sched_dump,
-                  ";;\t\tReady list on entry: %d insns\n", ready.n_ready);
+                  ";;\t\tReady list on entry: %d insns:  ", ready.n_ready);
+         debug_ready_list (&ready);
          fprintf (sched_dump,
                   ";;\t\t before reload => truncated to %d insns\n", i);
        }
index 67cb7d5..0b857ff 100644 (file)
@@ -534,14 +534,13 @@ chkp_maybe_create_clone (tree fndecl)
        symtab->call_cgraph_insertion_hooks (clone);
 
       /* Clone all aliases.  */
-      for (i = 0; node->iterate_referring (i, ref); i++)
-       if (ref->use == IPA_REF_ALIAS)
-         {
-           struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
-           struct cgraph_node *chkp_alias
-             = chkp_maybe_create_clone (alias->decl);
-           chkp_alias->create_reference (clone, IPA_REF_ALIAS, NULL);
-         }
+      for (i = 0; node->iterate_direct_aliases (i, ref); i++)
+       {
+         struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+         struct cgraph_node *chkp_alias
+           = chkp_maybe_create_clone (alias->decl);
+         chkp_alias->create_reference (clone, IPA_REF_ALIAS, NULL);
+       }
 
       /* Clone all thunks.  */
       for (e = node->callers; e; e = e->next_caller)
index ad5945f..9f43f29 100644 (file)
@@ -328,9 +328,14 @@ ipa_comdats (void)
 
   FOR_EACH_DEFINED_SYMBOL (symbol)
     {
+      struct cgraph_node *fun;
       symbol->aux = NULL; 
       if (!symbol->get_comdat_group ()
          && !symbol->alias
+         /* Thunks to external functions do not need to be categorized.  */
+         && (!(fun = dyn_cast <cgraph_node *> (symbol))
+             || !fun->thunk.thunk_p
+             || fun->function_symbol ()->definition)
          && symbol->real_symbol_p ())
        {
          tree *val = map.get (symbol);
index 440ced4..bfe4d97 100644 (file)
@@ -1438,8 +1438,7 @@ propagate_alignment_accross_jump_function (struct cgraph_edge *cs,
          if (op != NOP_EXPR)
            {
              if (op != POINTER_PLUS_EXPR
-                 && op != PLUS_EXPR
-                 && op != MINUS_EXPR)
+                 && op != PLUS_EXPR)
                goto prop_fail;
              tree operand = ipa_get_jf_pass_through_operand (jfunc);
              if (!tree_fits_shwi_p (operand))
@@ -1451,7 +1450,7 @@ propagate_alignment_accross_jump_function (struct cgraph_edge *cs,
       else
        {
          src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
-         offset = ipa_get_jf_ancestor_offset (jfunc);
+         offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;;
        }
 
       src_lats = ipa_get_parm_lattices (caller_info, src_idx);
@@ -4323,6 +4322,15 @@ ipcp_store_alignment_results (void)
     bool dumped_sth = false;
     bool found_useful_result = false;
 
+    if (!opt_for_fn (node->decl, flag_ipa_cp_alignment))
+      {
+       if (dump_file)
+         fprintf (dump_file, "Not considering %s for alignment discovery "
+                  "and propagate; -fipa-cp-alignment: disabled.\n",
+                  node->name ());
+       continue;
+      }
+
    if (info->ipcp_orig_node)
       info = IPA_NODE_REF (info->ipcp_orig_node);
 
index fe4f41b..c3f8b15 100644 (file)
@@ -551,7 +551,8 @@ set_type_binfo (tree type, tree binfo)
 /* Compare T2 and T2 based on name or structure.  */
 
 static bool
-odr_subtypes_equivalent_p (tree t1, tree t2, hash_set<type_pair,pair_traits> *visited)
+odr_subtypes_equivalent_p (tree t1, tree t2,
+                          hash_set<type_pair,pair_traits> *visited)
 {
   bool an1, an2;
 
@@ -618,7 +619,8 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
          prevailing = vtable;
          vtable = tmp;
        }
-      if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (vtable->decl))),
+      if (warning_at (DECL_SOURCE_LOCATION
+                       (TYPE_NAME (DECL_CONTEXT (vtable->decl))),
                      OPT_Wodr,
                      "virtual table of type %qD violates one definition rule",
                      DECL_CONTEXT (vtable->decl)))
@@ -633,39 +635,118 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
     {
       struct ipa_ref *ref1, *ref2;
       bool end1, end2;
+
       end1 = !prevailing->iterate_reference (n1, ref1);
       end2 = !vtable->iterate_reference (n2, ref2);
-      if (end1 && end2)
-       return;
-      if (!end1 && !end2
-         && DECL_ASSEMBLER_NAME (ref1->referred->decl)
-            != DECL_ASSEMBLER_NAME (ref2->referred->decl)
-         && !n2
-         && !DECL_VIRTUAL_P (ref2->referred->decl)
-         && DECL_VIRTUAL_P (ref1->referred->decl))
+
+      /* !DECL_VIRTUAL_P means RTTI entry;
+        We warn when RTTI is lost because non-RTTI previals; we silently
+        accept the other case.  */
+      while (!end2
+            && (end1
+                || (DECL_ASSEMBLER_NAME (ref1->referred->decl)
+                    != DECL_ASSEMBLER_NAME (ref2->referred->decl)
+                    && DECL_VIRTUAL_P (ref1->referred->decl)))
+            && !DECL_VIRTUAL_P (ref2->referred->decl))
        {
-         if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 0,
+         if (warning_at (DECL_SOURCE_LOCATION
+                           (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 0,
                          "virtual table of type %qD contains RTTI information",
                          DECL_CONTEXT (vtable->decl)))
            {
-             inform (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
-                     "but is prevailed by one without from other translation unit");
-             inform (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
+             inform (DECL_SOURCE_LOCATION
+                       (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
+                     "but is prevailed by one without from other translation "
+                     "unit");
+             inform (DECL_SOURCE_LOCATION
+                       (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
                      "RTTI will not work on this type");
            }
          n2++;
           end2 = !vtable->iterate_reference (n2, ref2);
        }
-      if (!end1 && !end2
-         && DECL_ASSEMBLER_NAME (ref1->referred->decl)
-            != DECL_ASSEMBLER_NAME (ref2->referred->decl)
-         && !n1
-         && !DECL_VIRTUAL_P (ref1->referred->decl)
-         && DECL_VIRTUAL_P (ref2->referred->decl))
+      while (!end1
+            && (end2
+                || (DECL_ASSEMBLER_NAME (ref2->referred->decl)
+                    != DECL_ASSEMBLER_NAME (ref1->referred->decl)
+                    && DECL_VIRTUAL_P (ref2->referred->decl)))
+            && !DECL_VIRTUAL_P (ref1->referred->decl))
        {
          n1++;
           end1 = !vtable->iterate_reference (n1, ref1);
        }
+
+      /* Finished?  */
+      if (end1 && end2)
+       {
+         /* Extra paranoia; compare the sizes.  We do not have information
+            about virtual inheritance offsets, so just be sure that these
+            match.  
+            Do this as very last check so the not very informative error
+            is not output too often.  */
+         if (DECL_SIZE (prevailing->decl) != DECL_SIZE (vtable->decl))
+           {
+             if (warning_at (DECL_SOURCE_LOCATION
+                               (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 0,
+                             "virtual table of type %qD violates "
+                             "one definition rule  ",
+                             DECL_CONTEXT (vtable->decl)))
+               {
+                 inform (DECL_SOURCE_LOCATION 
+                           (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
+                         "the conflicting type defined in another translation "
+                         "unit has virtual table of different size");
+               }
+           }
+         return;
+       }
+
+      if (!end1 && !end2)
+       {
+         if (DECL_ASSEMBLER_NAME (ref1->referred->decl)
+             == DECL_ASSEMBLER_NAME (ref2->referred->decl))
+           continue;
+
+         /* If the loops above stopped on non-virtual pointer, we have
+            mismatch in RTTI information mangling.  */
+         if (!DECL_VIRTUAL_P (ref1->referred->decl)
+             && !DECL_VIRTUAL_P (ref2->referred->decl))
+           {
+             if (warning_at (DECL_SOURCE_LOCATION
+                               (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 0,
+                             "virtual table of type %qD violates "
+                             "one definition rule  ",
+                             DECL_CONTEXT (vtable->decl)))
+               {
+                 inform (DECL_SOURCE_LOCATION 
+                           (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
+                         "the conflicting type defined in another translation "
+                         "unit virtual table with different RTTI information");
+               }
+             return;
+           }
+         /* At this point both REF1 and REF2 points either to virtual table
+            or virtual method.  If one points to virtual table and other to
+            method we can complain the same way as if one table was shorter
+            than other pointing out the extra method.  */
+         gcc_assert (DECL_VIRTUAL_P (ref1->referred->decl)
+                     && (TREE_CODE (ref1->referred->decl) == FUNCTION_DECL
+                         || TREE_CODE (ref1->referred->decl) == VAR_DECL));
+         gcc_assert (DECL_VIRTUAL_P (ref2->referred->decl)
+                     && (TREE_CODE (ref2->referred->decl) == FUNCTION_DECL
+                         || TREE_CODE (ref2->referred->decl) == VAR_DECL));
+         if (TREE_CODE (ref1->referred->decl)
+             != TREE_CODE (ref2->referred->decl))
+           {
+             if (TREE_CODE (ref1->referred->decl) == VAR_DECL)
+               end1 = true;
+             else if (TREE_CODE (ref2->referred->decl) == VAR_DECL)
+               end2 = true;
+           }
+       }
+
+      /* Complain about size mismatch.  Either we have too many virutal
+        functions or too many virtual table pointers.  */
       if (end1 || end2)
        {
          if (end1)
@@ -681,37 +762,56 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
                          "one definition rule",
                          DECL_CONTEXT (vtable->decl)))
            {
-             inform (DECL_SOURCE_LOCATION
-                      (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
-                     "the conflicting type defined in another translation "
-                     "unit");
-             inform (DECL_SOURCE_LOCATION
-                       (TYPE_NAME (DECL_CONTEXT (ref1->referring->decl))),
-                     "contains additional virtual method %qD",
-                     ref1->referred->decl);
+             if (TREE_CODE (ref1->referring->decl) == FUNCTION_DECL)
+               {
+                 inform (DECL_SOURCE_LOCATION
+                          (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
+                         "the conflicting type defined in another translation "
+                         "unit");
+                 inform (DECL_SOURCE_LOCATION
+                           (TYPE_NAME (DECL_CONTEXT (ref1->referring->decl))),
+                         "contains additional virtual method %qD",
+                         ref1->referred->decl);
+               }
+             else
+               {
+                 inform (DECL_SOURCE_LOCATION
+                          (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
+                         "the conflicting type defined in another translation "
+                         "unit has virtual table table with more entries");
+               }
            }
          return;
        }
-      if (DECL_ASSEMBLER_NAME (ref1->referred->decl)
-         != DECL_ASSEMBLER_NAME (ref2->referred->decl))
+
+      /* And in the last case we have either mistmatch in between two virtual
+        methods or two virtual table pointers.  */
+      if (warning_at (DECL_SOURCE_LOCATION
+                       (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 0,
+                     "virtual table of type %qD violates "
+                     "one definition rule  ",
+                     DECL_CONTEXT (vtable->decl)))
        {
-         if (warning_at (DECL_SOURCE_LOCATION
-                           (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 0,
-                         "virtual table of type %qD violates "
-                         "one definition rule  ",
-                         DECL_CONTEXT (vtable->decl)))
+         if (TREE_CODE (ref1->referred->decl) == FUNCTION_DECL)
            {
              inform (DECL_SOURCE_LOCATION 
                        (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
                      "the conflicting type defined in another translation "
                      "unit");
+             gcc_assert (TREE_CODE (ref2->referred->decl)
+                         == FUNCTION_DECL);
              inform (DECL_SOURCE_LOCATION (ref1->referred->decl),
                      "virtual method %qD", ref1->referred->decl);
              inform (DECL_SOURCE_LOCATION (ref2->referred->decl),
                      "ought to match virtual method %qD but does not",
                      ref2->referred->decl);
-             return;
            }
+         else
+           inform (DECL_SOURCE_LOCATION 
+                     (TYPE_NAME (DECL_CONTEXT (prevailing->decl))),
+                   "the conflicting type defined in another translation "
+                   "unit has virtual table table with different contents");
+         return;
        }
     }
 }
@@ -727,6 +827,8 @@ warn_odr (tree t1, tree t2, tree st1, tree st2,
          bool warn, bool *warned, const char *reason)
 {
   tree decl2 = TYPE_NAME (t2);
+  if (warned)
+    *warned = false;
 
   if (!warn)
     return;
@@ -840,7 +942,8 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
       return false;
     }
 
-  if (TREE_CODE (t1) == ENUMERAL_TYPE)
+  if (TREE_CODE (t1) == ENUMERAL_TYPE
+      && TYPE_VALUES (t1) && TYPE_VALUES (t2))
     {
       tree v1, v2;
       for (v1 = TYPE_VALUES (t1), v2 = TYPE_VALUES (t2);
@@ -1056,8 +1159,20 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
                  f2 = TREE_CHAIN (f2);
                if (!f1 || !f2)
                  break;
+               if (DECL_VIRTUAL_P (f1) != DECL_VIRTUAL_P (f2))
+                 {
+                   warn_odr (t1, t2, NULL, NULL, warn, warned,
+                             G_("a type with different virtual table pointers"
+                                " is defined in another translation unit"));
+                   return false;
+                 }
                if (DECL_ARTIFICIAL (f1) != DECL_ARTIFICIAL (f2))
-                 break;
+                 {
+                   warn_odr (t1, t2, NULL, NULL, warn, warned,
+                             G_("a type with different bases is defined "
+                                "in another translation unit"));
+                   return false;
+                 }
                if (DECL_NAME (f1) != DECL_NAME (f2)
                    && !DECL_ARTIFICIAL (f1))
                  {
@@ -1066,10 +1181,11 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
                                 "in another translation unit"));
                    return false;
                  }
-               if (!odr_subtypes_equivalent_p (TREE_TYPE (f1), TREE_TYPE (f2), visited))
+               if (!odr_subtypes_equivalent_p (TREE_TYPE (f1),
+                                               TREE_TYPE (f2), visited))
                  {
-                   /* Do not warn about artificial fields and just go into generic
-                      field mismatch warning.  */
+                   /* Do not warn about artificial fields and just go into
+                      generic field mismatch warning.  */
                    if (DECL_ARTIFICIAL (f1))
                      break;
 
@@ -1082,11 +1198,11 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
                  }
                if (!gimple_compare_field_offset (f1, f2))
                  {
-                   /* Do not warn about artificial fields and just go into generic
-                      field mismatch warning.  */
+                   /* Do not warn about artificial fields and just go into
+                      generic field mismatch warning.  */
                    if (DECL_ARTIFICIAL (f1))
                      break;
-                   warn_odr (t1, t2, t1, t2, warn, warned,
+                   warn_odr (t1, t2, f1, f2, warn, warned,
                              G_("fields has different layout "
                                 "in another translation unit"));
                    return false;
@@ -1099,18 +1215,18 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
               are not the same.  */
            if (f1 || f2)
              {
-               if (f1 && DECL_ARTIFICIAL (f1))
-                 f1 = NULL;
-               if (f2 && DECL_ARTIFICIAL (f2))
-                 f2 = NULL;
-               if (f1 || f2)
-                 warn_odr (t1, t2, f1, f2, warn, warned,
-                           G_("a type with different number of fields "
-                              "is defined in another translation unit"));
-               /* Ideally we should never get this generic message.  */
+               if ((f1 && DECL_VIRTUAL_P (f1)) || (f2 && DECL_VIRTUAL_P (f2)))
+                 warn_odr (t1, t2, NULL, NULL, warn, warned,
+                           G_("a type with different virtual table pointers"
+                              " is defined in another translation unit"));
+               if ((f1 && DECL_ARTIFICIAL (f1))
+                   || (f2 && DECL_ARTIFICIAL (f2)))
+                 warn_odr (t1, t2, NULL, NULL, warn, warned,
+                           G_("a type with different bases is defined "
+                              "in another translation unit"));
                else
                  warn_odr (t1, t2, f1, f2, warn, warned,
-                           G_("a type with different memory representation "
+                           G_("a type with different number of fields "
                               "is defined in another translation unit"));
                
                return false;
@@ -1207,12 +1323,24 @@ add_type_duplicate (odr_type val, tree type)
     val->types_set = new hash_set<tree>;
 
   /* Always prefer complete type to be the leader.  */
-  if ((!COMPLETE_TYPE_P (val->type) || !TYPE_BINFO (val->type))
-      && (COMPLETE_TYPE_P (type) && TYPE_BINFO (val->type)))
+
+  if (!COMPLETE_TYPE_P (val->type) && COMPLETE_TYPE_P (type))
+    build_bases = true;
+  else if (COMPLETE_TYPE_P (val->type) && !COMPLETE_TYPE_P (type))
+    ;
+  else if (TREE_CODE (val->type) == ENUMERAL_TYPE
+          && TREE_CODE (type) == ENUMERAL_TYPE
+          && !TYPE_VALUES (val->type) && TYPE_VALUES (type))
+    build_bases = true;
+  else if (TREE_CODE (val->type) == RECORD_TYPE
+          && TREE_CODE (type) == RECORD_TYPE
+          && TYPE_BINFO (type) && !TYPE_BINFO (val->type))
+    build_bases = true;
+
+  if (build_bases)
     {
       tree tmp = type;
 
-      build_bases = true;
       type = val->type;
       val->type = tmp;
     }
@@ -1303,11 +1431,14 @@ add_type_duplicate (odr_type val, tree type)
                if (base_mismatch)
                  {
                    if (!warned && !val->odr_violated)
-                     warn_odr (type, val->type, NULL, NULL,
-                               !warned, &warned,
-                               "a type with the same name but different base "
-                               "type is defined in another translation unit");
-                   warn_types_mismatch (type1, type2);
+                     {
+                       warn_odr (type, val->type, NULL, NULL,
+                                 !warned, &warned,
+                                 "a type with the same name but different base "
+                                 "type is defined in another translation unit");
+                       if (warned)
+                         warn_types_mismatch (type1, type2);
+                     }
                    break;
                  }
                if (BINFO_OFFSET (base1) != BINFO_OFFSET (base2))
@@ -1320,6 +1451,18 @@ add_type_duplicate (odr_type val, tree type)
                                "layout is defined in another translation unit");
                    break;
                  }
+               /* One base is polymorphic and the other not.
+                  This ought to be diagnosed earlier, but do not ICE in the
+                  checking bellow.  */
+               if (!TYPE_BINFO (type1) != !TYPE_BINFO (type2)
+                   || (TYPE_BINFO (type1)
+                       && polymorphic_type_binfo_p (TYPE_BINFO (type1))
+                          != polymorphic_type_binfo_p (TYPE_BINFO (type2))))
+                 {
+                   gcc_assert (val->odr_violated);
+                   base_mismatch = true;
+                   break;
+                 }
              }
 #ifdef ENABLE_CHECKING
          /* Sanity check that all bases will be build same way again.  */
@@ -1468,6 +1611,7 @@ get_odr_type (tree type, bool insert)
       val->anonymous_namespace = type_in_anonymous_namespace_p (type);
       build_bases = COMPLETE_TYPE_P (val->type);
       insert_to_odr_array = true;
+      *slot = val;
     }
 
   if (build_bases && TREE_CODE (type) == RECORD_TYPE && TYPE_BINFO (type)
@@ -1479,7 +1623,6 @@ get_odr_type (tree type, bool insert)
       gcc_assert (BINFO_TYPE (TYPE_BINFO (val->type)) = type);
   
       val->all_derivations_known = type_all_derivations_known_p (type);
-      *slot = val;
       for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++)
        /* For now record only polymorphic types. other are
           pointless for devirtualization and we can not precisely
@@ -1557,6 +1700,10 @@ dump_odr_type (FILE *f, odr_type t, int indent=0)
       fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "",
               DECL_SOURCE_FILE (TYPE_NAME (t->type)),
               DECL_SOURCE_LINE (TYPE_NAME (t->type)));
+      if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t->type)))
+        fprintf (f, "%*s mangled name: %s\n", indent * 2, "",
+                IDENTIFIER_POINTER
+                  (DECL_ASSEMBLER_NAME (TYPE_NAME (t->type))));
     }
   if (t->bases.length ())
     {
@@ -1710,7 +1857,6 @@ referenced_from_vtable_p (struct cgraph_node *node)
     return true;
 
   for (i = 0; node->iterate_referring (i, ref); i++)
-       
     if ((ref->use == IPA_REF_ALIAS
         && referenced_from_vtable_p (dyn_cast<cgraph_node *> (ref->referring)))
        || (ref->use == IPA_REF_ADDR
index 692946a..494fdcf 100644 (file)
@@ -563,10 +563,10 @@ sem_function::equals_private (sem_item *item,
          if (e1->flags != e2->flags)
            return return_false_with_msg ("flags comparison returns false");
 
-         if (!bb_dict_test (bb_dict, e1->src->index, e2->src->index))
+         if (!bb_dict_test (&bb_dict, e1->src->index, e2->src->index))
            return return_false_with_msg ("edge comparison returns false");
 
-         if (!bb_dict_test (bb_dict, e1->dest->index, e2->dest->index))
+         if (!bb_dict_test (&bb_dict, e1->dest->index, e2->dest->index))
            return return_false_with_msg ("BB comparison returns false");
 
          if (!m_checker->compare_edge (e1, e2))
@@ -1053,21 +1053,21 @@ sem_function::icf_handled_component_p (tree t)
    corresponds to TARGET.  */
 
 bool
-sem_function::bb_dict_test (auto_vec<int> bb_dict, int source, int target)
+sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
 {
   source++;
   target++;
 
-  if (bb_dict.length () <= (unsigned)source)
-    bb_dict.safe_grow_cleared (source + 1);
+  if (bb_dict->length () <= (unsigned)source)
+    bb_dict->safe_grow_cleared (source + 1);
 
-  if (bb_dict[source] == 0)
+  if ((*bb_dict)[source] == 0)
     {
-      bb_dict[source] = target;
+      (*bb_dict)[source] = target;
       return true;
     }
   else
-    return bb_dict[source] == target;
+    return (*bb_dict)[source] == target;
 }
 
 /* Iterates all tree types in T1 and T2 and returns true if all types
index adbedd6..a55699b 100644 (file)
@@ -275,7 +275,7 @@ private:
 
   /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
      corresponds to TARGET.  */
-  bool bb_dict_test (auto_vec<int> bb_dict, int source, int target);
+  bool bb_dict_test (vec<int> *bb_dict, int source, int target);
 
   /* Iterates all tree types in T1 and T2 and returns true if all types
      are compatible. If COMPARE_POLYMORPHIC is set to true,
index a628a9e..ea03f10 100644 (file)
@@ -3901,6 +3901,7 @@ struct growth_data
 {
   struct cgraph_node *node;
   bool self_recursive;
+  bool uninlinable;
   int growth;
 };
 
@@ -3917,6 +3918,12 @@ do_estimate_growth_1 (struct cgraph_node *node, void *data)
     {
       gcc_checking_assert (e->inline_failed);
 
+      if (cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
+       {
+         d->uninlinable = true;
+          continue;
+       }
+
       if (e->caller == d->node
          || (e->caller->global.inlined_to
              && e->caller->global.inlined_to == d->node))
@@ -3932,10 +3939,10 @@ do_estimate_growth_1 (struct cgraph_node *node, void *data)
 int
 estimate_growth (struct cgraph_node *node)
 {
-  struct growth_data d = { node, 0, false };
+  struct growth_data d = { node, false, false, 0 };
   struct inline_summary *info = inline_summaries->get (node);
 
-  node->call_for_symbol_thunks_and_aliases (do_estimate_growth_1, &d, true);
+  node->call_for_symbol_and_aliases (do_estimate_growth_1, &d, true);
 
   /* For self recursive functions the growth estimation really should be
      infinity.  We don't want to return very large values because the growth
@@ -3943,7 +3950,7 @@ estimate_growth (struct cgraph_node *node)
      return zero or negative growths. */
   if (d.self_recursive)
     d.growth = d.growth < info->size ? info->size : d.growth;
-  else if (DECL_EXTERNAL (node->decl))
+  else if (DECL_EXTERNAL (node->decl) || d.uninlinable)
     ;
   else
     {
@@ -3962,6 +3969,28 @@ estimate_growth (struct cgraph_node *node)
   return d.growth;
 }
 
+/* Verify if there are fewer than MAX_CALLERS.  */
+
+static bool
+check_callers (cgraph_node *node, int *max_callers)
+{
+  ipa_ref *ref;
+
+  for (cgraph_edge *e = node->callers; e; e = e->next_caller)
+    {
+      (*max_callers)--;
+      if (!*max_callers
+         || cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
+       return true;
+    }
+
+  FOR_EACH_ALIAS (node, ref)
+    if (check_callers (dyn_cast <cgraph_node *> (ref->referring), max_callers))
+      return true;
+
+  return false;
+}
+
 
 /* Make cheap estimation if growth of NODE is likely positive knowing
    EDGE_GROWTH of one particular edge. 
@@ -3969,7 +3998,8 @@ estimate_growth (struct cgraph_node *node)
    and skip computation if there are too many callers.  */
 
 bool
-growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUSED)
+growth_likely_positive (struct cgraph_node *node,
+                       int edge_growth)
 {
   int max_callers;
   struct cgraph_edge *e;
@@ -4000,9 +4030,16 @@ growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUS
   for (e = node->callers; e; e = e->next_caller)
     {
       max_callers--;
-      if (!max_callers)
+      if (!max_callers
+         || cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
        return true;
     }
+
+  ipa_ref *ref;
+  FOR_EACH_ALIAS (node, ref)
+    if (check_callers (dyn_cast <cgraph_node *> (ref->referring), &max_callers))
+      return true;
+
   return estimate_growth (node) > 0;
 }
 
index 235219d..52493cc 100644 (file)
@@ -261,6 +261,22 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
     }
 }
 
+/* Mark all call graph edges coming out of NODE and all nodes that have been
+   inlined to it as in_polymorphic_cdtor.  */
+
+static void
+mark_all_inlined_calls_cdtor (cgraph_node *node)
+{
+  for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
+    {
+      cs->in_polymorphic_cdtor = true;
+      if (!cs->inline_failed)
+    mark_all_inlined_calls_cdtor (cs->callee);
+    }
+  for (cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
+    cs->in_polymorphic_cdtor = true;
+}
+
 
 /* Mark edge E as inlined and update callgraph accordingly.  UPDATE_ORIGINAL
    specify whether profile of original function should be updated.  If any new
@@ -332,6 +348,8 @@ inline_call (struct cgraph_edge *e, bool update_original,
 
   old_size = inline_summaries->get (to)->size;
   inline_merge_summary (e);
+  if (e->in_polymorphic_cdtor)
+    mark_all_inlined_calls_cdtor (e->callee);
   if (opt_for_fn (e->caller->decl, optimize))
     new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
   if (update_overall_summary)
index 287a6dd..025f7fc 100644 (file)
@@ -975,14 +975,14 @@ want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold)
   if (node->global.inlined_to)
     return false;
   /* Does it have callers?  */
-  if (!node->call_for_symbol_thunks_and_aliases (has_caller_p, NULL, true))
+  if (!node->call_for_symbol_and_aliases (has_caller_p, NULL, true))
     return false;
   /* Inlining into all callers would increase size?  */
   if (estimate_growth (node) > 0)
     return false;
   /* All inlines must be possible.  */
-  if (node->call_for_symbol_thunks_and_aliases (check_callers, &has_hot_call,
-                                               true))
+  if (node->call_for_symbol_and_aliases (check_callers, &has_hot_call,
+                                        true))
     return false;
   if (!cold && !has_hot_call)
     return false;
@@ -2359,9 +2359,9 @@ ipa_inline (void)
          if (want_inline_function_to_all_callers_p (node, cold))
            {
              int num_calls = 0;
-             node->call_for_symbol_thunks_and_aliases (sum_callers, &num_calls,
-                                                     true);
-             while (node->call_for_symbol_thunks_and_aliases
+             node->call_for_symbol_and_aliases (sum_callers, &num_calls,
+                                                true);
+             while (node->call_for_symbol_and_aliases
                       (inline_to_all_callers, &num_calls, true))
                ;
              remove_functions = true;
index f82f7db..0929877 100644 (file)
@@ -322,6 +322,7 @@ ipa_profile_read_summary (void)
 
 struct ipa_propagate_frequency_data
 {
+  cgraph_node *function_symbol;
   bool maybe_unlikely_executed;
   bool maybe_executed_once;
   bool only_called_at_startup;
@@ -342,7 +343,7 @@ ipa_propagate_frequency_1 (struct cgraph_node *node, void *data)
                || d->only_called_at_startup || d->only_called_at_exit);
        edge = edge->next_caller)
     {
-      if (edge->caller != node)
+      if (edge->caller != d->function_symbol)
        {
           d->only_called_at_startup &= edge->caller->only_called_at_startup;
          /* It makes sense to put main() together with the static constructors.
@@ -358,7 +359,11 @@ ipa_propagate_frequency_1 (struct cgraph_node *node, void *data)
         errors can make us to push function into unlikely section even when
         it is executed by the train run.  Transfer the function only if all
         callers are unlikely executed.  */
-      if (profile_info && flag_branch_probabilities
+      if (profile_info
+         && opt_for_fn (d->function_symbol->decl, flag_branch_probabilities)
+         /* Thunks are not profiled.  This is more or less implementation
+            bug.  */
+         && !d->function_symbol->thunk.thunk_p
          && (edge->caller->frequency != NODE_FREQUENCY_UNLIKELY_EXECUTED
              || (edge->caller->global.inlined_to
                  && edge->caller->global.inlined_to->frequency
@@ -418,7 +423,7 @@ contains_hot_call_p (struct cgraph_node *node)
 bool
 ipa_propagate_frequency (struct cgraph_node *node)
 {
-  struct ipa_propagate_frequency_data d = {true, true, true, true};
+  struct ipa_propagate_frequency_data d = {node, true, true, true, true};
   bool changed = false;
 
   /* We can not propagate anything useful about externally visible functions
@@ -432,8 +437,8 @@ ipa_propagate_frequency (struct cgraph_node *node)
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "Processing frequency %s\n", node->name ());
 
-  node->call_for_symbol_thunks_and_aliases (ipa_propagate_frequency_1, &d,
-                                           true);
+  node->call_for_symbol_and_aliases (ipa_propagate_frequency_1, &d,
+                                    true);
 
   if ((d.only_called_at_startup && !d.only_called_at_exit)
       && !node->only_called_at_startup)
@@ -597,6 +602,9 @@ ipa_profile (void)
     {
       bool update = false;
 
+      if (!opt_for_fn (n->decl, flag_ipa_profile))
+       continue;
+
       for (e = n->indirect_calls; e; e = e->next_callee)
        {
          if (n->count)
@@ -697,7 +705,9 @@ ipa_profile (void)
   order_pos = ipa_reverse_postorder (order);
   for (i = order_pos - 1; i >= 0; i--)
     {
-      if (order[i]->local.local && ipa_propagate_frequency (order[i]))
+      if (order[i]->local.local
+         && opt_for_fn (order[i]->decl, flag_ipa_profile)
+         && ipa_propagate_frequency (order[i]))
        {
          for (e = order[i]->callees; e; e = e->next_callee)
            if (e->callee->local.local && !e->callee->aux)
@@ -714,7 +724,9 @@ ipa_profile (void)
       something_changed = false;
       for (i = order_pos - 1; i >= 0; i--)
        {
-         if (order[i]->aux && ipa_propagate_frequency (order[i]))
+         if (order[i]->aux
+             && opt_for_fn (order[i]->decl, flag_ipa_profile)
+             && ipa_propagate_frequency (order[i]))
            {
              for (e = order[i]->callees; e; e = e->next_callee)
                if (e->callee->local.local && !e->callee->aux)
index 878e94f..908b5ee 100644 (file)
@@ -3143,25 +3143,31 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
       if (jfunc->type == IPA_JF_PASS_THROUGH
           && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
        {
-         if ((ici->agg_contents
-              && !ipa_get_jf_pass_through_agg_preserved (jfunc))
-             || (ici->polymorphic
-                 && !ipa_get_jf_pass_through_type_preserved (jfunc)))
+         if (ici->agg_contents
+             && !ipa_get_jf_pass_through_agg_preserved (jfunc)
+             && !ici->polymorphic)
            ici->param_index = -1;
          else
-           ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
+           {
+             ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
+             if (ici->polymorphic
+                 && !ipa_get_jf_pass_through_type_preserved (jfunc))
+               ici->vptr_changed = true;
+           }
        }
       else if (jfunc->type == IPA_JF_ANCESTOR)
        {
-         if ((ici->agg_contents
-              && !ipa_get_jf_ancestor_agg_preserved (jfunc))
-             || (ici->polymorphic
-                 && !ipa_get_jf_ancestor_type_preserved (jfunc)))
+         if (ici->agg_contents
+             && !ipa_get_jf_ancestor_agg_preserved (jfunc)
+             && !ici->polymorphic)
            ici->param_index = -1;
          else
            {
              ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
              ici->offset += ipa_get_jf_ancestor_offset (jfunc);
+             if (ici->polymorphic
+                 && !ipa_get_jf_ancestor_type_preserved (jfunc))
+               ici->vptr_changed = true;
            }
        }
       else
index c33ee46..9247e29 100644 (file)
@@ -595,7 +595,8 @@ function_and_variable_visibility (bool whole_program)
     }
   FOR_EACH_DEFINED_FUNCTION (node)
     {
-      node->local.local |= node->local_p ();
+      if (!node->local.local)
+        node->local.local |= node->local_p ();
 
       /* If we know that function can not be overwritten by a different semantics
         and moreover its section can not be discarded, replace all direct calls
index 58ba309..b3752de 100644 (file)
@@ -661,7 +661,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
     if (node->address_taken
        && !node->used_from_other_partition)
       {
-       if (!node->call_for_symbol_thunks_and_aliases
+       if (!node->call_for_symbol_and_aliases
            (has_addr_references_p, NULL, true)
            && (!node->instrumentation_clone
                || !node->instrumented_version
@@ -808,8 +808,8 @@ ipa_discover_readonly_nonaddressable_vars (void)
          {
            if (TREE_ADDRESSABLE (vnode->decl) && dump_file)
              fprintf (dump_file, " %s (non-addressable)", vnode->name ());
-           vnode->call_for_node_and_aliases (clear_addressable_bit, NULL,
-                                             true);
+           vnode->call_for_symbol_and_aliases (clear_addressable_bit, NULL,
+                                               true);
          }
        if (!address_taken && !written
            /* Making variable in explicit section readonly can cause section
@@ -819,14 +819,14 @@ ipa_discover_readonly_nonaddressable_vars (void)
          {
            if (!TREE_READONLY (vnode->decl) && dump_file)
              fprintf (dump_file, " %s (read-only)", vnode->name ());
-           vnode->call_for_node_and_aliases (set_readonly_bit, NULL, true);
+           vnode->call_for_symbol_and_aliases (set_readonly_bit, NULL, true);
          }
        if (!vnode->writeonly && !read && !address_taken && written)
          {
            if (dump_file)
              fprintf (dump_file, " %s (write-only)", vnode->name ());
-           vnode->call_for_node_and_aliases (set_writeonly_bit, &remove_p, 
-                                            true);
+           vnode->call_for_symbol_and_aliases (set_writeonly_bit, &remove_p, 
+                                               true);
          }
       }
   if (dump_file)
@@ -1343,9 +1343,8 @@ ipa_single_use (void)
          single_user_map.put (var, user);
 
          /* Enqueue all aliases for re-processing.  */
-         for (i = 0; var->iterate_referring (i, ref); i++)
-           if (ref->use == IPA_REF_ALIAS
-               && !ref->referring->aux)
+         for (i = 0; var->iterate_direct_aliases (i, ref); i++)
+           if (!ref->referring->aux)
              {
                ref->referring->aux = first;
                first = dyn_cast <varpool_node *> (ref->referring);
index c0fa47d..6add7fd 100644 (file)
@@ -608,12 +608,18 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
                         lto_symtab_encoder_t encoder)
 {
   bool boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
+  bool encode_initializer_p
+        = (node->definition
+           && lto_symtab_encoder_encode_initializer_p (encoder, node));
   struct bitpack_d bp;
   int ref;
   const char *comdat;
   const char *section;
   tree group;
 
+  gcc_assert (!encode_initializer_p || node->definition);
+  gcc_assert (boundary_p || encode_initializer_p);
+
   streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
                       LTO_symtab_variable);
   streamer_write_hwi_stream (ob->main_stream, node->order);
@@ -624,11 +630,14 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
   bp_pack_value (&bp, node->force_output, 1);
   bp_pack_value (&bp, node->forced_by_abi, 1);
   bp_pack_value (&bp, node->unique_name, 1);
-  bp_pack_value (&bp, node->body_removed
-                || !lto_symtab_encoder_encode_initializer_p (encoder, node), 1);
+  bp_pack_value (&bp,
+                node->body_removed
+                || (!encode_initializer_p && !node->alias && node->definition),
+                1);
   bp_pack_value (&bp, node->implicit_section, 1);
   bp_pack_value (&bp, node->writeonly, 1);
-  bp_pack_value (&bp, node->definition, 1);
+  bp_pack_value (&bp, node->definition && (encode_initializer_p || node->alias),
+                1);
   bp_pack_value (&bp, node->alias, 1);
   bp_pack_value (&bp, node->weakref, 1);
   bp_pack_value (&bp, node->analyzed && !boundary_p, 1);
index 836dce9..542a813 100644 (file)
@@ -319,11 +319,13 @@ static hash_table<tree_hash_entry> *tree_htab;
 void
 lto_streamer_init (void)
 {
+#ifdef ENABLE_CHECKING
   /* Check that all the TS_* handled by the reader and writer routines
      match exactly the structures defined in treestruct.def.  When a
      new TS_* astructure is added, the streamer should be updated to
      handle it.  */
   streamer_check_handled_ts_structures ();
+#endif
 
 #ifdef LTO_STREAMER_DEBUG
   tree_htab = new hash_table<tree_hash_entry> (31);
index c1179cb..235b735 100644 (file)
@@ -57,6 +57,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-inline.h"
 #include "ipa-utils.h"
 #include "lto-partition.h"
+#include "stringpool.h"
 
 vec<ltrans_partition> ltrans_partitions;
 
@@ -783,29 +784,12 @@ lto_balanced_map (int n_lto_partitions)
   free (order);
 }
 
-/* Mangle NODE symbol name into a local name.  
-   This is necessary to do
-   1) if two or more static vars of same assembler name
-      are merged into single ltrans unit.
-   2) if prevoiusly static var was promoted hidden to avoid possible conflict
-      with symbols defined out of the LTO world.
-*/
+/* Return true if we must not change the name of the NODE.  The name as
+   extracted from the corresponding decl should be passed in NAME.  */
 
 static bool
-privatize_symbol_name (symtab_node *node)
+must_not_rename (symtab_node *node, const char *name)
 {
-  tree decl = node->decl;
-  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
-  const char *name;
-
-  /* If we want to privatize instrumentation clone
-     then we need to change original function name
-     which is used via transparent alias chain.  */
-  if (cnode && cnode->instrumentation_clone)
-    decl = cnode->orig_decl;
-
-  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-
   /* Our renaming machinery do not handle more than one change of assembler name.
      We should not need more than one anyway.  */
   if (node->lto_file_data
@@ -813,9 +797,9 @@ privatize_symbol_name (symtab_node *node)
     {
       if (symtab->dump_file)
        fprintf (symtab->dump_file,
-               "Not privatizing symbol name: %s. It privatized already.\n",
-               name);
-      return false;
+                "Not privatizing symbol name: %s. It privatized already.\n",
+                name);
+      return true;
     }
   /* Avoid mangling of already mangled clones. 
      ???  should have a flag whether a symbol has a 'private' name already,
@@ -825,12 +809,103 @@ privatize_symbol_name (symtab_node *node)
     {
       if (symtab->dump_file)
        fprintf (symtab->dump_file,
-               "Not privatizing symbol name: %s. Has unique name.\n",
-               name);
-      return false;
+                "Not privatizing symbol name: %s. Has unique name.\n",
+                name);
+      return true;
     }
+  return false;
+}
+
+/* If we are an offload compiler, we may have to rewrite symbols to be
+   valid on this target.  Return either PTR or a modified version of it.  */
+
+static const char *
+maybe_rewrite_identifier (const char *ptr)
+{
+#if defined ACCEL_COMPILER && (defined NO_DOT_IN_LABEL || defined NO_DOLLAR_IN_LABEL)
+#ifndef NO_DOT_IN_LABEL
+  char valid = '.';
+  const char reject[] = "$";
+#elif !defined NO_DOLLAR_IN_LABEL
+  char valid = '$';
+  const char reject[] = ".";
+#else
+  char valid = '_';
+  const char reject[] = ".$";
+#endif
+
+  char *copy = NULL;
+  const char *match = ptr;
+  for (;;)
+    {
+      size_t off = strcspn (match, reject);
+      if (match[off] == '\0')
+       break;
+      if (copy == NULL)
+       {
+         copy = xstrdup (ptr);
+         match = copy;
+       }
+      copy[off] = valid;
+    }
+  return match;
+#else
+  return ptr;
+#endif
+}
+
+/* Ensure that the symbol in NODE is valid for the target, and if not,
+   rewrite it.  */
+
+static void
+validize_symbol_for_target (symtab_node *node)
+{
+  tree decl = node->decl;
+  const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+  if (must_not_rename (node, name))
+    return;
+
+  const char *name2 = maybe_rewrite_identifier (name);
+  if (name2 != name)
+    {
+      symtab->change_decl_assembler_name (decl, get_identifier (name2));
+      if (node->lto_file_data)
+       lto_record_renamed_decl (node->lto_file_data, name,
+                                IDENTIFIER_POINTER
+                                (DECL_ASSEMBLER_NAME (decl)));
+    }
+}
+
+/* Mangle NODE symbol name into a local name.  
+   This is necessary to do
+   1) if two or more static vars of same assembler name
+      are merged into single ltrans unit.
+   2) if previously static var was promoted hidden to avoid possible conflict
+      with symbols defined out of the LTO world.  */
+
+static bool
+privatize_symbol_name (symtab_node *node)
+{
+  tree decl = node->decl;
+  const char *name;
+  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
+
+  /* If we want to privatize instrumentation clone
+     then we need to change original function name
+     which is used via transparent alias chain.  */
+  if (cnode && cnode->instrumentation_clone)
+    decl = cnode->orig_decl;
+
+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+  if (must_not_rename (node, name))
+    return false;
+
+  name = maybe_rewrite_identifier (name);
   symtab->change_decl_assembler_name (decl,
-                                     clone_function_name (decl, "lto_priv"));
+                                     clone_function_name_1 (name,
+                                                            "lto_priv"));
   if (node->lto_file_data)
     lto_record_renamed_decl (node->lto_file_data, name,
                             IDENTIFIER_POINTER
@@ -868,7 +943,10 @@ promote_symbol (symtab_node *node)
   if (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
       && DECL_VISIBILITY_SPECIFIED (node->decl)
       && TREE_PUBLIC (node->decl))
-    return;
+    {
+      validize_symbol_for_target (node);
+      return;
+    }
 
   gcc_checking_assert (!TREE_PUBLIC (node->decl)
                       && !DECL_EXTERNAL (node->decl));
@@ -1007,7 +1085,10 @@ lto_promote_cross_file_statics (void)
              /* ... or if we do not partition it. This mean that it will
                 appear in every partition refernecing it.  */
              || node->get_partitioning_class () != SYMBOL_PARTITION)
-           continue;
+           {
+             validize_symbol_for_target (node);
+             continue;
+           }
 
           promote_symbol (node);
         }
@@ -1022,5 +1103,8 @@ lto_promote_statics_nonwpa (void)
 {
   symtab_node *node;
   FOR_EACH_SYMBOL (node)
-    rename_statics (NULL, node);
+    {
+      rename_statics (NULL, node);
+      validize_symbol_for_target (node);
+    }
 }
index 81c4ee6..d438179 100644 (file)
@@ -1018,3 +1018,44 @@ along with GCC; see the file COPYING3.  If not see
    (logs (pows @0 @1))
    (mult @1 (logs @0)))))
 
+/* Narrowing of arithmetic and logical operations. 
+
+   These are conceptually similar to the transformations performed for
+   the C/C++ front-ends by shorten_binary_op and shorten_compare.  Long
+   term we want to move all that code out of the front-ends into here.  */
+
+/* If we have a narrowing conversion of an arithmetic operation where
+   both operands are widening conversions from the same type as the outer
+   narrowing conversion.  Then convert the innermost operands to a suitable
+   unsigned type (to avoid introducing undefined behaviour), perform the
+   operation and convert the result to the desired type.  */
+(for op (plus minus)
+  (simplify
+    (convert (op (convert@2 @0) (convert@3 @1)))
+    (if (INTEGRAL_TYPE_P (type)
+        /* We check for type compatibility between @0 and @1 below,
+           so there's no need to check that @1/@3 are integral types.  */
+        && INTEGRAL_TYPE_P (TREE_TYPE (@0))
+        && INTEGRAL_TYPE_P (TREE_TYPE (@2))
+        /* The precision of the type of each operand must match the
+           precision of the mode of each operand, similarly for the
+           result.  */
+        && (TYPE_PRECISION (TREE_TYPE (@0))
+            == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@0))))
+        && (TYPE_PRECISION (TREE_TYPE (@1))
+            == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@1))))
+        && TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type))
+        /* The inner conversion must be a widening conversion.  */
+        && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
+        && ((GENERIC 
+             && (TYPE_MAIN_VARIANT (TREE_TYPE (@0))
+                 == TYPE_MAIN_VARIANT (TREE_TYPE (@1)))
+             && (TYPE_MAIN_VARIANT (TREE_TYPE (@0))
+                 == TYPE_MAIN_VARIANT (type)))
+            || (GIMPLE
+                && types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1))
+                && types_compatible_p (TREE_TYPE (@0), type))))
+      (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+       (convert (op @0 @1)))
+      (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
+       (convert (op (convert:utype @0) (convert:utype @1)))))))
index 4a1ed0e..39c190d 100644 (file)
@@ -493,6 +493,7 @@ static const struct default_options default_options_table[] =
     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fipa_cp_alignment, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
@@ -1330,6 +1331,9 @@ enable_fdo_optimizations (struct gcc_options *opts,
   if (!opts_set->x_flag_ipa_cp_clone
       && value && opts->x_flag_ipa_cp)
     opts->x_flag_ipa_cp_clone = value;
+  if (!opts_set->x_flag_ipa_cp_alignment
+      && value && opts->x_flag_ipa_cp)
+    opts->x_flag_ipa_cp_alignment = value;
   if (!opts_set->x_flag_predictive_commoning)
     opts->x_flag_predictive_commoning = value;
   if (!opts_set->x_flag_unswitch_loops)
index 1b9f8d1..1cb0e2d 100644 (file)
@@ -1400,7 +1400,6 @@ extern int dfa_lookahead;
 
 extern int autopref_multipass_dfa_lookahead_guard (rtx_insn *, int);
 
-extern void ready_sort (struct ready_list *);
 extern rtx_insn *ready_element (struct ready_list *, int);
 extern rtx_insn **ready_lastpos (struct ready_list *);
 
index b85e3e6..45dc45f 100644 (file)
@@ -1722,7 +1722,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
 
              tree test_label
                = build_decl (curr_insn_location (),
-                             LABEL_DECL, NULL_TREE, NULL_TREE);
+                             LABEL_DECL, NULL_TREE, void_type_node);
 
               /* The default label could be reached either through the right
                  subtree or the left subtree. Divide the probability
@@ -1881,7 +1881,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
                 Branch to a label where we will handle it later.  */
 
              test_label = build_decl (curr_insn_location (),
-                                      LABEL_DECL, NULL_TREE, NULL_TREE);
+                                      LABEL_DECL, NULL_TREE, void_type_node);
               probability = conditional_probability (
                   node->right->subtree_prob + default_prob/2,
                   subtree_prob + default_prob);
index 3cdf62a..7a70b10 100644 (file)
@@ -313,18 +313,6 @@ symbol_table::change_decl_assembler_name (tree decl, tree name)
     }
 }
 
-/* Return true when RESOLUTION indicate that linker will use
-   the symbol from non-LTO object files.  */
-
-bool
-resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
-{
-  return (resolution == LDPR_PREVAILING_DEF
-         || resolution == LDPR_PREEMPTED_REG
-         || resolution == LDPR_RESOLVED_EXEC
-         || resolution == LDPR_RESOLVED_DYN);
-}
-
 /* Hash sections by their names.  */
 
 hashval_t
@@ -527,18 +515,18 @@ symtab_node::create_reference (symtab_node *referred_node,
 
   /* IPA_REF_ALIAS is always inserted at the beginning of the list.   */
   if(use_type == IPA_REF_ALIAS)
-  {
-    list2->referring.safe_insert (0, ref);
-    ref->referred_index = 0;
+    {
+      list2->referring.safe_insert (0, ref);
+      ref->referred_index = 0;
 
-    for (unsigned int i = 1; i < list2->referring.length (); i++)
-      list2->referring[i]->referred_index = i;
-  }
+      for (unsigned int i = 1; i < list2->referring.length (); i++)
+       list2->referring[i]->referred_index = i;
+    }
   else
-  {
-    list2->referring.safe_push (ref);
-    ref->referred_index = list2->referring.length () - 1;
-  }
+    {
+      list2->referring.safe_push (ref);
+      ref->referred_index = list2->referring.length () - 1;
+    }
 
   ref->referring = this;
   ref->referred = referred_node;
@@ -743,52 +731,6 @@ symtab_node::dump_referring (FILE *file)
   fprintf (file, "\n");
 }
 
-/* Return true if list contains an alias.  */
-bool
-symtab_node::has_aliases_p (void)
-{
-  ipa_ref *ref = NULL;
-  int i;
-
-  for (i = 0; iterate_referring (i, ref); i++)
-    if (ref->use == IPA_REF_ALIAS)
-      return true;
-  return false;
-}
-
-/* Iterates I-th reference in the list, REF is also set.  */
-
-ipa_ref *
-symtab_node::iterate_reference (unsigned i, ipa_ref *&ref)
-{
-  vec_safe_iterate (ref_list.references, i, &ref);
-
-  return ref;
-}
-
-/* Iterates I-th referring item in the list, REF is also set.  */
-
-ipa_ref *
-symtab_node::iterate_referring (unsigned i, ipa_ref *&ref)
-{
-  ref_list.referring.iterate (i, &ref);
-
-  return ref;
-}
-
-/* Iterates I-th referring alias item in the list, REF is also set.  */
-
-ipa_ref *
-symtab_node::iterate_direct_aliases (unsigned i, ipa_ref *&ref)
-{
-  ref_list.referring.iterate (i, &ref);
-
-  if (ref && ref->use != IPA_REF_ALIAS)
-    return NULL;
-
-  return ref;
-}
-
 static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
 
 /* Dump base fields of symtab nodes to F.  Not to be used directly.  */
@@ -1036,6 +978,11 @@ symtab_node::verify_base (void)
       error ("double linked list of assembler names corrupted");
       error_found = true;
     }
+  if (body_removed && definition)
+    {
+      error ("node has body_removed but is definition");
+      error_found = true;
+    }
   if (analyzed && !definition)
     {
       error ("node is analyzed byt it is not a definition");
@@ -1196,29 +1143,6 @@ symtab_node::verify_symtab_nodes (void)
     }
 }
 
-/* Return true when NODE is known to be used from other (non-LTO)
-   object file. Known only when doing LTO via linker plugin.  */
-
-bool
-symtab_node::used_from_object_file_p_worker (symtab_node *node)
-{
-  if (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl))
-    return false;
-  if (resolution_used_from_other_file_p (node->resolution))
-    return true;
-  return false;
-}
-
-
-/* Return true when symtab_node is known to be used from other (non-LTO)
-   object file. Known only when doing LTO via linker plugin.  */
-
-bool
-symtab_node::used_from_object_file_p (void)
-{
-  return symtab_node::used_from_object_file_p_worker (this);
-}
-
 /* Make DECL local.  FIXME: We shouldn't need to mess with rtl this early,
    but other code such as notice_global_symbol generates rtl.  */
 
@@ -1260,20 +1184,13 @@ symtab_node::make_decl_local (void)
 
 /* Walk the alias chain to return the symbol NODE is alias of.
    If NODE is not an alias, return NODE.
-   When AVAILABILITY is non-NULL, get minimal availability in the chain.  */
+   Assumes NODE is known to be alias.  */
 
 symtab_node *
-symtab_node::ultimate_alias_target (enum availability *availability)
+symtab_node::ultimate_alias_target_1 (enum availability *availability)
 {
   bool weakref_p = false;
 
-  if (!alias)
-    {
-      if (availability)
-       *availability = get_availability ();
-      return this;
-    }
-
   /* To determine visibility of the target, we follow ELF semantic of aliases.
      Here alias is an alternative assembler name of a given definition. Its
      availability prevails the availability of its target (i.e. static alias of
@@ -1453,16 +1370,6 @@ symtab_node::get_init_priority ()
   return h ? h->init : DEFAULT_INIT_PRIORITY;
 }
 
-/* Return availability of NODE.  */
-enum availability symtab_node::get_availability (void)
-{
-  if (is_a <cgraph_node *> (this))
-    return dyn_cast <cgraph_node *> (this)->get_availability ();
-  else
-    return dyn_cast <varpool_node *> (this)->get_availability ();;
-}
-
-
 /* Return the finalization priority.  */
 
 priority_type
@@ -1608,33 +1515,6 @@ symtab_node::resolve_alias (symtab_node *target)
   return true;
 }
 
-/* Call calback on symtab node and aliases associated to this node.
-   When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
-   skipped. */
-
-bool
-symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
-                                                         void *),
-                                       void *data, bool include_overwritable)
-{
-  int i;
-  ipa_ref *ref;
-
-  if (callback (this, data))
-    return true;
-  for (i = 0; iterate_referring (i, ref); i++)
-    if (ref->use == IPA_REF_ALIAS)
-      {
-       symtab_node *alias = ref->referring;
-       if (include_overwritable
-           || alias->get_availability () > AVAIL_INTERPOSABLE)
-         if (alias->call_for_symbol_and_aliases (callback, data,
-                                               include_overwritable))
-           return true;
-      }
-  return false;
-}
-
 /* Worker searching noninterposable alias.  */
 
 bool
@@ -1961,3 +1841,24 @@ symtab_node::equal_address_to (symtab_node *s2)
 
   return 2;
 }
+
+/* Worker for call_for_symbol_and_aliases.  */
+
+bool
+symtab_node::call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *,
+                                                             void *),
+                                           void *data,
+                                           bool include_overwritable)
+{
+  ipa_ref *ref;
+  FOR_EACH_ALIAS (this, ref)
+    {
+      symtab_node *alias = ref->referring;
+      if (include_overwritable
+         || alias->get_availability () > AVAIL_INTERPOSABLE)
+       if (alias->call_for_symbol_and_aliases (callback, data,
+                                             include_overwritable))
+         return true;
+    }
+  return false;
+}
index 21fa497..078c2da 100644 (file)
@@ -4967,6 +4967,8 @@ ipa_tm_create_version (struct cgraph_node *old_node)
   new_node->externally_visible = old_node->externally_visible;
   new_node->lowered = true;
   new_node->tm_clone = 1;
+  if (!old_node->implicit_section)
+    new_node->set_section (old_node->get_section ());
   get_cg_data (&old_node, true)->clone = new_node;
 
   if (old_node->get_availability () >= AVAIL_INTERPOSABLE)
index 2e23553..006bc08 100644 (file)
@@ -8754,7 +8754,7 @@ const pass_data pass_data_fixup_cfg =
   PROP_cfg, /* properties_required */
   0, /* properties_provided */
   0, /* properties_destroyed */
-  TODO_update_ssa_only_virtuals, /* todo_flags_start */
+  0, /* todo_flags_start */
   0, /* todo_flags_finish */
 };
 
index 3c45f37..a111e9d 100644 (file)
@@ -884,10 +884,10 @@ eh_region_may_contain_throw (eh_region r)
 /* We want to transform
        try { body; } catch { stuff; }
    to
-       normal_seqence:
+       normal_sequence:
          body;
          over:
-       eh_seqence:
+       eh_sequence:
          landing_pad:
          stuff;
          goto over;
@@ -1813,6 +1813,12 @@ lower_catch (struct leh_state *state, gtry *tp)
   this_state.cur_region = state->cur_region;
   this_state.ehp_region = try_region;
 
+  /* Add eh_seq from lowering EH in the cleanup sequence after the cleanup
+     itself, so that e.g. for coverage purposes the nested cleanups don't
+     appear before the cleanup body.  See PR64634 for details.  */
+  gimple_seq old_eh_seq = eh_seq;
+  eh_seq = NULL;
+
   out_label = NULL;
   cleanup = gimple_try_cleanup (tp);
   for (gsi = gsi_start (cleanup);
@@ -1849,7 +1855,11 @@ lower_catch (struct leh_state *state, gtry *tp)
 
   gimple_try_set_cleanup (tp, new_seq);
 
-  return frob_into_branch_around (tp, try_region, out_label);
+  gimple_seq new_eh_seq = eh_seq;
+  eh_seq = old_eh_seq;
+  gimple_seq ret_seq = frob_into_branch_around (tp, try_region, out_label);
+  gimple_seq_add_seq (&eh_seq, new_eh_seq);
+  return ret_seq;
 }
 
 /* A subroutine of lower_eh_constructs_1.  Lower a GIMPLE_TRY with a
index b4711a5..4d7b4e9 100644 (file)
@@ -787,7 +787,7 @@ ipa_lower_emutls (void)
       if (var->alias && !var->analyzed)
        any_aliases = true;
       else if (!var->alias)
-       var->call_for_node_and_aliases (create_emultls_var, &ctor_body, true);
+       var->call_for_symbol_and_aliases (create_emultls_var, &ctor_body, true);
     }
 
   /* If there were any aliases, then frob the alias_pairs vector.  */
index ac32c84..03a38b4 100644 (file)
@@ -1745,9 +1745,8 @@ execute_pred_commoning_chain (struct loop *loop, chain_p chain,
   if (chain->combined)
     {
       /* For combined chains, just remove the statements that are used to
-        compute the values of the expression (except for the root one).  */
-      for (i = 1; chain->refs.iterate (i, &a); i++)
-       remove_stmt (a->stmt);
+        compute the values of the expression (except for the root one).
+        We delay this until after all chains are processed.  */
     }
   else
     {
@@ -1776,9 +1775,21 @@ determine_unroll_factor (vec<chain_p> chains)
 
   FOR_EACH_VEC_ELT (chains, i, chain)
     {
-      if (chain->type == CT_INVARIANT || chain->combined)
+      if (chain->type == CT_INVARIANT)
        continue;
 
+      if (chain->combined)
+       {
+         /* For combined chains, we can't handle unrolling if we replace
+            looparound PHIs.  */
+         dref a;
+         unsigned j;
+         for (j = 1; chain->refs.iterate (j, &a); j++)
+           if (gimple_code (a->stmt) == GIMPLE_PHI)
+             return 1;
+         continue;
+       }
+
       /* The best unroll factor for this chain is equal to the number of
         temporary variables that we create for it.  */
       af = chain->length;
@@ -1811,6 +1822,21 @@ execute_pred_commoning (struct loop *loop, vec<chain_p> chains,
        execute_pred_commoning_chain (loop, chain, tmp_vars);
     }
 
+  FOR_EACH_VEC_ELT (chains, i, chain)
+    {
+      if (chain->type == CT_INVARIANT)
+       ;
+      else if (chain->combined)
+       {
+         /* For combined chains, just remove the statements that are used to
+            compute the values of the expression (except for the root one).  */
+         dref a;
+         unsigned j;
+         for (j = 1; chain->refs.iterate (j, &a); j++)
+           remove_stmt (a->stmt);
+       }
+    }
+
   update_ssa (TODO_update_ssa_only_virtuals);
 }
 
index c6726a8..023b817 100644 (file)
@@ -4890,6 +4890,20 @@ some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
   return false;
 }
 
+/* Return false if all callers have vuse attached to a call statement.  */
+
+static bool
+some_callers_have_no_vuse_p (struct cgraph_node *node,
+                            void *data ATTRIBUTE_UNUSED)
+{
+  struct cgraph_edge *cs;
+  for (cs = node->callers; cs; cs = cs->next_caller)
+    if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
+      return true;
+
+  return false;
+}
+
 /* Convert all callers of NODE.  */
 
 static bool
@@ -5116,6 +5130,15 @@ ipa_early_sra (void)
       goto simple_out;
     }
 
+  if (node->call_for_symbol_thunks_and_aliases
+       (some_callers_have_no_vuse_p, NULL, true))
+    {
+      if (dump_file)
+       fprintf (dump_file, "There are callers with no VUSE attached "
+                "to a call stmt.\n");
+      goto simple_out;
+    }
+
   bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
                                 func_param_count
                                 * last_basic_block_for_fn (cfun));
index 9f0b2a5..096e471 100644 (file)
@@ -2291,11 +2291,16 @@ cprop_operand (gimple stmt, use_operand_p op_p)
       if (!may_propagate_copy (op, val))
        return;
 
-      /* Do not propagate copies into simple IV increment statements.
-         See PR23821 for how this can disturb IV analysis.  */
-      if (TREE_CODE (val) != INTEGER_CST
-         && simple_iv_increment_p (stmt))
-       return;
+      /* Do not propagate copies into BIVs.
+         See PR23821 and PR62217 for how this can disturb IV and
+        number of iteration analysis.  */
+      if (TREE_CODE (val) != INTEGER_CST)
+       {
+         gimple def = SSA_NAME_DEF_STMT (op);
+         if (gimple_code (def) == GIMPLE_PHI
+             && gimple_bb (def)->loop_father->header == gimple_bb (def))
+           return;
+       }
 
       /* Dump details.  */
       if (dump_file && (dump_flags & TDF_DETAILS))
index bad546d..c7fb073 100644 (file)
@@ -917,6 +917,31 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
              && absorbing_element_p (code_def, cond_rhs))))
     {
       gsi = gsi_for_stmt (cond);
+      if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
+       {
+         /* Moving ASSIGN might change VR of lhs, e.g. when moving u_6
+            def-stmt in:
+            if (n_5 != 0)
+              goto <bb 3>;
+            else
+              goto <bb 4>;
+
+            <bb 3>:
+            # RANGE [0, 4294967294]
+            u_6 = n_5 + 4294967295;
+
+            <bb 4>:
+            # u_3 = PHI <u_6(3), 4294967295(2)>  */
+         SSA_NAME_RANGE_INFO (lhs) = NULL;
+         SSA_NAME_ANTI_RANGE_P (lhs) = 0;
+         /* If available, we can use VR of phi result at least.  */
+         tree phires = gimple_phi_result (phi);
+         struct range_info_def *phires_range_info
+           = SSA_NAME_RANGE_INFO (phires);
+         if (phires_range_info)
+           duplicate_ssa_name_range_info (lhs, SSA_NAME_RANGE_TYPE (phires),
+                                          phires_range_info);
+       }
       gimple_stmt_iterator gsi_from = gsi_for_stmt (assign);
       gsi_move_before (&gsi_from, &gsi);
       replace_phi_edge_with_variable (cond_bb, e1, phi, lhs);
index 9952222..ce37053 100644 (file)
@@ -2177,10 +2177,18 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
 
   tem = fold_convert_loc (loc, optype, tem);
   gsi = gsi_for_stmt (stmt);
+  unsigned int uid = gimple_uid (stmt);
   /* In rare cases range->exp can be equal to lhs of stmt.
      In that case we have to insert after the stmt rather then before
-     it.  */
-  if (op == range->exp)
+     it.  If stmt is a PHI, insert it at the start of the basic block.  */
+  if (op != range->exp)
+    {
+      gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
+      tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, true,
+                                     GSI_SAME_STMT);
+      gsi_prev (&gsi);
+    }
+  else if (gimple_code (stmt) != GIMPLE_PHI)
     {
       gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
       tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, false,
@@ -2188,16 +2196,32 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
     }
   else
     {
+      gsi = gsi_after_labels (gimple_bb (stmt));
+      if (!gsi_end_p (gsi))
+       uid = gimple_uid (gsi_stmt (gsi));
+      else
+       {
+         gsi = gsi_start_bb (gimple_bb (stmt));
+         uid = 1;
+         while (!gsi_end_p (gsi))
+           {
+             uid = gimple_uid (gsi_stmt (gsi));
+             gsi_next (&gsi);
+           }
+       }
       gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
       tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, true,
                                      GSI_SAME_STMT);
-      gsi_prev (&gsi);
+      if (gsi_end_p (gsi))
+       gsi = gsi_last_bb (gimple_bb (stmt));
+      else
+       gsi_prev (&gsi);
     }
   for (; !gsi_end_p (gsi); gsi_prev (&gsi))
     if (gimple_uid (gsi_stmt (gsi)))
       break;
     else
-      gimple_set_uid (gsi_stmt (gsi), gimple_uid (stmt));
+      gimple_set_uid (gsi_stmt (gsi), uid);
 
   oe->op = tem;
   range->exp = exp;
index 4c43b75..fd0f535 100644 (file)
@@ -3492,6 +3492,9 @@ get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
          case ARRAY_REF:
          case ARRAY_RANGE_REF:
          case COMPONENT_REF:
+         case IMAGPART_EXPR:
+         case REALPART_EXPR:
+         case BIT_FIELD_REF:
            get_constraint_for_component_ref (t, results, address_p, lhs_p);
            return;
          case VIEW_CONVERT_EXPR:
@@ -4712,11 +4715,7 @@ find_func_aliases (struct function *fn, gimple origt)
 
          get_constraint_for (lhsop, &lhsc);
 
-         if (FLOAT_TYPE_P (TREE_TYPE (lhsop)))
-           /* If the operation produces a floating point result then
-              assume the value is not produced to transfer a pointer.  */
-           ;
-         else if (code == POINTER_PLUS_EXPR)
+         if (code == POINTER_PLUS_EXPR)
            get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
                                           gimple_assign_rhs2 (t), &rhsc);
          else if (code == BIT_AND_EXPR
index 4f83991..7187d06 100644 (file)
@@ -110,6 +110,15 @@ potentially_threadable_block (basic_block bb)
 {
   gimple_stmt_iterator gsi;
 
+  /* Special case.  We can get blocks that are forwarders, but are
+     not optimized away because they forward from outside a loop
+     to the loop header.   We want to thread through them as we can
+     sometimes thread to the loop exit, which is obviously profitable. 
+     the interesting case here is when the block has PHIs.  */
+  if (gsi_end_p (gsi_start_nondebug_bb (bb))
+      && !gsi_end_p (gsi_start_phis (bb)))
+    return true;
+  
   /* If BB has a single successor or a single predecessor, then
      there is no threading opportunity.  */
   if (single_succ_p (bb) || single_pred_p (bb))
@@ -1281,16 +1290,32 @@ thread_through_normal_block (edge e,
     = record_temporary_equivalences_from_stmts_at_dest (e, stack, simplify,
                                                        *backedge_seen_p);
 
-  /* If we didn't look at all the statements, the most likely reason is
-     there were too many and thus duplicating this block is not profitable.
+  /* There's two reasons STMT might be null, and distinguishing
+     between them is important.
 
-     Also note if we do not look at all the statements, then we may not
-     have invalidated equivalences that are no longer valid if we threaded
-     around a loop.  Thus we must signal to our caller that this block
-     is not suitable for use as a joiner in a threading path.  */
+     First the block may not have had any statements.  For example, it
+     might have some PHIs and unconditionally transfer control elsewhere.
+     Such blocks are suitable for jump threading, particularly as a
+     joiner block.
+
+     The second reason would be if we did not process all the statements
+     in the block (because there were too many to make duplicating the
+     block profitable.   If we did not look at all the statements, then
+     we may not have invalidated everything needing invalidation.  Thus
+     we must signal to our caller that this block is not suitable for
+     use as a joiner in a threading path.  */
   if (!stmt)
-    return -1;
+    {
+      /* First case.  The statement simply doesn't have any instructions, but
+        does have PHIs.  */
+      if (gsi_end_p (gsi_start_nondebug_bb (e->dest))
+         && !gsi_end_p (gsi_start_phis (e->dest)))
+       return 0;
 
+      /* Second case.  */
+      return -1;
+    }
+  
   /* If we stopped at a COND_EXPR or SWITCH_EXPR, see if we know which arm
      will be taken.  */
   if (gimple_code (stmt) == GIMPLE_COND
index 2cf0ca3..0c70790 100644 (file)
@@ -704,8 +704,16 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *fun)
     {
-      /* This optimization is only for stdarg functions.  */
-      return fun->stdarg != 0;
+      return (flag_stdarg_opt
+#ifdef ACCEL_COMPILER
+             /* Disable for GCC5 in the offloading compilers, as
+                va_list and gpr/fpr counter fields are not merged.
+                In GCC6 when stdarg is lowered late this shouldn't be
+                an issue.  */
+             && !in_lto_p
+#endif
+             /* This optimization is only for stdarg functions.  */
+             && fun->stdarg != 0);
     }
 
   virtual unsigned int execute (function *);
index 8f597aa..7b35358 100644 (file)
@@ -342,7 +342,14 @@ preload_common_nodes (struct streamer_tree_cache_d *cache)
        && i != TI_TARGET_OPTION_DEFAULT
        && i != TI_TARGET_OPTION_CURRENT
        && i != TI_CURRENT_TARGET_PRAGMA
-       && i != TI_CURRENT_OPTIMIZE_PRAGMA)
+       && i != TI_CURRENT_OPTIMIZE_PRAGMA
+       /* Skip va_list* related nodes if offloading.  For native LTO
+          we want them to be merged for the stdarg pass, for offloading
+          they might not be identical between host and offloading target.  */
+       && (!lto_stream_offload_p
+           || (i != TI_VA_LIST_TYPE
+               && i != TI_VA_LIST_GPR_COUNTER_FIELD
+               && i != TI_VA_LIST_FPR_COUNTER_FIELD)))
       record_common_node (cache, global_trees[i]);
 }
 
index dad1830..9556ede 100644 (file)
@@ -10173,16 +10173,20 @@ identify_jump_threads (void)
       if (! potentially_threadable_block (bb))
        continue;
 
-      /* We only care about blocks ending in a COND_EXPR.  While there
-        may be some value in handling SWITCH_EXPR here, I doubt it's
-        terribly important.  */
-      last = gsi_stmt (gsi_last_bb (bb));
+      last = last_stmt (bb);
 
       /* We're basically looking for a switch or any kind of conditional with
         integral or pointer type arguments.  Note the type of the second
         argument will be the same as the first argument, so no need to
-        check it explicitly.  */
-      if (gimple_code (last) == GIMPLE_SWITCH
+        check it explicitly. 
+
+        We also handle the case where there are no statements in the
+        block.  This come up with forwarder blocks that are not
+        optimized away because they lead to a loop header.  But we do
+        want to thread through them as we can sometimes thread to the
+        loop exit which is obviously profitable.  */
+      if (!last
+         || gimple_code (last) == GIMPLE_SWITCH
          || (gimple_code (last) == GIMPLE_COND
              && TREE_CODE (gimple_cond_lhs (last)) == SSA_NAME
              && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (last)))
index 6fe1d5a..29f70f8 100644 (file)
@@ -11992,7 +11992,7 @@ type_in_anonymous_namespace_p (const_tree t)
 
 /* Lookup sub-BINFO of BINFO of TYPE at offset POS.  */
 
-tree
+static tree
 lookup_binfo_at_offset (tree binfo, tree type, HOST_WIDE_INT pos)
 {
   unsigned int i;
@@ -12045,11 +12045,13 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
       else if (offset != 0)
        {
          tree found_binfo = NULL, base_binfo;
-         int offset = (tree_to_shwi (BINFO_OFFSET (binfo)) + pos
-                       / BITS_PER_UNIT);
+         /* Offsets in BINFO are in bytes relative to the whole structure
+            while POS is in bits relative to the containing field.  */
+         int binfo_offset = (tree_to_shwi (BINFO_OFFSET (binfo)) + pos
+                            / BITS_PER_UNIT);
 
          for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
-           if (tree_to_shwi (BINFO_OFFSET (base_binfo)) == offset
+           if (tree_to_shwi (BINFO_OFFSET (base_binfo)) == binfo_offset
                && types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld)))
              {
                found_binfo = base_binfo;
@@ -12058,7 +12060,8 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
          if (found_binfo)
            binfo = found_binfo;
          else
-           binfo = lookup_binfo_at_offset (binfo, TREE_TYPE (fld), offset);
+           binfo = lookup_binfo_at_offset (binfo, TREE_TYPE (fld),
+                                           binfo_offset);
         }
 
       type = TREE_TYPE (fld);
index fc3352f..38d98cf 100644 (file)
@@ -920,6 +920,8 @@ ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
   return false;
 }
 
+#define OBJSZ_MAX_OFFSET (1024 * 16)
+
 /* Expand UBSAN_OBJECT_SIZE internal call.  */
 
 bool
@@ -941,6 +943,10 @@ ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
       || integer_all_onesp (size))
     /* Yes, __builtin_object_size couldn't determine the
        object size.  */;
+  else if (TREE_CODE (offset) == INTEGER_CST
+          && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
+          && wi::les_p (wi::to_widest (offset), -1))
+    /* The offset is in range [-16K, -1].  */;
   else
     {
       /* if (offset > objsize) */
@@ -952,8 +958,42 @@ ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
       gimple_set_location (g, loc);
       gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
 
+      /* If the offset is small enough, we don't need the second
+        run-time check.  */
+      if (TREE_CODE (offset) == INTEGER_CST
+         && wi::ges_p (wi::to_widest (offset), 0)
+         && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
+       *gsi = gsi_after_labels (then_bb);
+      else
+       {
+         /* Don't issue run-time error if (ptr > ptr + offset).  That
+            may happen when computing a POINTER_PLUS_EXPR.  */
+         basic_block then2_bb, fallthru2_bb;
+
+         gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
+         cond_insert_point = create_cond_insert_point (&gsi2, false, false,
+                                                       true, &then2_bb,
+                                                       &fallthru2_bb);
+         /* Convert the pointer to an integer type.  */
+         tree p = make_ssa_name (pointer_sized_int_node);
+         g = gimple_build_assign (p, NOP_EXPR, ptr);
+         gimple_set_location (g, loc);
+         gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
+         p = gimple_assign_lhs (g);
+         /* Compute ptr + offset.  */
+         g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
+                                  PLUS_EXPR, p, offset);
+         gimple_set_location (g, loc);
+         gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
+         /* Now build the conditional and put it into the IR.  */
+         g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
+                                NULL_TREE, NULL_TREE);
+         gimple_set_location (g, loc);
+         gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
+         *gsi = gsi_after_labels (then2_bb);
+       }
+
       /* Generate __ubsan_handle_type_mismatch call.  */
-      *gsi = gsi_after_labels (then_bb);
       if (flag_sanitize_undefined_trap_on_error)
        g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
       else
index 0211306..8173207 100644 (file)
@@ -6828,19 +6828,18 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
      because dynamic linking might overwrite symbols
      in shared libraries.  */
   bool resolved_locally = false;
-  bool defined_locally = false;
+  bool defined_locally = !DECL_EXTERNAL (exp);
   if (symtab_node *node = symtab_node::get (exp))
     {
-      if (node->definition || node->in_other_partition)
-       {
-         defined_locally = true;
-         resolved_locally = (weak_dominate && !shlib);
-       }
+      if (node->in_other_partition)
+       defined_locally = true;
       if (resolution_to_local_definition_p (node->resolution))
        defined_locally = resolved_locally = true;
       else if (resolution_local_p (node->resolution))
        resolved_locally = true;
     }
+  if (defined_locally && weak_dominate && !shlib)
+    resolved_locally = true;
 
   /* Undefined weak symbols are never defined locally.  */
   if (DECL_WEAK (exp) && !defined_locally)
@@ -7043,7 +7042,13 @@ default_file_start (void)
     fputs (ASM_APP_OFF, asm_out_file);
 
   if (targetm.asm_file_start_file_directive)
-    output_file_directive (asm_out_file, main_input_filename);
+    {
+      /* LTO produced units have no meaningful main_input_filename.  */
+      if (in_lto_p)
+       output_file_directive (asm_out_file, "<artificial>");
+      else
+       output_file_directive (asm_out_file, main_input_filename);
+    }
 }
 
 /* This is a generic routine suitable for use as TARGET_ASM_FILE_END
index 49a9213..707f62f 100644 (file)
@@ -303,7 +303,8 @@ varpool_node::get_constructor (void)
   size_t len;
 
   if (DECL_INITIAL (decl) != error_mark_node
-      || !in_lto_p)
+      || !in_lto_p
+      || !lto_file_data)
     return DECL_INITIAL (decl);
 
   timevar_push (TV_IPA_LTO_CTORS_IN);
@@ -817,28 +818,23 @@ varpool_node::create_extra_name_alias (tree alias, tree decl)
   return alias_node;
 }
 
-/* Call calback on varpool symbol and aliases associated to varpool symbol.
-   When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
-   skipped. */
+/* Worker for call_for_symbol_and_aliases.  */
 
 bool
-varpool_node::call_for_node_and_aliases (bool (*callback) (varpool_node *,
-                                                          void *),
-                                        void *data,
-                                        bool include_overwritable)
+varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *,
+                                                              void *),
+                                            void *data,
+                                            bool include_overwritable)
 {
   ipa_ref *ref;
 
-  if (callback (this, data))
-    return true;
-
   FOR_EACH_ALIAS (this, ref)
     {
       varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
       if (include_overwritable
          || alias->get_availability () > AVAIL_INTERPOSABLE)
-       if (alias->call_for_node_and_aliases (callback, data,
-                                             include_overwritable))
+       if (alias->call_for_symbol_and_aliases (callback, data,
+                                               include_overwritable))
          return true;
     }
   return false;
index 04db61a..e15e07c 100644 (file)
@@ -23,6 +23,10 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 
 #include "ansidecl.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* A floatformat consists of a sign bit, an exponent and a mantissa.  Once the
    bytes are concatenated according to the byteorder flag, then each of those
    fields is contiguous.  We number the bits with 0 being the most significant
@@ -149,4 +153,8 @@ floatformat_from_double (const struct floatformat *, const double *, void *);
 extern int
 floatformat_is_valid (const struct floatformat *fmt, const void *from);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* defined (FLOATFORMAT_H) */
index 5b4a9a4..136f010 100644 (file)
@@ -21,8 +21,7 @@
    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <stdlib.h>
-#include <string.h>
+#include <stddef.h>
 #include "nvptx-malloc.h"
 
 void *
@@ -44,7 +43,7 @@ __nvptx_realloc (void *ptr, size_t newsz)
       oldsz = *sp;
     }
   if (oldsz != 0)
-    memcpy (newptr, ptr, oldsz > newsz ? newsz : oldsz);
+    __builtin_memcpy (newptr, ptr, oldsz > newsz ? newsz : oldsz);
 
   __nvptx_free (ptr);
   return newptr;
index ffb22e9..f448ba9 100644 (file)
@@ -55,7 +55,7 @@ GOMP_PLUGIN_debug (int kind, const char *msg, ...)
   va_list ap;
 
   va_start (ap, msg);
-  gomp_debug (kind, msg, ap);
+  gomp_vdebug (kind, msg, ap);
   va_end (ap);
 }
 
index 13ff86f..2419a46 100644 (file)
   ".version 3.1\n" \
   ".target sm_30\n" \
   ".address_size 64\n" \
+  ".visible .func (.param .u32 %out_retval) GOACC_tid (.param .u32 %in_ar1);\n" \
+  ".visible .func (.param .u32 %out_retval) GOACC_ntid (.param .u32 %in_ar1);\n" \
+  ".visible .func (.param .u32 %out_retval) GOACC_ctaid (.param .u32 %in_ar1);\n" \
+  ".visible .func (.param .u32 %out_retval) GOACC_nctaid (.param .u32 %in_ar1);\n" \
   ".visible .func (.param .u32 %out_retval) GOACC_get_num_threads;\n" \
   ".visible .func (.param .u32 %out_retval) GOACC_get_thread_num;\n" \
   ".extern .func abort;\n" \
+  ".visible .func (.param .u32 %out_retval) GOACC_tid (.param .u32 %in_ar1)\n" \
+  "{\n" \
+  ".reg .u32 %ar1;\n" \
+  ".reg .u32 %retval;\n" \
+  ".reg .u64 %hr10;\n" \
+  ".reg .u32 %r22;\n" \
+  ".reg .u32 %r23;\n" \
+  ".reg .u32 %r24;\n" \
+  ".reg .u32 %r25;\n" \
+  ".reg .u32 %r26;\n" \
+  ".reg .u32 %r27;\n" \
+  ".reg .u32 %r28;\n" \
+  ".reg .u32 %r29;\n" \
+  ".reg .pred %r30;\n" \
+  ".reg .u32 %r31;\n" \
+  ".reg .pred %r32;\n" \
+  ".reg .u32 %r33;\n" \
+  ".reg .pred %r34;\n" \
+  ".local .align 8 .b8 %frame[4];\n" \
+  "ld.param.u32 %ar1,[%in_ar1];\n" \
+  "mov.u32 %r27,%ar1;\n" \
+  "st.local.u32 [%frame],%r27;\n" \
+  "ld.local.u32 %r28,[%frame];\n" \
+  "mov.u32 %r29,1;\n"                                                  \
+  "setp.eq.u32 %r30,%r28,%r29;\n"                                      \
+  "@%r30 bra $L4;\n"                                                   \
+  "mov.u32 %r31,2;\n"                                                  \
+  "setp.eq.u32 %r32,%r28,%r31;\n"                                      \
+  "@%r32 bra $L5;\n"                                                   \
+  "mov.u32 %r33,0;\n"                                                  \
+  "setp.eq.u32 %r34,%r28,%r33;\n"                                      \
+  "@!%r34 bra $L8;\n"                                                  \
+  "mov.u32 %r23,%tid.x;\n"                                             \
+  "mov.u32 %r22,%r23;\n"                                               \
+  "bra $L7;\n"                                                         \
+  "$L4:\n"                                                             \
+  "mov.u32 %r24,%tid.y;\n"                                             \
+  "mov.u32 %r22,%r24;\n"                                               \
+  "bra $L7;\n"                                                         \
+  "$L5:\n"                                                             \
+  "mov.u32 %r25,%tid.z;\n"                                             \
+  "mov.u32 %r22,%r25;\n"                                               \
+  "bra $L7;\n"                                                         \
+  "$L8:\n"                                                             \
+  "{\n"                                                                        \
+  "{\n"                                                                        \
+  "call abort;\n"                                                      \
+  "}\n"                                                                        \
+  "}\n"                                                                        \
+  "$L7:\n"                                                             \
+  "mov.u32 %r26,%r22;\n"                                               \
+  "mov.u32 %retval,%r26;\n"                                            \
+  "st.param.u32 [%out_retval],%retval;\n"                              \
+  "ret;\n"                                                             \
+  "}\n"                                                                        \
+  ".visible .func (.param .u32 %out_retval) GOACC_ntid (.param .u32 %in_ar1)\n" \
+  "{\n"                                                                        \
+  ".reg .u32 %ar1;\n"                                                  \
+  ".reg .u32 %retval;\n"                                               \
+  ".reg .u64 %hr10;\n"                                                 \
+  ".reg .u32 %r22;\n"                                                  \
+  ".reg .u32 %r23;\n"                                                  \
+  ".reg .u32 %r24;\n"                                                  \
+  ".reg .u32 %r25;\n"                                                  \
+  ".reg .u32 %r26;\n"                                                  \
+  ".reg .u32 %r27;\n"                                                  \
+  ".reg .u32 %r28;\n"                                                  \
+  ".reg .u32 %r29;\n"                                                  \
+  ".reg .pred %r30;\n"                                                 \
+  ".reg .u32 %r31;\n"                                                  \
+  ".reg .pred %r32;\n"                                                 \
+  ".reg .u32 %r33;\n"                                                  \
+  ".reg .pred %r34;\n"                                                 \
+  ".local .align 8 .b8 %frame[4];\n"                                   \
+  "ld.param.u32 %ar1,[%in_ar1];\n"                                     \
+  "mov.u32 %r27,%ar1;\n"                                               \
+  "st.local.u32 [%frame],%r27;\n"                                      \
+  "ld.local.u32 %r28,[%frame];\n"                                      \
+  "mov.u32 %r29,1;\n"                                                  \
+  "setp.eq.u32 %r30,%r28,%r29;\n"                                      \
+  "@%r30 bra $L11;\n"                                                  \
+  "mov.u32 %r31,2;\n"                                                  \
+  "setp.eq.u32 %r32,%r28,%r31;\n"                                      \
+  "@%r32 bra $L12;\n"                                                  \
+  "mov.u32 %r33,0;\n"                                                  \
+  "setp.eq.u32 %r34,%r28,%r33;\n"                                      \
+  "@!%r34 bra $L15;\n"                                                 \
+  "mov.u32 %r23,%ntid.x;\n"                                            \
+  "mov.u32 %r22,%r23;\n"                                               \
+  "bra $L14;\n"                                                                \
+  "$L11:\n"                                                            \
+  "mov.u32 %r24,%ntid.y;\n"                                            \
+  "mov.u32 %r22,%r24;\n"                                               \
+  "bra $L14;\n"                                                                \
+  "$L12:\n"                                                            \
+  "mov.u32 %r25,%ntid.z;\n"                                            \
+  "mov.u32 %r22,%r25;\n"                                               \
+  "bra $L14;\n"                                                                \
+  "$L15:\n"                                                            \
+  "{\n"                                                                        \
+  "{\n"                                                                        \
+  "call abort;\n"                                                      \
+  "}\n"                                                                        \
+  "}\n"                                                                        \
+  "$L14:\n"                                                            \
+  "mov.u32 %r26,%r22;\n"                                               \
+  "mov.u32 %retval,%r26;\n"                                            \
+  "st.param.u32 [%out_retval],%retval;\n"                              \
+  "ret;\n"                                                             \
+  "}\n"                                                                        \
+  ".visible .func (.param .u32 %out_retval) GOACC_ctaid (.param .u32 %in_ar1)\n" \
+  "{\n"                                                                        \
+  ".reg .u32 %ar1;\n"                                                  \
+  ".reg .u32 %retval;\n"                                               \
+  ".reg .u64 %hr10;\n"                                                 \
+  ".reg .u32 %r22;\n"                                                  \
+  ".reg .u32 %r23;\n"                                                  \
+  ".reg .u32 %r24;\n"                                                  \
+  ".reg .u32 %r25;\n"                                                  \
+  ".reg .u32 %r26;\n"                                                  \
+  ".reg .u32 %r27;\n"                                                  \
+  ".reg .u32 %r28;\n"                                                  \
+  ".reg .u32 %r29;\n"                                                  \
+  ".reg .pred %r30;\n"                                                 \
+  ".reg .u32 %r31;\n"                                                  \
+  ".reg .pred %r32;\n"                                                 \
+  ".reg .u32 %r33;\n"                                                  \
+  ".reg .pred %r34;\n"                                                 \
+  ".local .align 8 .b8 %frame[4];\n"                                   \
+  "ld.param.u32 %ar1,[%in_ar1];\n"                                     \
+  "mov.u32 %r27,%ar1;\n"                                               \
+  "st.local.u32 [%frame],%r27;\n"                                      \
+  "ld.local.u32 %r28,[%frame];\n"                                      \
+  "mov.u32 %r29,1;\n"                                                  \
+  "setp.eq.u32 %r30,%r28,%r29;\n"                                      \
+  "@%r30 bra $L18;\n"                                                  \
+  "mov.u32 %r31,2;\n"                                                  \
+  "setp.eq.u32 %r32,%r28,%r31;\n"                                      \
+  "@%r32 bra $L19;\n"                                                  \
+  "mov.u32 %r33,0;\n"                                                  \
+  "setp.eq.u32 %r34,%r28,%r33;\n"                                      \
+  "@!%r34 bra $L22;\n"                                                 \
+  "mov.u32 %r23,%ctaid.x;\n"                                           \
+  "mov.u32 %r22,%r23;\n"                                               \
+  "bra $L21;\n"                                                                \
+  "$L18:\n"                                                            \
+  "mov.u32 %r24,%ctaid.y;\n"                                           \
+  "mov.u32 %r22,%r24;\n"                                               \
+  "bra $L21;\n"                                                                \
+  "$L19:\n"                                                            \
+  "mov.u32 %r25,%ctaid.z;\n"                                           \
+  "mov.u32 %r22,%r25;\n"                                               \
+  "bra $L21;\n"                                                                \
+  "$L22:\n"                                                            \
+  "{\n"                                                                        \
+  "{\n"                                                                        \
+  "call abort;\n"                                                      \
+  "}\n"                                                                        \
+  "}\n"                                                                        \
+  "$L21:\n"                                                            \
+  "mov.u32 %r26,%r22;\n"                                               \
+  "mov.u32 %retval,%r26;\n"                                            \
+  "st.param.u32 [%out_retval],%retval;\n"                              \
+  "ret;\n"                                                             \
+  "}\n"                                                                        \
+  ".visible .func (.param .u32 %out_retval) GOACC_nctaid (.param .u32 %in_ar1)\n" \
+  "{\n"                                                                        \
+  ".reg .u32 %ar1;\n"                                                  \
+  ".reg .u32 %retval;\n"                                               \
+  ".reg .u64 %hr10;\n"                                                 \
+  ".reg .u32 %r22;\n"                                                  \
+  ".reg .u32 %r23;\n"                                                  \
+  ".reg .u32 %r24;\n"                                                  \
+  ".reg .u32 %r25;\n"                                                  \
+  ".reg .u32 %r26;\n"                                                  \
+  ".reg .u32 %r27;\n"                                                  \
+  ".reg .u32 %r28;\n"                                                  \
+  ".reg .u32 %r29;\n"                                                  \
+  ".reg .pred %r30;\n"                                                 \
+  ".reg .u32 %r31;\n"                                                  \
+  ".reg .pred %r32;\n"                                                 \
+  ".reg .u32 %r33;\n"                                                  \
+  ".reg .pred %r34;\n"                                                 \
+  ".local .align 8 .b8 %frame[4];\n"                                   \
+  "ld.param.u32 %ar1,[%in_ar1];\n"                                     \
+  "mov.u32 %r27,%ar1;\n"                                               \
+  "st.local.u32 [%frame],%r27;\n"                                      \
+  "ld.local.u32 %r28,[%frame];\n"                                      \
+  "mov.u32 %r29,1;\n"                                                  \
+  "setp.eq.u32 %r30,%r28,%r29;\n"                                      \
+  "@%r30 bra $L25;\n"                                                  \
+  "mov.u32 %r31,2;\n"                                                  \
+  "setp.eq.u32 %r32,%r28,%r31;\n"                                      \
+  "@%r32 bra $L26;\n"                                                  \
+  "mov.u32 %r33,0;\n"                                                  \
+  "setp.eq.u32 %r34,%r28,%r33;\n"                                      \
+  "@!%r34 bra $L29;\n"                                                 \
+  "mov.u32 %r23,%nctaid.x;\n"                                          \
+  "mov.u32 %r22,%r23;\n"                                               \
+  "bra $L28;\n"                                                                \
+  "$L25:\n"                                                            \
+  "mov.u32 %r24,%nctaid.y;\n"                                          \
+  "mov.u32 %r22,%r24;\n"                                               \
+  "bra $L28;\n"                                                                \
+  "$L26:\n"                                                            \
+  "mov.u32 %r25,%nctaid.z;\n"                                          \
+  "mov.u32 %r22,%r25;\n"                                               \
+  "bra $L28;\n"                                                                \
+  "$L29:\n"                                                            \
+  "{\n"                                                                        \
+  "{\n"                                                                        \
+  "call abort;\n"                                                      \
+  "}\n"                                                                        \
+  "}\n"                                                                        \
+  "$L28:\n"                                                            \
+  "mov.u32 %r26,%r22;\n"                                               \
+  "mov.u32 %retval,%r26;\n"                                            \
+  "st.param.u32 [%out_retval],%retval;\n"                              \
+  "ret;\n"                                                             \
+  "}\n"                                                                        \
   ".visible .func (.param .u32 %out_retval) GOACC_get_num_threads\n"   \
   "{\n"                                                                        \
   ".reg .u32 %retval;\n"                                               \
index 73e757a..50baa4d 100644 (file)
@@ -919,7 +919,7 @@ static bool
 gomp_load_plugin_for_device (struct gomp_device_descr *device,
                             const char *plugin_name)
 {
-  char *err = NULL, *last_missing = NULL;
+  const char *err = NULL, *last_missing = NULL;
   int optional_present, optional_total;
 
   /* Clear any existing error.  */
@@ -947,7 +947,7 @@ gomp_load_plugin_for_device (struct gomp_device_descr *device,
 #define DLSYM_OPT(f, n)                                                \
   do                                                                   \
     {                                                                  \
-      char *tmp_err;                                                   \
+      const char *tmp_err;                                                     \
       device->f##_func = dlsym (plugin_handle, "GOMP_OFFLOAD_" #n);    \
       tmp_err = dlerror ();                                            \
       if (tmp_err == NULL)                                             \
index 11361bb..1dfc4ad 100644 (file)
@@ -530,9 +530,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _OIter 
     reverse_copy(_BIter, _BIter, _OIter);
 
-  template<typename _FIter>
-    _FIter
-    rotate(_FIter, _FIter, _FIter);
+  inline namespace _V2
+  {
+    template<typename _FIter>
+      _FIter
+      rotate(_FIter, _FIter, _FIter);
+  }
 
   template<typename _FIter, typename _OIter>
     _OIter 
index 71a47f5..3b2603f 100644 (file)
@@ -476,9 +476,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       {
        if (__str._M_is_local())
          {
-           if (__str.length())
-             traits_type::copy(_M_local_buf, __str._M_local_buf,
-                               _S_local_capacity + 1);
+           traits_type::copy(_M_local_buf, __str._M_local_buf,
+                             _S_local_capacity + 1);
          }
        else
          {
index c27c092..53c455b 100644 (file)
@@ -1237,6 +1237,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __m;
     }
 
+  inline namespace _V2
+  {
+
   /// This is a helper function for the rotate algorithm.
   template<typename _ForwardIterator>
     _ForwardIterator
@@ -1438,6 +1441,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                           std::__iterator_category(__first));
     }
 
+  } // namespace _V2
+
   /**
    *  @brief Copy a sequence, rotating its elements.
    *  @ingroup mutating_algorithms
index 594dae6..aebd3f3 100644 (file)
@@ -295,13 +295,10 @@ namespace
       {
        // Algorithm from http://www.unicode.org/faq/utf_bom.html#utf16-4
        const char32_t LEAD_OFFSET = 0xD800 - (0x10000 >> 10);
-       const char32_t SURROGATE_OFFSET = 0x10000 - (0xD800 << 10) - 0xDC00;
        char16_t lead = LEAD_OFFSET + (codepoint >> 10);
        char16_t trail = 0xDC00 + (codepoint & 0x3FF);
-       char32_t utf16bytes = (lead << 10) + trail + SURROGATE_OFFSET;
-
-       to.next[0] = adjust_byte_order(utf16bytes >> 16, mode);
-       to.next[1] = adjust_byte_order(utf16bytes & 0xFFFF, mode);
+       to.next[0] = adjust_byte_order(lead, mode);
+       to.next[1] = adjust_byte_order(trail, mode);
        to.next += 2;
        return true;
       }
@@ -400,7 +397,7 @@ namespace
          return codecvt_base::partial;
        if (codepoint > maxcode)
          return codecvt_base::error;
-       if (!write_utf16_code_point(to, codepoint, {}))
+       if (!write_utf16_code_point(to, codepoint, mode))
          {
            from.next = first;
            return codecvt_base::partial;
@@ -618,7 +615,12 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
 {
   range<const char> from{ __from, __from_end };
   range<char16_t> to{ __to, __to_end };
-  auto res = utf16_in(from, to);
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+  codecvt_mode mode = {};
+#else
+  codecvt_mode mode = little_endian;
+#endif
+  auto res = utf16_in(from, to, max_code_point, mode);
   __from_next = from.next;
   __to_next = to.next;
   return res;