Index: dumpfile.c
===================================================================
--- dumpfile.c  (revision 201461)
+++ dumpfile.c  (working copy)
@@ -257,16 +257,18 @@ dump_open_alternate_stream (struct dump_file_info
 void
 dump_loc (int dump_kind, FILE *dfile, source_location loc)
 {
-  /* Currently vectorization passes print location information.  */
   if (dump_kind)
     {
+      /* Ensure dump message starts on a new line.  */
+      fprintf (dfile, "\n");
       if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
-        fprintf (dfile, "\n%s:%d: note: ", LOCATION_FILE (loc),
-                 LOCATION_LINE (loc));
+        fprintf (dfile, "%s:%d:%d: note: ", LOCATION_FILE (loc),
+                 LOCATION_LINE (loc), LOCATION_COLUMN (loc));
       else if (current_function_decl)
-        fprintf (dfile, "\n%s:%d: note: ",
+        fprintf (dfile, "%s:%d:%d: note: ",
                  DECL_SOURCE_FILE (current_function_decl),
-                 DECL_SOURCE_LINE (current_function_decl));
+                 DECL_SOURCE_LINE (current_function_decl),
+                 DECL_SOURCE_COLUMN (current_function_decl));
     }
 }

Index: dumpfile.h
===================================================================
--- dumpfile.h  (revision 201461)
+++ dumpfile.h  (working copy)
@@ -97,8 +97,9 @@ enum tree_dump_index
 #define OPTGROUP_LOOP        (1 << 2)   /* Loop optimization passes */
 #define OPTGROUP_INLINE      (1 << 3)   /* Inlining passes */
 #define OPTGROUP_VEC         (1 << 4)   /* Vectorization passes */
+#define OPTGROUP_OTHER       (1 << 5)   /* All other passes */
 #define OPTGROUP_ALL        (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \
-                              | OPTGROUP_VEC)
+                              | OPTGROUP_VEC | OPTGROUP_OTHER)

 /* Define a tree dump switch.  */
 struct dump_file_info
Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c      (revision 201461)
+++ ipa-inline-transform.c      (working copy)
@@ -192,6 +192,108 @@ clone_inlined_nodes (struct cgraph_edge *e, bool d
 }


+#define MAX_INT_LENGTH 20
+
+/* Return NODE's name and profile count, if available.  */
+
+static const char *
+cgraph_node_opt_info (struct cgraph_node *node)
+{
+  char *buf;
+  size_t buf_size;
+  const char *bfd_name = lang_hooks.dwarf_name (node->symbol.decl, 0);
+
+  if (!bfd_name)
+    bfd_name = "unknown";
+
+  buf_size = strlen (bfd_name) + 1;
+  if (profile_info)
+    buf_size += (MAX_INT_LENGTH + 3);
+
+  buf = (char *) xmalloc (buf_size);
+
+  strcpy (buf, bfd_name);
+
+  if (profile_info)
+    sprintf (buf, "%s ("HOST_WIDEST_INT_PRINT_DEC")", buf, node->count);
+  return buf;
+}
+
+
+/* Return CALLER's inlined call chain. Save the cgraph_node of the ultimate
+   function that the caller is inlined to in FINAL_CALLER.  */
+
+static const char *
+cgraph_node_call_chain (struct cgraph_node *caller,
+                       struct cgraph_node **final_caller)
+{
+  struct cgraph_node *node;
+  const char *via_str = " (via inline instance";
+  size_t current_string_len = strlen (via_str) + 1;
+  size_t buf_size = current_string_len;
+  char *buf = (char *) xmalloc (buf_size);
+
+  buf[0] = 0;
+  gcc_assert (caller->global.inlined_to != NULL);
+  strcat (buf, via_str);
+  for (node = caller; node->global.inlined_to != NULL;
+       node = node->callers->caller)
+    {
+      const char *name = cgraph_node_opt_info (node);
+      current_string_len += (strlen (name) + 1);
+      if (current_string_len >= buf_size)
+       {
+         buf_size = current_string_len * 2;
+         buf = (char *) xrealloc (buf, buf_size);
+       }
+      strcat (buf, " ");
+      strcat (buf, name);
+    }
+  strcat (buf, ")");
+  *final_caller = node;
+  return buf;
+}
+
+
+/* Dump the inline decision of EDGE.  */
+
+static void
+dump_inline_decision (struct cgraph_edge *edge)
+{
+  location_t locus;
+  const char *inline_chain_text;
+  const char *call_count_text;
+  struct cgraph_node *final_caller = edge->caller;
+
+  if (final_caller->global.inlined_to != NULL)
+    inline_chain_text = cgraph_node_call_chain (final_caller, &final_caller);
+  else
+    inline_chain_text = "";
+
+  if (edge->count > 0)
+    {
+      const char *call_count_str = " with call count ";
+      char *buf = (char *) xmalloc (strlen (call_count_str) + MAX_INT_LENGTH);
+      sprintf (buf, "%s"HOST_WIDEST_INT_PRINT_DEC, call_count_str,
+              edge->count);
+      call_count_text = buf;
+    }
+  else
+    {
+      call_count_text = "";
+    }
+
+  locus = gimple_location (edge->call_stmt);
+  dump_printf_loc (is_in_ipa_inline ? MSG_OPTIMIZED_LOCATIONS : MSG_NOTE,
+                   locus,
+                   "%s inlined into %s%s%s\n",
+                   cgraph_node_opt_info (edge->callee),
+                   cgraph_node_opt_info (final_caller),
+                   call_count_text,
+                   inline_chain_text);
+}
+
+
 /* Mark edge E as inlined and update callgraph accordingly.  UPDATE_ORIGINAL
    specify whether profile of original function should be updated.  If any new
    indirect edges are discovered in the process, add them to NEW_EDGES, unless
@@ -218,6 +320,9 @@ inline_call (struct cgraph_edge *e, bool update_or
   bool predicated = inline_edge_summary (e)->predicate != NULL;
 #endif

+  if (dump_enabled_p ())
+    dump_inline_decision (e);
+
   /* Don't inline inlined edges.  */
   gcc_assert (e->inline_failed);
   /* Don't even think of inlining inline clone.  */
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi     (revision 201461)
+++ doc/invoke.texi     (working copy)
@@ -6234,6 +6234,9 @@ Enable dumps from all loop optimizations.
 Enable dumps from all inlining optimizations.
 @item vec
 Enable dumps from all vectorization optimizations.
+@item optall
+Enable dumps from all optimizations. This is a superset of
+the optimization groups listed above.
 @end table

 For example,
Index: profile.c
===================================================================
--- profile.c   (revision 201461)
+++ profile.c   (working copy)
@@ -432,8 +432,8 @@ read_profile_edge_counts (gcov_type *exec_counts)
                    if (flag_profile_correction)
                      {
                        static bool informed = 0;
-                       if (!informed)
-                         inform (input_location,
+                       if (dump_enabled_p () && !informed)
+                         dump_printf_loc (MSG_NOTE, input_location,
                                  "corrupted profile info: edge count
exceeds maximal count");
                        informed = 1;
                      }
@@ -692,10 +692,11 @@ compute_branch_probabilities (unsigned cfg_checksu
        {
          /* Inconsistency detected. Make it flow-consistent. */
          static int informed = 0;
-         if (informed == 0)
+         if (dump_enabled_p () && informed == 0)
            {
              informed = 1;
-             inform (input_location, "correcting inconsistent profile data");
+             dump_printf_loc (MSG_NOTE, input_location,
+                              "correcting inconsistent profile data");
            }
          correct_negative_edge_counts ();
          /* Set bb counts to the sum of the outgoing edge counts */
Index: passes.c
===================================================================
--- passes.c    (revision 201461)
+++ passes.c    (working copy)
@@ -524,6 +524,11 @@ pass_manager::register_one_dump_file (struct opt_p
   flag_name = concat (prefix, name, num, NULL);
   glob_name = concat (prefix, name, NULL);
   optgroup_flags |= pass->optinfo_flags;
+  /* For any passes that do not have an optgroup set, and which are not
+     IPA passes setup above, set the optgroup to OPTGROUP_OTHER so that
+     any dump messages are emitted properly under -fopt-info(-optall).  */
+  if (optgroup_flags == OPTGROUP_NONE)
+    optgroup_flags = OPTGROUP_OTHER;
   id = dump_register (dot_name, flag_name, glob_name, flags, optgroup_flags);
   set_pass_for_id (id, pass);
   full_name = concat (prefix, pass->name, num, NULL);
Index: value-prof.c
===================================================================
--- value-prof.c        (revision 201461)
+++ value-prof.c        (working copy)
@@ -585,9 +585,11 @@ check_counter (gimple stmt, const char * name,
               : DECL_SOURCE_LOCATION (current_function_decl);
       if (flag_profile_correction)
         {
-         inform (locus, "correcting inconsistent value profile: "
-                 "%s profiler overall count (%d) does not match BB count "
-                  "(%d)", name, (int)*all, (int)bb_count);
+          if (dump_enabled_p ())
+            dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
+                             "correcting inconsistent value profile: %s "
+                             "profiler overall count (%d) does not match BB "
+                             "count (%d)", name, (int)*all, (int)bb_count);
          *all = bb_count;
          if (*count > *all)
             *count = *all;
@@ -1209,9 +1211,11 @@ find_func_by_funcdef_no (int func_id)
   int max_id = get_last_funcdef_no ();
   if (func_id >= max_id || cgraph_node_map[func_id] == NULL)
     {
-      if (flag_profile_correction)
-        inform (DECL_SOURCE_LOCATION (current_function_decl),
-                "Inconsistent profile: indirect call target (%d) does
not exist", func_id);
+      if (flag_profile_correction && dump_enabled_p ())
+        dump_printf_loc (MSG_MISSED_OPTIMIZATION,
+                         DECL_SOURCE_LOCATION (current_function_decl),
+                         "Inconsistent profile: indirect call target (%d) "
+                         "does not exist", func_id);
       else
         error ("Inconsistent profile: indirect call target (%d) does
not exist", func_id);

@@ -1235,8 +1239,10 @@ check_ic_target (gimple call_stmt, struct cgraph_n
      return true;

    locus =  gimple_location (call_stmt);
-   inform (locus, "Skipping target %s with mismatching types for icall ",
-           cgraph_node_name (target));
+   if (dump_enabled_p ())
+     dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
+                      "Skipping target %s with mismatching types for icall ",
+                      cgraph_node_name (target));
    return false;
 }

Index: coverage.c
===================================================================
--- coverage.c  (revision 201461)
+++ coverage.c  (working copy)
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "hash-table.h"
 #include "tree-iterator.h"
+#include "tree-pass.h"
 #include "cgraph.h"
 #include "dumpfile.h"
 #include "diagnostic-core.h"
@@ -341,11 +342,13 @@ get_coverage_counts (unsigned counter, unsigned ex
     {
       static int warned = 0;

-      if (!warned++)
-       inform (input_location, (flag_guess_branch_prob
-                ? "file %s not found, execution counts estimated"
-                : "file %s not found, execution counts assumed to be zero"),
-               da_file_name);
+      if (!warned++ && dump_enabled_p ())
+       dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+                         (flag_guess_branch_prob
+                          ? "file %s not found, execution counts estimated"
+                          : "file %s not found, execution counts assumed to "
+                            "be zero"),
+                         da_file_name);
       return NULL;
     }

@@ -369,21 +372,25 @@ get_coverage_counts (unsigned counter, unsigned ex
        warning_at (input_location, OPT_Wcoverage_mismatch,
                    "the control flow of function %qE does not match "
                    "its profile data (counter %qs)", id, ctr_names[counter]);
-      if (warning_printed)
+      if (warning_printed && dump_enabled_p ())
        {
-        inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
-                "the mismatch but performance may drop if the
function is hot");
+          dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+                           "use -Wno-error=coverage-mismatch to tolerate "
+                           "the mismatch but performance may drop if the "
+                           "function is hot");

          if (!seen_error ()
              && !warned++)
            {
-             inform (input_location, "coverage mismatch ignored");
-             inform (input_location, flag_guess_branch_prob
-                     ? G_("execution counts estimated")
-                     : G_("execution counts assumed to be zero"));
+             dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+                               "coverage mismatch ignored");
+             dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+                               flag_guess_branch_prob
+                               ? G_("execution counts estimated")
+                               : G_("execution counts assumed to be zero"));
              if (!flag_guess_branch_prob)
-               inform (input_location,
-                       "this can result in poorly optimized code");
+               dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+                                 "this can result in poorly optimized code");
            }
        }

@@ -1103,6 +1110,11 @@ coverage_init (const char *filename)
   int len = strlen (filename);
   int prefix_len = 0;

+  /* Since coverage_init is invoked very early, before the pass
+     manager, we need to set up the dumping explicitly. This is
+     similar to the handling in finish_optimization_passes.  */
+  dump_start (pass_profile.pass.static_pass_number, NULL);
+
   if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
     profile_data_prefix = getpwd ();

@@ -1145,6 +1157,8 @@ coverage_init (const char *filename)
          gcov_write_unsigned (bbg_file_stamp);
        }
     }
+
+  dump_finish (pass_profile.pass.static_pass_number);
 }

 /* Performs file-level cleanup.  Close notes file, generate coverage
Index: ipa-inline.c
===================================================================
--- ipa-inline.c        (revision 201461)
+++ ipa-inline.c        (working copy)
@@ -118,6 +118,9 @@ along with GCC; see the file COPYING3.  If not see
 static int overall_size;
 static gcov_type max_count;

+/* Global variable to denote if it is in ipa-inline pass. */
+bool is_in_ipa_inline = false;
+
 /* Return false when inlining edge E would lead to violating
    limits on function unit growth or stack usage growth.

@@ -1407,6 +1410,8 @@ inline_small_functions (void)
   int initial_size = 0;
   struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);

+  is_in_ipa_inline = true;
+
   if (flag_indirect_inlining)
     new_indirect_edges.create (8);

Index: ipa-inline.h
===================================================================
--- ipa-inline.h        (revision 201461)
+++ ipa-inline.h        (working copy)
@@ -234,6 +234,7 @@ void clone_inlined_nodes (struct cgraph_edge *e, b

 extern int ncalls_inlined;
 extern int nfunctions_inlined;
+extern bool is_in_ipa_inline;

 static inline struct inline_summary *
 inline_summary (struct cgraph_node *node)
Index: testsuite/gcc.dg/pr40209.c
===================================================================
--- testsuite/gcc.dg/pr40209.c  (revision 201461)
+++ testsuite/gcc.dg/pr40209.c  (working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fprofile-use" } */
+/* { dg-options "-O2 -fprofile-use -fopt-info" } */

 void process(const char *s);

Index: testsuite/gcc.dg/pr26570.c
===================================================================
--- testsuite/gcc.dg/pr26570.c  (revision 201461)
+++ testsuite/gcc.dg/pr26570.c  (working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fprofile-generate -fprofile-use" } */
+/* { dg-options "-O2 -fprofile-generate -fprofile-use -fopt-info" } */

 unsigned test (unsigned a, unsigned b)
 {
Index: testsuite/gcc.dg/pr32773.c
===================================================================
--- testsuite/gcc.dg/pr32773.c  (revision 201461)
+++ testsuite/gcc.dg/pr32773.c  (working copy)
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-O -fprofile-use" } */
-/* { dg-options "-O -m4 -fprofile-use" { target sh-*-* } } */
+/* { dg-options "-O -fprofile-use -fopt-info" } */
+/* { dg-options "-O -m4 -fprofile-use -fopt-info" { target sh-*-* } } */

 void foo (int *p)
 {
Index: testsuite/g++.dg/tree-ssa/dom-invalid.C
===================================================================
--- testsuite/g++.dg/tree-ssa/dom-invalid.C     (revision 201461)
+++ testsuite/g++.dg/tree-ssa/dom-invalid.C     (working copy)
@@ -1,7 +1,7 @@
 // PR tree-optimization/39557
 // invalid post-dom info leads to infinite loop
 // { dg-do run }
-// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fno-rtti" }
+// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fopt-info
-fno-rtti" }

 struct C
 {
