[patch] more target inline control hooks

DJ Delorie dj@redhat.com
Tue Mar 20 18:25:00 GMT 2007

This is one of the patches I was talking about last week.  The intent
is to let the target decide when attributes are "compatible", not just
whether the callee's attributes permit inlining in general (that hook
doesn't appear to be callee-context-specific any more, so you can't
cheat and check cfun).

The MeP port supports two types of modes; core and vliw.  Vliw mode
packs one core insn and one coprocessor insn in a bundle, so the code
generator is the same but the intrinsics differ (there are extra copro
insns in vliw mode).  Thus, every function is tagged (implicitly or
explicitly) as core or vliw, and you can only inline into same-mode
functions.  Calls from a core function to a "static inline vliw" one
need to be blocked completely.

No regressions on i686-fc6.  Ok to apply?

	* doc/tm.texi (TARGET_ALLOW_INLINING_P): Document.
	(TARGET_ALLOW_CALL_P)): Document.
	caller specific.
	* hooks.c (hook_bool_tree_tree_true): New.
	* hooks.h (hook_bool_tree_tree_true): Declare.
	* target.h (allow_call_p): New.
	(allow_inline_p): New.
	* target-def.h (TARGET_ALLOW_CALL_P): Add.

	* ipa-inline.c (cgraph_mark_inline_edge): Call target hook
	to see if inlining here is permitted.
	* c-typeck.c (build_function_call): See if this function
	call is permitted.

Index: doc/tm.texi
--- doc/tm.texi	(revision 123090)
+++ doc/tm.texi	(working copy)
@@ -9024,17 +9024,34 @@ attributes, or a copy of the list may be
 @end deftypefn
 @deftypefn {Target Hook} bool TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P (tree @var{fndecl})
 @cindex inlining
 This target hook returns @code{true} if it is ok to inline @var{fndecl}
-into the current function, despite its having target-specific
+into any function, despite its having target-specific
 attributes, @code{false} otherwise.  By default, if a function has a
 target specific attribute attached to it, it will not be inlined.
 @end deftypefn
+@deftypefn {Target Hook} bool TARGET_ALLOW_INLINING_P (tree @var{caller}, tree @var{callee})
+@cindex inlining
+This target hook returns @code{true} if it is ok to inline
+@var{callee} into @var{caller}, based on compatibility of their
+target-specific attributes, @code{false} otherwise.  By default, two
+functions are considered compatible as long as
+@end deftypefn
+@deftypefn {Target Hook} bool TARGET_ALLOW_CALL_P (tree @var{caller}, tree @var{callee})
+@cindex inlining
+This target hook returns @code{true} if it is ok to call @var{callee}
+from @var{caller}, based on compatibility of their target-specific
+attributes, @code{false} otherwise.  By default, this hook always
+returns @code{true}.
+@end deftypefn
 @node MIPS Coprocessors
 @section Defining coprocessor specifics for MIPS targets.
 @cindex MIPS coprocessor-definition macros
 The MIPS specification allows MIPS implementations to have as many as 4
 coprocessors, each with as many as 32 private registers.  GCC supports
Index: hooks.c
--- hooks.c	(revision 123090)
+++ hooks.c	(working copy)
@@ -199,12 +199,18 @@ bool
 hook_bool_tree_tree_false (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
   return false;
+hook_bool_tree_tree_true (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
+  return true;
 hook_bool_tree_bool_false (tree a ATTRIBUTE_UNUSED, bool b ATTRIBUTE_UNUSED)
   return false;
Index: hooks.h
--- hooks.h	(revision 123090)
+++ hooks.h	(working copy)
@@ -39,12 +39,13 @@ extern bool hook_bool_tree_hwi_hwi_tree_
 extern bool hook_bool_rtx_false (rtx);
 extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *);
 extern bool hook_bool_rtx_int_int_intp_false (rtx, int, int, int *);
 extern bool hook_bool_constcharptr_size_t_false (const char *, size_t);
 extern bool hook_bool_size_t_constcharptr_int_true (size_t, const char *, int);
 extern bool hook_bool_tree_tree_false (tree, tree);
+extern bool hook_bool_tree_tree_true (tree, tree);
 extern bool hook_bool_tree_bool_false (tree, bool);
 extern void hook_void_void (void);
 extern void hook_void_constcharptr (const char *);
 extern void hook_void_FILEptr_constcharptr (FILE *, const char *);
 extern void hook_void_tree (tree);
Index: target.h
--- target.h	(revision 123090)
+++ target.h	(working copy)
@@ -450,12 +450,21 @@ struct gcc_target
   void (* insert_attributes) (tree decl, tree *attributes);
   /* Return true if FNDECL (which has at least one machine attribute)
      can be inlined despite its machine attributes, false otherwise.  */
   bool (* function_attribute_inlinable_p) (tree fndecl);
+  /* Return true if function CALLER may call CALLEE.  Report an error
+     otherwise.  CALLER is a decl and CALLEE is an arbitrary function
+     expression.  */
+  bool (* allow_call_p) (tree caller, tree callee);
+  /* Return true if function CALLER may inline calls to CALLEE.  Both
+     arguments are decls.  */
+  bool (* allow_inlining_p) (tree caller, tree callee);
   /* Return true if bitfields in RECORD_TYPE should follow the
      Microsoft Visual C++ bitfield layout rules.  */
   bool (* ms_bitfield_layout_p) (tree record_type);
   /* True if the target supports decimal floating point.  */
   bool (* decimal_float_supported_p) (void);
Index: ipa-inline.c
--- ipa-inline.c	(revision 123090)
+++ ipa-inline.c	(working copy)
@@ -137,12 +137,13 @@ Software Foundation, 51 Franklin Street,
 #include "tree-pass.h"
 #include "hashtab.h"
 #include "coverage.h"
 #include "ggc.h"
 #include "tree-flow.h"
 #include "rtl.h"
+#include "target.h"
 /* Mode incremental inliner operate on:
    In ALWAYS_INLINE only functions marked
    always_inline are inlined.  This mode is used after detecting cycle during
@@ -245,12 +246,15 @@ cgraph_clone_inlined_nodes (struct cgrap
 cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original)
   int old_insns = 0, new_insns = 0;
   struct cgraph_node *to = NULL, *what;
+  if (! targetm.allow_inlining_p (e->caller->decl, e->callee->decl))
+    return;
   if (e->callee->inline_decl)
     cgraph_redirect_edge_callee (e, cgraph_node (e->callee->inline_decl));
   gcc_assert (e->inline_failed);
   e->inline_failed = NULL;
Index: c-typeck.c
--- c-typeck.c	(revision 123090)
+++ c-typeck.c	(working copy)
@@ -2267,12 +2267,15 @@ build_function_call (tree function, tree
       error ("called object %qE is not a function", function);
       return error_mark_node;
+  if (! targetm.allow_call_p (current_function_decl, function))
+    return error_mark_node;
   if (fundecl && TREE_THIS_VOLATILE (fundecl))
     current_function_returns_abnormally = 1;
   /* fntype now gets the type of function pointed to.  */
   fntype = TREE_TYPE (fntype);
Index: target-def.h
--- target-def.h	(revision 123090)
+++ target-def.h	(working copy)
@@ -446,12 +446,14 @@ Foundation, 51 Franklin Street, Fifth Fl
 #define TARGET_COMP_TYPE_ATTRIBUTES hook_int_tree_tree_1
 #define TARGET_INSERT_ATTRIBUTES hook_void_tree_treeptr
 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_tree_false
+#define TARGET_ALLOW_CALL_P      hook_bool_tree_tree_true
+#define TARGET_ALLOW_INLINING_P  hook_bool_tree_tree_true
 #define TARGET_MS_BITFIELD_LAYOUT_P hook_bool_tree_false
 #define TARGET_ALIGN_ANON_BITFIELD hook_bool_void_false
 #define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
 #define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false
 #define TARGET_MANGLE_FUNDAMENTAL_TYPE hook_constcharptr_tree_null
@@ -653,12 +655,14 @@ Foundation, 51 Franklin Street, Fifth Fl

More information about the Gcc-patches mailing list