public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Christian Bruel <christian.bruel@st.com>
To: Richard Guenther <richard.guenther@gmail.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATH] PR/49139 fix always_inline failures diagnostics
Date: Tue, 31 May 2011 17:07:00 -0000	[thread overview]
Message-ID: <4DE5115B.4070409@st.com> (raw)
In-Reply-To: <BANLkTi=qeD0+UcKwx6waA9u_mL_E56sbiA@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 3797 bytes --]



On 05/31/2011 11:18 AM, Richard Guenther wrote:
> On Tue, May 31, 2011 at 9:54 AM, Christian Bruel<christian.bruel@st.com>  wrote:
>> Hello,
>>
>> The attached patch fixes a few diagnostic discrepancies for always_inline
>> failures.
>>
>> Illustrated by the fail_always_inline[12].c attached cases, the current
>> behavior is one of:
>>
>> - success (with and without -Winline), silently not honoring always_inline
>>    gcc fail_always_inline1.c -S -Winline -O0 -fpic
>>    gcc fail_always_inline1.c -S -O2 -fpic
>>
>> - error: with -Winline but not without
>>    gcc fail_always_inline1.c -S -Winline -O2 -fpic
>>
>> - error: without -Winline
>>    gcc fail_always_inline2.c -S -fno-early-inlining -O2
>>    or the original c++ attachment in this defect
>>
>> note that -Winline never warns, as stated in the documentation
>>
>> This simple patch consistently emits a warning (changing the sorry
>> unimplemented message) whenever the attribute is not honored.
>>
>> My first will was to generate and error instead of the warning, but since it
>> is possible that inlines is only performed at LTO time, an error would be
>> inapropriate (Note that today this is not possible with -Winline that would
>> abort).
>>
>> Another alternative I considered would be to emit the warning under -Winline
>> rather than unconditionally, but this more a user misuse of the attribute,
>> so should always be warned anyway. Or maybe a new -Winline-always that would
>> be activated under -Wall ? Other opinion welcomed.
>>
>> Tested with standard bootstrap and regression on x86.
>>
>> Comments, and/or OK for trunk ?
>
> The patch is not ok, we may not fail to inline an always_inline
> function.

OK, I thought so that would be an error. but I was afraid to abort the 
inline of function with a missing body (provided by another file) by 
LTO, which would be a regression. rethinking about this and considering 
that a valid LTO program should be valid without LTO, and that the scope 
is the translation unit, that would be OK to always reject 
attribute_inline on functions without a body.

To make this more consistent I proposed to warn
> whenever you take the address of an always_inline function
> (because then you can confuse GCC by indirectly calling
> such function which we might inline dependent on optimization
> setting and which we might discover we didn't inline only
> dependent on optimization setting).Honza proposed to move
> the sorry()ing to when we feel the need to output the
> always_inline function, thus when it was not optimized away,
> but that would require us not preserving the body (do we?)
> with -fpreserve-inline-functions.
>

But we don't know if taking the address of the function will result by a 
call to it, or how the pointer will be used. So I think the check should 
be done at the caller site. But I code like:

inline __attribute__((always_inline))  int foo() { return 0; }

static int (*ptr)() = foo;

int
bar()
{
   return ptr();
}

is not be (legitimately) inlined, but without diagnostic, I don't know 
where to look at this that at the moment.

> For fail_always_inline1.c we should diagnose the appearant
> misuse of always_inline with a warning, drop the attribute
> but keep DECL_DISREGARD_INLINE_LIMITS set.
>
 > Same for fail_always_inline2.c.
>
> I agree that sorry()ing for those cases is odd.  EIther we
> should reject the declarations upfront
> ("always-inline function will not be inlinable"), or we should
> emit a warning of that kind and make sure to not sorry later.

In addition to the error at the caller site, I've added the specific 
warn about the missing inline keyword.

Thanks for your comments, here is the new patch that I'm testing, 
(without the handling of indirect calls which can be treated separately).

Cheers

Christian

[-- Attachment #2: always_inline_warn.patch --]
[-- Type: text/plain, Size: 4832 bytes --]

2010-05-25  Christian Bruel  <christian.bruel@st.com>
	
	PR 49139
	* cgraph.c (cgraph_function_body_availability): Check always_inline
	* ipa-inline-transform.c (inline_transform): Force optimize_inline_calls
	error checking if always_inline seen.
	* tree-inline.c (tree_inlinable_function_p): Use error instead of sorry.
	(expand_call_inline): Likewise.

2010-05-25  Christian Bruel  <christian.bruel@st.com>
	
	* gcc.db/always_inline.c: Removed -Winline. Update checks
	* gcc.db/always_inline2.c: Likewise.
	* gcc.db/always_inline3.c: Likewise.
	* gcc.db/fail_always_inline.c: New.


Index: gcc/cgraph.c
===================================================================
--- gcc/cgraph.c	(revision 174264)
+++ gcc/cgraph.c	(working copy)
@@ -2414,7 +2414,14 @@
      bit.  */
 
   else if (decl_replaceable_p (node->decl) && !DECL_EXTERNAL (node->decl))
+    {
+      if (cgraph_global_info_ready)
+	if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (node->decl)))
+	  if (!DECL_DECLARED_INLINE_P (node->decl))
+	    warning (0, "always_inline function might not be inlinable");
+      
     avail = AVAIL_OVERWRITABLE;
+    }
   else avail = AVAIL_AVAILABLE;
 
   return avail;
Index: gcc/ipa-inline-transform.c
===================================================================
--- gcc/ipa-inline-transform.c	(revision 174264)
+++ gcc/ipa-inline-transform.c	(working copy)
@@ -302,9 +302,20 @@
 
   for (e = node->callees; e; e = e->next_callee)
     {
-      cgraph_redirect_edge_call_stmt_to_callee (e);
+      gimple call = cgraph_redirect_edge_call_stmt_to_callee (e);
+
+      if (!inline_p)
+	{
       if (!e->inline_failed || warn_inline)
         inline_p = true;
+	  else
+	    {
+	      tree fn = gimple_call_fndecl (call);
+	      
+	      if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
+		inline_p = true;
+	    }
+	}
     }
 
   if (inline_p)
Index: gcc/testsuite/gcc.dg/always_inline.c
===================================================================
--- gcc/testsuite/gcc.dg/always_inline.c	(revision 174264)
+++ gcc/testsuite/gcc.dg/always_inline.c	(working copy)
@@ -1,8 +1,8 @@
 /* { dg-do compile } */
-/* { dg-options "-Winline -O2" } */
+/* { dg-options "-O2" } */
 #include <stdarg.h>
 inline __attribute__ ((always_inline)) void
-e(int t, ...) /* { dg-message "sorry\[^\n\]*variable argument" "" } */
+e(int t, ...) /* { dg-error "variable argument" } */
 {
   va_list q;
   va_start (q, t);
Index: gcc/testsuite/gcc.dg/always_inline2.c
===================================================================
--- gcc/testsuite/gcc.dg/always_inline2.c	(revision 174264)
+++ gcc/testsuite/gcc.dg/always_inline2.c	(working copy)
@@ -1,8 +1,8 @@
 /* { dg-do compile } */
-/* { dg-options "-Winline -O2" } */
-inline __attribute__ ((always_inline)) void t(void); /* { dg-message "sorry\[^\n\]*body not available" "" } */
+/* { dg-options "-O2" } */
+inline __attribute__ ((always_inline)) void t(void); /* { dg-error "body not available" } */
 void
 q(void)
 {
-  t(); 				/* { dg-message "sorry\[^\n\]*called from here" "" } */
+  t(); 				/* { dg-error "called from here" } */
 }
Index: gcc/testsuite/gcc.dg/always_inline3.c
===================================================================
--- gcc/testsuite/gcc.dg/always_inline3.c	(revision 174264)
+++ gcc/testsuite/gcc.dg/always_inline3.c	(working copy)
@@ -1,11 +1,11 @@
 /* { dg-do compile } */
-/* { dg-options "-Winline -O2" } */
+/* { dg-options "-O2" } */
 int do_something_evil (void);
 inline __attribute__ ((always_inline)) void
-q2(void) /* { dg-message "sorry\[^\n\]*recursive" "" } */
+q2(void) /* { dg-error "recursive inlining" } */
 {
   if (do_something_evil ())
     return;
-  q2(); 			/* { dg-message "sorry\[^\n\]*called from here" "" } */
+  q2(); 			/* { dg-error "called from here" } */
   q2(); /* With -O2 we don't warn here, it is eliminated by tail recursion.  */
 }
Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c	(revision 174264)
+++ gcc/tree-inline.c	(working copy)
@@ -3192,7 +3192,7 @@
 	 As a bonus we can now give more details about the reason why a
 	 function is not inlinable.  */
       if (always_inline)
-	sorry (inline_forbidden_reason, fn);
+	error (inline_forbidden_reason, fn);
       else if (do_warning)
 	warning (OPT_Winline, inline_forbidden_reason, fn);
 
@@ -3744,9 +3744,9 @@
 	  /* Avoid warnings during early inline pass. */
 	  && cgraph_global_info_ready)
 	{
-	  sorry ("inlining failed in call to %q+F: %s", fn,
-		 _(cgraph_inline_failed_string (reason)));
-	  sorry ("called from here");
+	  error ("inlining failed in call to always_inline %q+F: %s", fn,
+		 cgraph_inline_failed_string (reason));
+	  error ("called from here");
 	}
       else if (warn_inline
 	       && DECL_DECLARED_INLINE_P (fn)

[-- Attachment #3: fail_always_inline.c --]
[-- Type: text/plain, Size: 232 bytes --]

/* { dg-do compile { target fpic } } */
/* { dg-options "-fpic" } */

__attribute((always_inline)) void
 bar() { } /* { dg-error "can be overwriten at linktime" } */

void
f()
{
  bar(); /* { dg-error "called from here" "" } */
}



  parent reply	other threads:[~2011-05-31 16:04 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-31  9:07 Christian Bruel
2011-05-31 12:25 ` Richard Guenther
2011-05-31 12:28   ` Jakub Jelinek
2011-05-31 17:07   ` Christian Bruel [this message]
2011-06-01 10:03     ` Richard Guenther
2011-06-01 13:02       ` Christian Bruel
2011-06-01 13:07         ` Richard Guenther
2011-06-06  8:58           ` Christian Bruel
2011-06-06  9:55             ` Richard Guenther
2011-06-08  8:25               ` Christian Bruel
2011-06-08  9:42                 ` Richard Guenther
2011-06-08 11:56                   ` Christian Bruel
2011-06-14 11:29                   ` Christian Bruel
2011-06-20 13:36                   ` Christian Bruel
2011-06-20 13:46                     ` Rainer Orth
2011-06-20 13:54                       ` Mike Stump
2011-06-20 14:04                       ` Christian Bruel
2011-06-21 11:52                         ` Richard Guenther
2011-06-21 12:07                           ` Richard Guenther
2011-06-20 13:51                     ` Richard Guenther
2011-06-01 14:49       ` Jan Hubicka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4DE5115B.4070409@st.com \
    --to=christian.bruel@st.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).