OSDN Git Service

compiler: Sort array constructors by index.
[pf3gnuchains/gcc-fork.git] / gcc / ipa-inline.c
index 14bd89a..b4a32c1 100644 (file)
@@ -220,8 +220,8 @@ report_inline_failed_reason (struct cgraph_edge *e)
   if (dump_file)
     {
       fprintf (dump_file, "  not inlinable: %s/%i -> %s/%i, %s\n",
-              cgraph_node_name (e->caller), e->caller->uid,
-              cgraph_node_name (e->callee), e->callee->uid,
+              xstrdup (cgraph_node_name (e->caller)), e->caller->uid,
+              xstrdup (cgraph_node_name (e->callee)), e->callee->uid,
               cgraph_inline_failed_string (e->inline_failed));
     }
 }
@@ -284,10 +284,10 @@ can_inline_edge_p (struct cgraph_edge *e, bool report)
       e->inline_failed = CIF_EH_PERSONALITY;
       inlinable = false;
     }
-  /* TM pure functions should not get inlined if the outer function is
-     a TM safe function.  */
+  /* TM pure functions should not be inlined into non-TM_pure
+     functions.  */
   else if (is_tm_pure (callee->decl)
-          && is_tm_safe (e->caller->decl))
+          && !is_tm_pure (e->caller->decl))
     {
       e->inline_failed = CIF_UNSPECIFIED;
       inlinable = false;
@@ -423,8 +423,8 @@ want_early_inline_function_p (struct cgraph_edge *e)
          if (dump_file)
            fprintf (dump_file, "  will not early inline: %s/%i->%s/%i, "
                     "call is cold and code would grow by %i\n",
-                    cgraph_node_name (e->caller), e->caller->uid,
-                    cgraph_node_name (callee), callee->uid,
+                    xstrdup (cgraph_node_name (e->caller)), e->caller->uid,
+                    xstrdup (cgraph_node_name (callee)), callee->uid,
                     growth);
          want_inline = false;
        }
@@ -434,8 +434,8 @@ want_early_inline_function_p (struct cgraph_edge *e)
          if (dump_file)
            fprintf (dump_file, "  will not early inline: %s/%i->%s/%i, "
                     "callee is not leaf and code would grow by %i\n",
-                    cgraph_node_name (e->caller), e->caller->uid,
-                    cgraph_node_name (callee), callee->uid,
+                    xstrdup (cgraph_node_name (e->caller)), e->caller->uid,
+                    xstrdup (cgraph_node_name (callee)), callee->uid,
                     growth);
          want_inline = false;
        }
@@ -444,8 +444,8 @@ want_early_inline_function_p (struct cgraph_edge *e)
          if (dump_file)
            fprintf (dump_file, "  will not early inline: %s/%i->%s/%i, "
                     "growth %i exceeds --param early-inlining-insns\n",
-                    cgraph_node_name (e->caller), e->caller->uid,
-                    cgraph_node_name (callee), callee->uid,
+                    xstrdup (cgraph_node_name (e->caller)), e->caller->uid,
+                    xstrdup (cgraph_node_name (callee)), callee->uid,
                     growth);
          want_inline = false;
        }
@@ -482,21 +482,13 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
           e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
          want_inline = false;
        }
-      else if (!DECL_DECLARED_INLINE_P (callee->decl)
-              && !flag_inline_functions)
-       {
-          e->inline_failed = CIF_NOT_DECLARED_INLINED;
-         want_inline = false;
-       }
-      else if (!DECL_DECLARED_INLINE_P (callee->decl)
-              && growth >= MAX_INLINE_INSNS_AUTO)
-       {
-          e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
-         want_inline = false;
-       }
-      /* If call is cold, do not inline when function body would grow.
-        Still inline when the overall unit size will shrink because the offline
-        copy of function being eliminated.
+      /* Before giving up based on fact that caller size will grow, allow
+         functions that are called few times and eliminating the offline
+        copy will lead to overall code size reduction.
+        Not all of these will be handled by subsequent inlining of functions
+        called once: in particular weak functions are not handled or funcitons
+        that inline to multiple calls but a lot of bodies is optimized out.
+        Finally we want to inline earlier to allow inlining of callbacks.
 
         This is slightly wrong on aggressive side:  it is entirely possible
         that function is called many times with a context where inlining
@@ -509,24 +501,37 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
         first, this situation is not a problem at all: after inlining all
         "good" calls, we will realize that keeping the function around is
         better.  */
-      else if (!cgraph_maybe_hot_edge_p (e)
-              && (DECL_EXTERNAL (callee->decl)
-
-                  /* Unlike for functions called once, we play unsafe with
-                     COMDATs.  We can allow that since we know functions
-                     in consideration are small (and thus risk is small) and
-                     moreover grow estimates already accounts that COMDAT
-                     functions may or may not disappear when eliminated from
-                     current unit. With good probability making aggressive
-                     choice in all units is going to make overall program
-                     smaller.
-
-                     Consequently we ask cgraph_can_remove_if_no_direct_calls_p
-                     instead of
-                     cgraph_will_be_removed_from_program_if_no_direct_calls  */
-
-                  || !cgraph_can_remove_if_no_direct_calls_p (callee)
-                  || estimate_growth (callee) > 0))
+      else if (growth <= MAX_INLINE_INSNS_SINGLE
+              /* Unlike for functions called once, we play unsafe with
+                 COMDATs.  We can allow that since we know functions
+                 in consideration are small (and thus risk is small) and
+                 moreover grow estimates already accounts that COMDAT
+                 functions may or may not disappear when eliminated from
+                 current unit. With good probability making aggressive
+                 choice in all units is going to make overall program
+                 smaller.
+
+                 Consequently we ask cgraph_can_remove_if_no_direct_calls_p
+                 instead of
+                 cgraph_will_be_removed_from_program_if_no_direct_calls  */
+               && !DECL_EXTERNAL (callee->decl)
+               && cgraph_can_remove_if_no_direct_calls_p (callee)
+               && estimate_growth (callee) <= 0)
+       ;
+      else if (!DECL_DECLARED_INLINE_P (callee->decl)
+              && !flag_inline_functions)
+       {
+          e->inline_failed = CIF_NOT_DECLARED_INLINED;
+         want_inline = false;
+       }
+      else if (!DECL_DECLARED_INLINE_P (callee->decl)
+              && growth >= MAX_INLINE_INSNS_AUTO)
+       {
+          e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
+         want_inline = false;
+       }
+      /* If call is cold, do not inline when function body would grow. */
+      else if (!cgraph_maybe_hot_edge_p (e))
        {
           e->inline_failed = CIF_UNLIKELY_CALL;
          want_inline = false;
@@ -749,8 +754,8 @@ edge_badness (struct cgraph_edge *edge, bool dump)
   if (dump)
     {
       fprintf (dump_file, "    Badness calculation for %s -> %s\n",
-              cgraph_node_name (edge->caller),
-              cgraph_node_name (callee));
+              xstrdup (cgraph_node_name (edge->caller)),
+              xstrdup (cgraph_node_name (callee)));
       fprintf (dump_file, "      size growth %i, time growth %i\n",
               growth,
               time_growth);
@@ -905,8 +910,10 @@ update_edge_key (fibheap_t heap, struct cgraph_edge *edge)
            {
              fprintf (dump_file,
                       "  decreasing badness %s/%i -> %s/%i, %i to %i\n",
-                      cgraph_node_name (edge->caller), edge->caller->uid,
-                      cgraph_node_name (edge->callee), edge->callee->uid,
+                      xstrdup (cgraph_node_name (edge->caller)),
+                      edge->caller->uid,
+                      xstrdup (cgraph_node_name (edge->callee)),
+                      edge->callee->uid,
                       (int)n->key,
                       badness);
            }
@@ -920,8 +927,10 @@ update_edge_key (fibheap_t heap, struct cgraph_edge *edge)
         {
           fprintf (dump_file,
                    "  enqueuing call %s/%i -> %s/%i, badness %i\n",
-                   cgraph_node_name (edge->caller), edge->caller->uid,
-                   cgraph_node_name (edge->callee), edge->callee->uid,
+                   xstrdup (cgraph_node_name (edge->caller)),
+                   edge->caller->uid,
+                   xstrdup (cgraph_node_name (edge->callee)),
+                   edge->callee->uid,
                    badness);
         }
       edge->aux = fibheap_insert (heap, badness, edge);
@@ -1603,8 +1612,8 @@ flatten_function (struct cgraph_node *node, bool early)
          if (dump_file)
            fprintf (dump_file,
                     "Not inlining %s into %s to avoid cycle.\n",
-                    cgraph_node_name (callee),
-                    cgraph_node_name (e->caller));
+                    xstrdup (cgraph_node_name (callee)),
+                    xstrdup (cgraph_node_name (e->caller)));
          e->inline_failed = CIF_RECURSIVE_INLINING;
          continue;
        }
@@ -1644,8 +1653,8 @@ flatten_function (struct cgraph_node *node, bool early)
          recursing through the original node if the node was cloned.  */
       if (dump_file)
        fprintf (dump_file, " Inlining %s into %s.\n",
-                cgraph_node_name (callee),
-                cgraph_node_name (e->caller));
+                xstrdup (cgraph_node_name (callee)),
+                xstrdup (cgraph_node_name (e->caller)));
       orig_callee = callee;
       inline_call (e, true, NULL, NULL);
       if (e->callee != orig_callee)
@@ -1747,7 +1756,8 @@ ipa_inline (void)
                    {
                      fprintf (dump_file,
                               "\nInlining %s size %i.\n",
-                              cgraph_node_name (node), inline_summary (node)->size);
+                              cgraph_node_name (node),
+                              inline_summary (node)->size);
                      fprintf (dump_file,
                               " Called once from %s %i insns.\n",
                               cgraph_node_name (node->callers->caller),
@@ -1810,8 +1820,8 @@ inline_always_inline_functions (struct cgraph_node *node)
 
       if (dump_file)
        fprintf (dump_file, "  Inlining %s into %s (always_inline).\n",
-                cgraph_node_name (e->callee),
-                cgraph_node_name (e->caller));
+                xstrdup (cgraph_node_name (e->callee)),
+                xstrdup (cgraph_node_name (e->caller)));
       inline_call (e, true, NULL, NULL);
       inlined = true;
     }
@@ -1860,8 +1870,8 @@ early_inline_small_functions (struct cgraph_node *node)
 
       if (dump_file)
        fprintf (dump_file, " Inlining %s into %s.\n",
-                cgraph_node_name (callee),
-                cgraph_node_name (e->caller));
+                xstrdup (cgraph_node_name (callee)),
+                xstrdup (cgraph_node_name (e->caller)));
       inline_call (e, true, NULL, NULL);
       inlined = true;
     }