Index: gcc/value-prof.c
===================================================================
--- gcc/value-prof.c	(revision 180106)
+++ gcc/value-prof.c	(working copy)
@@ -472,9 +472,10 @@
               : 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 (flag_opt_info >= OPT_INFO_MAX)
+            inform (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;
@@ -510,33 +511,42 @@
   location_t locus;
   if (*count1 > all && flag_profile_correction)
     {
-      locus = (stmt != NULL)
-              ? gimple_location (stmt)
-              : DECL_SOURCE_LOCATION (current_function_decl);
-      inform (locus, "Correcting inconsistent value profile: "
-              "ic (topn) profiler top target count (%ld) exceeds "
-	      "BB count (%ld)", (long)*count1, (long)all);
+      if (flag_opt_info >= OPT_INFO_MAX)
+        {
+          locus = (stmt != NULL)
+                  ? gimple_location (stmt)
+                  : DECL_SOURCE_LOCATION (current_function_decl);
+          inform (locus, "Correcting inconsistent value profile: "
+                  "ic (topn) profiler top target count (%ld) exceeds "
+                  "BB count (%ld)", (long)*count1, (long)all);
+        }
       *count1 = all;
     }
   if (*count2 > all && flag_profile_correction)
     {
-      locus = (stmt != NULL)
-              ? gimple_location (stmt)
-              : DECL_SOURCE_LOCATION (current_function_decl);
-      inform (locus, "Correcting inconsistent value profile: "
-              "ic (topn) profiler second target count (%ld) exceeds "
-	      "BB count (%ld)", (long)*count2, (long)all);
+      if (flag_opt_info >= OPT_INFO_MAX)
+        {
+          locus = (stmt != NULL)
+                  ? gimple_location (stmt)
+                  : DECL_SOURCE_LOCATION (current_function_decl);
+          inform (locus, "Correcting inconsistent value profile: "
+                  "ic (topn) profiler second target count (%ld) exceeds "
+    	          "BB count (%ld)", (long)*count2, (long)all);
+        }
       *count2 = all;
     }
   
   if (*count2 > *count1)
     {
-      locus = (stmt != NULL)
-              ? gimple_location (stmt)
-              : DECL_SOURCE_LOCATION (current_function_decl);
-      inform (locus, "Corrupted topn ic value profile: "
-	      "first target count (%ld) is less than the second "
-	      "target count (%ld)", (long)*count1, (long)*count2);
+      if (flag_opt_info >= OPT_INFO_MAX)
+        {
+          locus = (stmt != NULL)
+                  ? gimple_location (stmt)
+                  : DECL_SOURCE_LOCATION (current_function_decl);
+          inform (locus, "Corrupted topn ic value profile: "
+    	          "first target count (%ld) is less than the second "
+    	          "target count (%ld)", (long)*count1, (long)*count2);
+        }
       return true;
     }
 
@@ -548,12 +558,16 @@
 	*count2 = all - *count1;
       else
 	{
-	  locus = (stmt != NULL)
-	    ? gimple_location (stmt)
-	    : DECL_SOURCE_LOCATION (current_function_decl);
-	  inform (locus, "Corrupted topn ic value profile: top two targets's"
-		  " total count (%ld) exceeds bb count (%ld)",
-		  (long)(*count1 + *count2), (long)all);
+          if (flag_opt_info >= OPT_INFO_MAX)
+            {
+	      locus = (stmt != NULL)
+	        ? gimple_location (stmt)
+	        : DECL_SOURCE_LOCATION (current_function_decl);
+	      inform (locus,
+                      "Corrupted topn ic value profile: top two targets's"
+                      " total count (%ld) exceeds bb count (%ld)",
+                      (long)(*count1 + *count2), (long)all);
+            }
 	  return true;
 	}
     }
@@ -1177,8 +1191,11 @@
                                       func_id) == NULL)
     {
       if (flag_profile_correction)
-        inform (DECL_SOURCE_LOCATION (current_function_decl),
+        {
+          if (flag_opt_info >= OPT_INFO_MED)
+            inform (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);
 
@@ -1308,8 +1325,9 @@
      return true;
 
    locus =  gimple_location (call_stmt);
-   inform (locus, "Skipping target %s with mismatching types for icall ",
-           cgraph_node_name (target));
+   if (flag_opt_info >= OPT_INFO_MAX)
+     inform (locus, "Skipping target %s with mismatching types for icall ",
+             cgraph_node_name (target));
    return false;
 }
 
@@ -1571,7 +1589,7 @@
   if (direct_call1 == NULL
       || !check_ic_target (stmt, direct_call1))
     {
-      if (flag_ripa_verbose)
+      if (flag_opt_info >= OPT_INFO_MAX)
         {
           if (!direct_call1)
             inform (locus, "Can not find indirect call target decl "
@@ -1597,7 +1615,7 @@
     return false;
 
   modify1 = gimple_ic (stmt, direct_call1, prob1, count1, all);
-  if (flag_ripa_verbose)
+  if (flag_opt_info >= OPT_INFO_MIN)
     inform (locus, "Promote indirect call to target (call count:%u) %s",
 	    (unsigned) count1,
 	    lang_hooks.decl_printable_name (direct_call1->decl, 3));
@@ -1635,7 +1653,7 @@
       modify2 = gimple_ic (stmt, direct_call2,
                            prob2, count2, all - count1);
 
-      if (flag_ripa_verbose)
+      if (flag_opt_info >= OPT_INFO_MIN)
 	inform (locus, "Promote indirect call to target (call count:%u) %s",
 		(unsigned) count2,
 		lang_hooks.decl_printable_name (direct_call2->decl, 3));
Index: gcc/mcf.c
===================================================================
--- gcc/mcf.c	(revision 180106)
+++ gcc/mcf.c	(working copy)
@@ -1442,7 +1442,8 @@
       if (iteration > MAX_ITER (fixup_graph->num_vertices,
                                 fixup_graph->num_edges))
 	{
-	  inform (DECL_SOURCE_LOCATION (current_function_decl),
+          if (flag_opt_info >= OPT_INFO_MAX)
+            inform (DECL_SOURCE_LOCATION (current_function_decl),
 		  "Exiting profile correction early to avoid excessive "
 		  "compile time");
 	  break;
Index: gcc/testsuite/gcc.dg/pr32773.c
===================================================================
--- gcc/testsuite/gcc.dg/pr32773.c	(revision 180106)
+++ gcc/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: gcc/testsuite/gcc.dg/pr40209.c
===================================================================
--- gcc/testsuite/gcc.dg/pr40209.c	(revision 180106)
+++ gcc/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: gcc/testsuite/gcc.dg/pr26570.c
===================================================================
--- gcc/testsuite/gcc.dg/pr26570.c	(revision 180106)
+++ gcc/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: gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C
===================================================================
--- gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C	(revision 180106)
+++ gcc/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
 {
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 180106)
+++ gcc/opts.c	(working copy)
@@ -1579,6 +1579,15 @@
       pp_set_line_maximum_length (dc->printer, value);
       break;
 
+    case OPT_fopt_info_:
+      if (value < 0 || value > OPT_INFO_MAX)
+	error_at (loc,
+		  "%d: invalid value for opt_info",
+		  value);
+      else
+	opts->x_flag_opt_info = value;
+      break;
+
     case OPT_fpack_struct_:
       if (value <= 0 || (value & (value - 1)) || value > 16)
 	error_at (loc,
Index: gcc/profile.c
===================================================================
--- gcc/profile.c	(revision 180106)
+++ gcc/profile.c	(working copy)
@@ -414,7 +414,7 @@
 		    if (flag_profile_correction)
 		      {
 			static bool informed = 0;
-			if (!informed)
+			if ((flag_opt_info >= OPT_INFO_MAX) && !informed)
 		          inform (input_location,
 			          "corrupted profile info: edge count exceeds maximal count");
 			informed = 1;
@@ -635,7 +635,7 @@
        {
          /* Inconsistency detected. Make it flow-consistent. */
          static int informed = 0;
-         if (informed == 0)
+         if ((flag_opt_info >= OPT_INFO_MAX) && informed == 0)
            {
              informed = 1;
              inform (input_location, "correcting inconsistent profile data");
Index: gcc/flag-types.h
===================================================================
--- gcc/flag-types.h	(revision 180106)
+++ gcc/flag-types.h	(working copy)
@@ -204,4 +204,11 @@
   MAX_VERBOSITY_LEVEL
 };
 
+/* flag_opt_info verbosity levels.  */
+enum opt_info_verbosity_levels {
+  OPT_INFO_NONE = 0,
+  OPT_INFO_MIN  = 1,
+  OPT_INFO_MED  = 2,
+  OPT_INFO_MAX  = 3
+};
 #endif /* ! GCC_FLAG_TYPES_H */
Index: gcc/coverage.c
===================================================================
--- gcc/coverage.c	(revision 180106)
+++ gcc/coverage.c	(working copy)
@@ -355,7 +355,8 @@
     warning (OPT_Wripa_opt_mismatch, "command line arguments mismatch for %s "
 	     "and %s", mod_info1->source_filename, mod_info2->source_filename);
 
-   if (warn_ripa_opt_mismatch && non_warning_mismatch && flag_ripa_verbose)
+   if (warn_ripa_opt_mismatch && non_warning_mismatch 
+       && (flag_opt_info >= OPT_INFO_MED))
      {
        inform (UNKNOWN_LOCATION, "Options for %s", mod_info1->source_filename);
        for (i = 0; i < num_non_warning_opts1; i++)
@@ -575,29 +576,47 @@
 	      int fd;
 	      char *aux_da_filename = get_da_file_name (mod_info->da_filename);
               gcc_assert (!mod_info->is_primary);
-	      if (pointer_set_insert (modset, (void *)(size_t)mod_info->ident))
-		inform (input_location, "Not importing %s: already imported",
-			mod_info->source_filename);
-	      else if ((module_infos[0]->lang & GCOV_MODULE_LANG_MASK) !=
-		       (mod_info->lang & GCOV_MODULE_LANG_MASK))
-		inform (input_location, "Not importing %s: source language"
-			" different from primary module's source language",
-			mod_info->source_filename);
-	      else if (module_infos_read == max_group)
-		inform (input_location, "Not importing %s: maximum group size"
-			" reached", mod_info->source_filename);
-	      else if (incompatible_cl_args (module_infos[0], mod_info))
-		inform (input_location, "Not importing %s: command-line"
-			" arguments not compatible with primary module",
-			mod_info->source_filename);
-	      else if ((fd = open (aux_da_filename, O_RDONLY)) < 0)
-		inform (input_location, "Not importing %s: couldn't open %s",
-			mod_info->source_filename, aux_da_filename);
-	      else if ((mod_info->lang & GCOV_MODULE_ASM_STMTS)
-		       && flag_ripa_disallow_asm_modules)
-		inform (input_location, "Not importing %s: contains assembler"
-			" statements", mod_info->source_filename);
-	      else
+              if (pointer_set_insert (modset, (void *)(size_t)mod_info->ident))
+                {
+                  if (flag_opt_info >= OPT_INFO_MAX)
+                    inform (input_location, "Not importing %s: already imported",
+                            mod_info->source_filename);
+                }
+              else if ((module_infos[0]->lang & GCOV_MODULE_LANG_MASK) !=
+                       (mod_info->lang & GCOV_MODULE_LANG_MASK))
+                {
+                  if (flag_opt_info >= OPT_INFO_MAX)
+                    inform (input_location, "Not importing %s: source language"
+                            " different from primary module's source language",
+                            mod_info->source_filename);
+                }
+              else if (module_infos_read == max_group)
+                {
+                  if (flag_opt_info >= OPT_INFO_MAX)
+                    inform (input_location, "Not importing %s: maximum group"
+                            " size reached", mod_info->source_filename);
+                }
+              else if (incompatible_cl_args (module_infos[0], mod_info))
+                {
+                  if (flag_opt_info >= OPT_INFO_MAX)
+                    inform (input_location, "Not importing %s: command-line"
+                            " arguments not compatible with primary module",
+                            mod_info->source_filename);
+                }
+              else if ((fd = open (aux_da_filename, O_RDONLY)) < 0)
+                {
+                  if (flag_opt_info >= OPT_INFO_MAX)
+                    inform (input_location, "Not importing %s: couldn't open %s",
+                            mod_info->source_filename, aux_da_filename);
+                }
+              else if ((mod_info->lang & GCOV_MODULE_ASM_STMTS)
+                       && flag_ripa_disallow_asm_modules)
+                {
+                  if (flag_opt_info >= OPT_INFO_MAX)
+                    inform (input_location, "Not importing %s: contains "
+                            "assembler statements", mod_info->source_filename);
+                }
+              else
 		{
 		  close (fd);
 		  module_infos_read++;
@@ -612,7 +631,7 @@
 		}
             }
 
-          if (flag_ripa_verbose)
+          if (flag_opt_info >= OPT_INFO_MAX)
             {
               inform (input_location,
                       "MODULE Id=%d, Is_Primary=%s,"
@@ -676,7 +695,7 @@
     {
       static int warned = 0;
 
-      if (!warned++)
+      if ((flag_opt_info >= OPT_INFO_MIN) && !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"),
@@ -688,7 +707,7 @@
 
   if (!entry)
     {
-      if (!flag_dyn_ipa)
+      if ((flag_opt_info >= OPT_INFO_MIN) && !flag_dyn_ipa)
 	warning (0, "no coverage for function %qE found",
 		 DECL_ASSEMBLER_NAME (current_function_decl));
       return NULL;
@@ -705,7 +724,7 @@
 	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 ((flag_opt_info >= OPT_INFO_MIN) && warning_printed)
 	{
 	 inform (input_location, "Use -Wno-error=coverage-mismatch to tolerate "
 	 	 "the mismatch but performance may drop if the function is hot");
@@ -727,7 +746,8 @@
     }
     else if (entry->lineno_checksum != lineno_checksum)
       {
-        warning (0, "Source location for function %qE have changed,"
+        warning (OPT_Wcoverage_mismatch,
+                 "Source location for function %qE have changed,"
                  " the profile data may be out of date",
                  DECL_ASSEMBLER_NAME (current_function_decl));
       }
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 180106)
+++ gcc/common.opt	(working copy)
@@ -1125,11 +1125,6 @@
 Don't promote always inline static functions assuming they
 will be inlined and no copy is needed.
 
-
-fripa-verbose
-Common Report Var(flag_ripa_verbose)
-Enable verbose informational messages for LIPO compilation
-
 fearly-inlining
 Common Report Var(flag_early_inlining) Init(1) Optimization
 Perform early inlining
@@ -1572,6 +1567,19 @@
 Common Report Var(flag_omit_frame_pointer) Optimization
 When possible do not generate stack frames
 
+fopt-info
+Common Report Var(flag_opt_info) Optimization Init(1)
+Enable verbose informational messages for optimizations (same as -fopt-info=1)
+
+; fopt-info=0: no message will be emitted.
+; fopt-info or fopt-info=1: emit important warnings and optimization messages with
+;   large performance impact.
+; fopt-info=2: warnings and optimization messages targeting power users.
+; fopt-info=3: informational messages for compiler developers.
+fopt-info=
+Common RejectNegative Joined UInteger Optimization
+-fopt-info=[0|1|2|3] Set the verbose level of informational messages for optimizations
+
 foptimize-register-move
 Common Report Var(flag_regmove) Optimization
 Do the full register move optimization pass
Index: gcc/tree-profile.c
===================================================================
--- gcc/tree-profile.c	(revision 180106)
+++ gcc/tree-profile.c	(working copy)
@@ -1096,13 +1096,16 @@
                 reusedist_make_instr_call (stmt, subst, counters),
                 GSI_NEW_STMT);
 
-            locus = (stmt != NULL)
-                ? gimple_location (stmt)
-                : DECL_SOURCE_LOCATION (current_function_decl);
-            inform (locus,
-                    "inserted reuse distance instrumentation for %qs, using "
-                    "%d gcov counters", subst->original_name,
-                    subst->num_ptr_args * RD_NUM_COUNTERS);
+            if (flag_opt_info >= OPT_INFO_MAX)
+              {
+                locus = (stmt != NULL)
+                    ? gimple_location (stmt)
+                    : DECL_SOURCE_LOCATION (current_function_decl);
+                inform (locus,
+                        "inserted reuse distance instrumentation for %qs, using "
+                        "%d gcov counters", subst->original_name,
+                        subst->num_ptr_args * RD_NUM_COUNTERS);
+              }
           }
       }
 }
@@ -1214,7 +1217,7 @@
 
   reusedist_from_counters (counters, &rd);
 
-  if (rd.count)
+  if ((flag_opt_info >= OPT_INFO_MAX) && rd.count)
     inform (locus, "reuse distance counters for arg %d: %lld %lld %lld %lld",
             arg, (long long int)rd.mean_dist, (long long int)rd.mean_size,
             (long long int)rd.count, (long long int)rd.dist_x_size);
@@ -1283,9 +1286,10 @@
   subst_decl = reusedist_get_nt_decl (gimple_call_fndecl (stmt), subst,
                                       suffix);
   gimple_call_set_fndecl (stmt, subst_decl);
-  inform (locus, "replaced %qs with non-temporal %qs",
-          subst->original_name,
-          IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (subst_decl)));
+  if (flag_opt_info >= OPT_INFO_MED)
+    inform (locus, "replaced %qs with non-temporal %qs",
+            subst->original_name,
+            IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (subst_decl)));
 }
 
 /* Replace string operations with equivalent nontemporal, when profitable.  */
@@ -1323,11 +1327,13 @@
 
   if (counter_index != n_counters)
     {
-      warning (0, "coverage mismatch for reuse distance counters "
+      warning (OPT_Wcoverage_mismatch,
+               "coverage mismatch for reuse distance counters "
                "in function %qs", IDENTIFIER_POINTER
                (DECL_ASSEMBLER_NAME (current_function_decl)));
-      inform (input_location, "number of counters is %u instead of %u",
-              n_counters, counter_index);
+      if (flag_opt_info >= OPT_INFO_MAX)
+        inform (input_location, "number of counters is %u instead of %u",
+                n_counters, counter_index);
     }
 }
 
