[A fair bit later than promised, sorry...]

Mikhail posted a patch to make genflags generate the default HAVE_foo
and gen_foo definitions that have recently been added to defaults.h:

  https://gcc.gnu.org/ml/gcc-patches/2015-06/msg00723.html

I agree it'd be a good idea to generate this kind of thing automatically,
but I think we should take the opportunity to move the interface to the
target structure.  I.e.:

  HAVE_foo -> targetm.have_foo ()
  gen_foo -> targetm.gen_foo ()

This should move us closer to the pipedream goal of supporting multiple
targets at once.  It should also mean that only the target code depends
on insn-flags.h.

The patch just moves return and simple_return as an example.  I have more
locally (in order to test other code paths), but they're just an obvious
extension of this one.

The patch relies on the hashing changes in:

  https://gcc.gnu.org/ml/gcc-patches/2015-06/msg01066.html
  https://gcc.gnu.org/ml/gcc-patches/2015-06/msg01564.html

and on this trivial patch:

  https://gcc.gnu.org/ml/gcc-patches/2015-06/msg01604.html

It seems a bit heavyweight when you just look at these two instructions,
but I think it'll be a saving in the end.

Bootstrapped & regression-tested on x86_64-linux-gnu.  Also tested
via config-list.mk.  OK to install?

Thanks,
Richard


gcc/
        * Makefile.in (TARGET_DEF): Add target-insns.def.
        (.PRECIOUS, simple_rtl_generated_h): Add insn-target-def.h.
        (build/gentarget-def.o): New rule.
        (genprogrtl): Add target-def.
        * target-insns.def, gentarget-def.c: New files.
        * target.def: Add targetm.have_* and targetm.gen_* hooks,
        based on the contents of target-insns.def.
        * defaults.h (HAVE_simple_return, gen_simple_return): Delete.
        (HAVE_return, gen_return): Delete.
        * target-def.h: Include insn-target-def.h.
        * cfgrtl.c (force_nonfallthru_and_redirect): Use targetm interface
        instead of direct calls.  Rely on them to do the appropriate assertions.
        * function.c (gen_return_pattern): Likewise.  Return an rtx_insn *.
        (convert_jumps_to_returns): Use targetm interface instead of
        direct calls.
        (thread_prologue_and_epilogue_insns): Likewise.
        * reorg.c (find_end_label, dbr_schedule): Likewise.
        * shrink-wrap.h (SHRINK_WRAPPING_ENABLED): Likewise.
        * shrink-wrap.c (convert_to_simple_return): Likewise.
        (try_shrink_wrapping): Use SHRINK_WRAPPING_ENABLED.

Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in     2015-06-22 14:03:10.985503368 +0100
+++ gcc/Makefile.in     2015-06-22 14:04:26.689971484 +0100
@@ -866,7 +866,7 @@ DUMPFILE_H = $(srcdir)/../libcpp/include
 VEC_H = vec.h statistics.h $(GGC_H)
 HASH_TABLE_H = $(HASHTAB_H) hash-table.h
 EXCEPT_H = except.h $(HASHTAB_H)
-TARGET_DEF = target.def target-hooks-macros.h
+TARGET_DEF = target.def target-hooks-macros.h target-insns.def
 C_TARGET_DEF = c-family/c-target.def target-hooks-macros.h
 COMMON_TARGET_DEF = common/common-target.def target-hooks-macros.h
 TARGET_H = $(TM_H) target.h $(TARGET_DEF) insn-modes.h insn-codes.h
@@ -2078,7 +2078,8 @@ $(common_out_object_file): $(common_out_
 .PRECIOUS: insn-config.h insn-flags.h insn-codes.h insn-constants.h \
   insn-emit.c insn-recog.c insn-extract.c insn-output.c insn-peep.c \
   insn-attr.h insn-attr-common.h insn-attrtab.c insn-dfatab.c \
-  insn-latencytab.c insn-preds.c gimple-match.c generic-match.c
+  insn-latencytab.c insn-preds.c gimple-match.c generic-match.c \
+  insn-target-def.h
 
 # Dependencies for the md file.  The first time through, we just assume
 # the md file itself and the generated dependency file (in order to get
@@ -2099,7 +2100,7 @@ s-mddeps: $(md_file) $(MD_INCLUDES) buil
 # the target file.
 
 simple_rtl_generated_h = insn-attr.h insn-attr-common.h insn-codes.h \
-                         insn-config.h insn-flags.h
+                         insn-config.h insn-flags.h insn-target-def.h
 
 simple_rtl_generated_c = insn-automata.c insn-emit.c \
                          insn-extract.c insn-output.c \
@@ -2498,6 +2499,9 @@ build/genextract.o : genextract.c $(RTL_
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
 build/genflags.o : genflags.c $(RTL_BASE_H) $(OBSTACK_H) $(BCONFIG_H)  \
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
+build/gentarget-def.o : gentarget-def.c $(BCONFIG_H) $(SYSTEM_H)       \
+  coretypes.h $(GTM_H) $(RTL_BASE_H) errors.h $(READ_MD_H) gensupport.h        
\
+  $(HASH_TABLE_H) target-insns.def
 build/gengenrtl.o : gengenrtl.c $(BCONFIG_H) $(SYSTEM_H) rtl.def
 
 # The gengtype generator program is special: Two versions are built.
@@ -2562,7 +2566,7 @@ build/genmatch.o : genmatch.c $(BCONFIG_
 
 # All these programs use the RTL reader ($(BUILD_RTL)).
 genprogrtl = attr attr-common attrtab automata codes conditions config emit \
-            extract flags opinit output peep preds recog mddump
+            extract flags mddump opinit output peep preds recog target-def
 $(genprogrtl:%=build/gen%$(build_exeext)): $(BUILD_RTL)
 
 # All these programs use the MD reader ($(BUILD_MD)).
Index: gcc/target-insns.def
===================================================================
--- /dev/null   2015-06-22 13:54:06.971314091 +0100
+++ gcc/target-insns.def        2015-06-22 14:04:26.690971419 +0100
@@ -0,0 +1,34 @@
+/* Target instruction definitions.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This file has one entry for each public pattern name that the target
+   can provide.  It is only used if no distinction between operand modes
+   is necessary.  If separate patterns are needed for different modes
+   (so as to distinguish addition of QImode values from addition of
+   HImode values, for example) then an optab should be used instead.
+
+   Each entry has the form:
+
+     DEF_TARGET_INSN (name, prototype)
+
+   where NAME is the name of the pattern and PROTOTYPE is its C prototype.
+   The prototype should use parameter names of the form "x0", "x1", etc.
+   Patterns that take no operands should have a prototype "(void)".
+
+   Instructions should be documented in md.texi rather than here.  */
+DEF_TARGET_INSN (return, (void))
+DEF_TARGET_INSN (simple_return, (void))
Index: gcc/gentarget-def.c
===================================================================
--- /dev/null   2015-06-22 13:54:06.971314091 +0100
+++ gcc/gentarget-def.c 2015-06-22 14:04:26.689971484 +0100
@@ -0,0 +1,265 @@
+/* Generate insn-target-def.h, an automatically-generated part of targetm.
+   Copyright (C) 1987-2015 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "bconfig.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "errors.h"
+#include "read-md.h"
+#include "gensupport.h"
+#include "hash-table.h"
+
+/* This class hashes define_insns and define_expands by name.  */
+struct insn_hasher : nofree_ptr_hash <rtx_def>
+{
+  typedef rtx value_type;
+  typedef const char *compare_type;
+
+  static inline hashval_t hash (rtx);
+  static inline bool equal (rtx, const char *);
+};
+
+hashval_t
+insn_hasher::hash (rtx x)
+{
+  return htab_hash_string (XSTR (x, 0));
+}
+
+bool
+insn_hasher::equal (rtx x, const char *y)
+{
+  return strcmp (XSTR (x, 0), y) == 0;
+}
+
+/* All define_insns and define_expands, hashed by name.  */
+static hash_table <insn_hasher> *insns;
+
+/* Records the prototype suffix X for each invalid_X stub that has been
+   generated.  */
+static hash_table <nofree_string_hash> *stubs;
+
+/* Records which C conditions have been wrapped in functions, as a mapping
+   from the C condition to the function name.  */
+static hash_map <nofree_string_hash, const char *> *have_funcs;
+
+/* Output hook definitions for pattern NAME, which has target-insns.def
+   prototype PROTOTYPE.  */
+
+static void
+def_target_insn (const char *name, const char *prototype)
+{
+  /* Get an upper-case form of NAME.  */
+  unsigned int i;
+  char *upper_name = XALLOCAVEC (char, strlen (name) + 1);
+  for (i = 0; name[i]; ++i)
+    upper_name[i] = TOUPPER (name[i]);
+  upper_name[i] = 0;
+
+  /* Check that the prototype is valid and concatenate the types
+     together to get a suffix.  */
+  char *suffix = XALLOCAVEC (char, strlen (prototype) + 1);
+  i = 0;
+  unsigned int opno = 0;
+  for (const char *p = prototype; *p; ++p)
+    if (*p == 'x' && ISDIGIT (p[1]))
+      {
+       /* This should be a parameter name of the form "x<OPNO>".
+          That doesn't contribute to the suffix, so skip ahead and
+          process the following character.  */
+       char *endptr;
+       if (strtol (p + 1, &endptr, 10) != opno
+           || (*endptr != ',' && *endptr != ')'))
+         {
+           error ("invalid prototype for '%s'", name);
+           exit (FATAL_EXIT_CODE);
+         }
+       opno += 1;
+       p = endptr;
+       if (*p == ',')
+         suffix[i++] = '_';
+      }
+    else if (*p == ')' || *p == ',')
+      {
+       /* We found the end of a parameter without finding a
+          parameter name.  */
+       if (strcmp (prototype, "(void)") != 0)
+         {
+           error ("argument %d of '%s' did not have the expected name",
+                  opno, name);
+           exit (FATAL_EXIT_CODE);
+         }
+      }
+    else if (*p != '(' && !ISSPACE (*p))
+      suffix[i++] = *p;
+  suffix[i] = 0;
+
+  /* See whether we have an implementation of this pattern.  */
+  hashval_t hash = htab_hash_string (name);
+  int truth = 0;
+  const char *have_name = name;
+  if (rtx insn = insns->find_with_hash (name, hash))
+    {
+      const char *test = XSTR (insn, 2);
+      truth = maybe_eval_c_test (test);
+      gcc_assert (truth != 0);
+      if (truth < 0)
+       {
+         /* Try to reuse an existing function that performs the same test.  */
+         bool existed;
+         const char *&entry = have_funcs->get_or_insert (test, &existed);
+         if (!existed)
+           {
+             entry = name;
+             printf ("\nstatic bool\n");
+             printf ("target_have_%s (void)\n", name);
+             printf ("{\n");
+             printf ("  return ");
+             print_c_condition (test);
+             printf (";\n");
+             printf ("}\n");
+           }
+         have_name = entry;
+       }
+      printf ("\nstatic rtx_insn *\n");
+      printf ("target_gen_%s %s\n", name, prototype);
+      printf ("{\n");
+      if (truth < 0)
+       printf ("  gcc_checking_assert (targetm.have_%s ());\n", name);
+      printf ("  return insnify (gen_%s (", name);
+      for (i = 0; i < opno; ++i)
+       printf ("%sx%d", i == 0 ? "" : ", ", i);
+      printf ("));\n");
+      printf ("}\n");
+    }
+  else
+    {
+      const char **slot = stubs->find_slot (suffix, INSERT);
+      if (!*slot)
+       {
+         *slot = xstrdup (suffix);
+         printf ("\nstatic rtx_insn *\n");
+         printf ("invalid_%s ", suffix);
+         const char *p = prototype;
+         while (*p)
+           {
+             if (p[0] == 'x' && ISDIGIT (p[1]))
+               {
+                 char *endptr;
+                 strtol (p + 1, &endptr, 10);
+                 p = endptr;
+               }
+             else
+               fputc (*p++, stdout);
+           }
+         printf ("\n{\n");
+         printf ("  gcc_unreachable ();\n");
+         printf ("}\n");
+       }
+    }
+  printf ("\n#undef TARGET_HAVE_%s\n", upper_name);
+  printf ("#define TARGET_HAVE_%s ", upper_name);
+  if (truth == 0)
+    printf ("hook_bool_void_false\n");
+  else if (truth == 1)
+    printf ("hook_bool_void_true\n");
+  else
+    printf ("target_have_%s\n", have_name);
+
+  printf ("#undef TARGET_GEN_%s\n", upper_name);
+  printf ("#define TARGET_GEN_%s ", upper_name);
+  if (truth == 0)
+    printf ("invalid_%s\n", suffix);
+  else
+    printf ("target_gen_%s\n", name);
+}
+
+int
+main (int argc, char **argv)
+{
+  int insn_code_number = 0;
+
+  progname = "gentarget-def";
+
+  if (!init_rtx_reader_args (argc, argv))
+    return (FATAL_EXIT_CODE);
+
+  insns = new hash_table <insn_hasher> (31);
+  stubs = new hash_table <nofree_string_hash> (31);
+  have_funcs = new hash_map <nofree_string_hash, const char *>;
+
+  while (1)
+    {
+      int line_no;
+      rtx desc = read_md_rtx (&line_no, &insn_code_number);
+      if (desc == NULL)
+       break;
+      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
+       {
+         const char *name = XSTR (desc, 0);
+         if (name[0] != 0 && name[0] != '*')
+           {
+             hashval_t hash = htab_hash_string (name);
+             rtx *slot = insns->find_slot_with_hash (name, hash, INSERT);
+             if (*slot)
+               {
+                 message_with_line (line_no, "duplicate definition of '%s'",
+                                    name);
+                 have_error = 1;
+               }
+             else
+               *slot = desc;
+           }
+       }
+    }
+
+  printf ("/* Generated automatically by the program `gentarget-def'.  */\n");
+  printf ("#ifndef GCC_INSN_TARGET_DEF_H\n");
+  printf ("#define GCC_INSN_TARGET_DEF_H\n");
+
+  /* Output a routine to convert an rtx to an rtx_insn sequence.
+     ??? At some point the gen_* functions themselves should return
+        rtx_insns.  */
+  printf ("\nstatic inline rtx_insn *\n");
+  printf ("insnify (rtx x)\n");
+  printf ("{\n");
+  printf ("  if (!x)\n");
+  printf ("    return NULL;\n");
+  printf ("  if (rtx_insn *insn = dyn_cast <rtx_insn *> (x))\n");
+  printf ("    return insn;\n");
+  printf ("  start_sequence ();\n");
+  printf ("  emit (x);\n");
+  printf ("  rtx_insn *res = get_insns ();\n");
+  printf ("  end_sequence ();\n");
+  printf ("  return res;\n");
+  printf ("}\n");
+
+#define DEF_TARGET_INSN(INSN, ARGS) \
+  def_target_insn (#INSN, #ARGS);
+#include "target-insns.def"
+#undef DEF_TARGET_INSN
+
+  printf ("\n#endif /* GCC_INSN_TARGET_DEF_H */\n");
+
+  if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
+    return FATAL_EXIT_CODE;
+
+  return SUCCESS_EXIT_CODE;
+}
Index: gcc/target.def
===================================================================
--- gcc/target.def      2015-06-22 14:03:10.985503368 +0100
+++ gcc/target.def      2015-06-22 14:04:26.690971419 +0100
@@ -5864,6 +5864,19 @@ DEFHOOK
 
 HOOK_VECTOR_END (mode_switching)
 
+#undef HOOK_PREFIX
+#define HOOK_PREFIX "TARGET_"
+
+#define DEF_TARGET_INSN(NAME, PROTO) \
+  DEFHOOK_UNDOC (have_##NAME, "", bool, (void), false)
+#include "target-insns.def"
+#undef DEF_TARGET_INSN
+
+#define DEF_TARGET_INSN(NAME, PROTO) \
+  DEFHOOK_UNDOC (gen_##NAME, "", rtx_insn *, PROTO, NULL)
+#include "target-insns.def"
+#undef DEF_TARGET_INSN
+
 /* Close the 'struct gcc_target' definition.  */
 HOOK_VECTOR_END (C90_EMPTY_HACK)
 
Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h      2015-06-22 14:03:10.985503368 +0100
+++ gcc/defaults.h      2015-06-22 14:04:26.691971355 +0100
@@ -1426,26 +1426,6 @@ #define STACK_CHECK_MAX_VAR_SIZE (STACK_
 #define TARGET_VTABLE_USES_DESCRIPTORS 0
 #endif
 
-#ifndef HAVE_simple_return
-#define HAVE_simple_return 0
-static inline rtx
-gen_simple_return ()
-{
-  gcc_unreachable ();
-  return NULL;
-}
-#endif
-
-#ifndef HAVE_return
-#define HAVE_return 0
-static inline rtx
-gen_return ()
-{
-  gcc_unreachable ();
-  return NULL;
-}
-#endif
-
 #ifndef HAVE_epilogue
 #define HAVE_epilogue 0
 static inline rtx
Index: gcc/target-def.h
===================================================================
--- gcc/target-def.h    2015-06-22 14:03:10.985503368 +0100
+++ gcc/target-def.h    2015-06-22 14:04:26.689971484 +0100
@@ -107,3 +107,4 @@ #define TARGET_FUNCTION_INCOMING_ARG TAR
 
 #include "hooks.h"
 #include "targhooks.h"
+#include "insn-target-def.h"
Index: gcc/cfgrtl.c
===================================================================
--- gcc/cfgrtl.c        2015-06-22 14:02:23.724223518 +0100
+++ gcc/cfgrtl.c        2015-06-22 14:04:26.693971225 +0100
@@ -1695,19 +1695,12 @@ force_nonfallthru_and_redirect (edge e,
   if (target == EXIT_BLOCK_PTR_FOR_FN (cfun))
     {
       if (jump_label == ret_rtx)
-       {
-         if (!HAVE_return)
-           gcc_unreachable ();
-
-         emit_jump_insn_after_setloc (gen_return (), BB_END (jump_block), loc);
-       }
+       emit_jump_insn_after_setloc (targetm.gen_return (),
+                                    BB_END (jump_block), loc);
       else
        {
          gcc_assert (jump_label == simple_return_rtx);
-         if (!HAVE_simple_return)
-           gcc_unreachable ();
-
-         emit_jump_insn_after_setloc (gen_simple_return (),
+         emit_jump_insn_after_setloc (targetm.gen_simple_return (),
                                       BB_END (jump_block), loc);
        }
       set_return_jump_label (BB_END (jump_block));
Index: gcc/function.c
===================================================================
--- gcc/function.c      2015-06-22 14:04:03.369476746 +0100
+++ gcc/function.c      2015-06-22 14:04:26.692971290 +0100
@@ -5657,13 +5657,12 @@ emit_use_return_register_into_block (bas
 /* Create a return pattern, either simple_return or return, depending on
    simple_p.  */
 
-static rtx
+static rtx_insn *
 gen_return_pattern (bool simple_p)
 {
-  if (!HAVE_simple_return)
-    gcc_assert (!simple_p);
-
-  return simple_p ? gen_simple_return () : gen_return ();
+  return (simple_p
+         ? targetm.gen_simple_return ()
+         : targetm.gen_return ());
 }
 
 /* Insert an appropriate return pattern at the end of block BB.  This
@@ -5769,7 +5768,7 @@ convert_jumps_to_returns (basic_block la
            dest = ret_rtx;
          if (!redirect_jump (as_a <rtx_jump_insn *> (jump), dest, 0))
            {
-             if (HAVE_simple_return && simple_p)
+             if (targetm.have_simple_return () && simple_p)
                {
                  if (dump_file)
                    fprintf (dump_file,
@@ -5790,7 +5789,7 @@ convert_jumps_to_returns (basic_block la
        }
       else
        {
-         if (HAVE_simple_return && simple_p)
+         if (targetm.have_simple_return () && simple_p)
            {
              if (dump_file)
                fprintf (dump_file,
@@ -5981,12 +5980,12 @@ thread_prologue_and_epilogue_insns (void
 
   exit_fallthru_edge = find_fallthru_edge (EXIT_BLOCK_PTR_FOR_FN 
(cfun)->preds);
 
-  if (HAVE_simple_return && entry_edge != orig_entry_edge)
+  if (targetm.have_simple_return () && entry_edge != orig_entry_edge)
     exit_fallthru_edge
        = get_unconverted_simple_return (exit_fallthru_edge, bb_flags,
                                         &unconverted_simple_returns,
                                         &returnjump);
-  if (HAVE_return)
+  if (targetm.have_return ())
     {
       if (exit_fallthru_edge == NULL)
        goto epilogue_done;
@@ -6007,7 +6006,8 @@ thread_prologue_and_epilogue_insns (void
 
              /* Emitting the return may add a basic block.
                 Fix bb_flags for the added block.  */
-             if (HAVE_simple_return && last_bb != exit_fallthru_edge->src)
+             if (targetm.have_simple_return ()
+                 && last_bb != exit_fallthru_edge->src)
                bitmap_set_bit (&bb_flags, last_bb->index);
 
              goto epilogue_done;
@@ -6123,7 +6123,7 @@ thread_prologue_and_epilogue_insns (void
        }
     }
 
-  if (HAVE_simple_return)
+  if (targetm.have_simple_return ())
     convert_to_simple_return (entry_edge, orig_entry_edge, bb_flags,
                              returnjump, unconverted_simple_returns);
 
@@ -6139,8 +6139,9 @@ thread_prologue_and_epilogue_insns (void
 
       if (!CALL_P (insn)
          || ! SIBLING_CALL_P (insn)
-         || (HAVE_simple_return && (entry_edge != orig_entry_edge
-                                    && !bitmap_bit_p (&bb_flags, bb->index))))
+         || (targetm.have_simple_return ()
+             && entry_edge != orig_entry_edge
+             && !bitmap_bit_p (&bb_flags, bb->index)))
        {
          ei_next (&ei);
          continue;
Index: gcc/reorg.c
===================================================================
--- gcc/reorg.c 2015-06-22 14:03:10.985503368 +0100
+++ gcc/reorg.c 2015-06-22 14:04:26.692971290 +0100
@@ -473,7 +473,7 @@ find_end_label (rtx kind)
        }
       else
        {
-         if (HAVE_epilogue && ! HAVE_return)
+         if (HAVE_epilogue && ! targetm.have_return ())
            /* The RETURN insn has its delay slot filled so we cannot
               emit the label just before it.  Since we already have
               an epilogue and cannot emit a new RETURN, we cannot
@@ -483,10 +483,10 @@ find_end_label (rtx kind)
          /* Otherwise, make a new label and emit a RETURN and BARRIER,
             if needed.  */
          emit_label (label);
-         if (HAVE_return)
+         if (targetm.have_return ())
            {
              /* The return we make may have delay slots too.  */
-             rtx pat = gen_return ();
+             rtx_insn *pat = targetm.gen_return ();
              rtx_insn *insn = emit_jump_insn (pat);
              set_return_jump_label (insn);
              emit_barrier ();
@@ -3815,8 +3815,9 @@ dbr_schedule (rtx_insn *first)
     delete_related_insns (function_simple_return_label);
 
   need_return_insns = false;
-  need_return_insns |= HAVE_return && function_return_label != 0;
-  need_return_insns |= HAVE_simple_return && function_simple_return_label != 0;
+  need_return_insns |= targetm.have_return () && function_return_label != 0;
+  need_return_insns |= (targetm.have_simple_return ()
+                       && function_simple_return_label != 0);
   if (need_return_insns)
     make_return_insns (first);
 
Index: gcc/shrink-wrap.h
===================================================================
--- gcc/shrink-wrap.h   2015-06-22 14:03:10.985503368 +0100
+++ gcc/shrink-wrap.h   2015-06-22 14:04:26.692971290 +0100
@@ -36,7 +36,8 @@ extern void convert_to_simple_return (ed
                                      bitmap_head bb_flags,
                                      rtx_insn *returnjump,
                                      vec<edge> unconverted_simple_returns);
-#define SHRINK_WRAPPING_ENABLED (flag_shrink_wrap && HAVE_simple_return)
+#define SHRINK_WRAPPING_ENABLED \
+  (flag_shrink_wrap && targetm.have_simple_return ())
 
 #endif  /* GCC_SHRINK_WRAP_H  */
 
Index: gcc/shrink-wrap.c
===================================================================
--- gcc/shrink-wrap.c   2015-06-22 14:03:10.985503368 +0100
+++ gcc/shrink-wrap.c   2015-06-22 14:04:26.692971290 +0100
@@ -541,7 +541,7 @@ try_shrink_wrapping (edge *entry_edge, e
        break;
       }
 
-  if (flag_shrink_wrap && HAVE_simple_return
+  if (SHRINK_WRAPPING_ENABLED
       && (targetm.profile_before_prologue () || !crtl->profile)
       && nonempty_prologue && !crtl->calls_eh_return)
     {
@@ -1004,8 +1004,8 @@ convert_to_simple_return (edge entry_edg
 
              bb = create_basic_block (NULL, NULL, exit_pred);
              BB_COPY_PARTITION (bb, e->src);
-             rtx_jump_insn *start = emit_jump_insn_after (gen_simple_return (),
-                                                          BB_END (bb));
+             rtx_insn *ret = targetm.gen_simple_return ();
+             rtx_jump_insn *start = emit_jump_insn_after (ret, BB_END (bb));
              JUMP_LABEL (start) = simple_return_rtx;
              emit_barrier_after (start);
 

Reply via email to