Bug 13081

Summary: [3.3 regression] forward template declarations in <complex> let inlining fail
Product: gcc Reporter: Debian GCC Maintainers <debian-gcc>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs
Priority: P2 Keywords: missed-optimization
Version: 3.3.2   
Target Milestone: 3.3.3   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2003-12-25 17:24:05

Description Debian GCC Maintainers 2003-11-17 00:06:03 UTC
[ forwarded from http://bugs.debian.org/195264 ]

the bug submitter noticed, that std::conj() doesn't get inlined, as one'd expect
it to be, when compiling the following with -O2

template<typename T> T foo(T);
 
template<typename T> inline T foo(T t)
{
  return t;
} // __attribute((always_inline))
 
long bar (long);
 
inline long bar (long l)
{
  return l;
}
 
void doo (long &l)
{
  l = foo (l);
  l = bar (l);
}


Disassembly of section .text:

00000000 <doo(long&)>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   53                      push   %ebx
   4:   83 ec 10                sub    $0x10,%esp
   7:   8b 5d 08                mov    0x8(%ebp),%ebx
   a:   ff 33                   pushl  (%ebx)
   c:   e8 fc ff ff ff          call   d <doo(long&)+0xd>
                        d: R_386_PC32   long foo<long>(long)
  11:   89 03                   mov    %eax,(%ebx)
  13:   83 c4 10                add    $0x10,%esp
  16:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
  19:   c9                      leave  
  1a:   c3                      ret    
Disassembly of section .gnu.linkonce.t._Z3fooIlET_S0_:

00000000 <long foo<long>(long)>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   8b 45 08                mov    0x8(%ebp),%eax
   6:   c9                      leave  
   7:   c3                      ret    


i.e. bar get's inlined, but foo<long> does not... why?
btw, gcc-2.95 would optimize it into a NOP:

00000000 <doo(long &)>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   c9                      leave  
   4:   c3                      ret    

-- I'd say that's a regression...
Comment 1 Andrew Pinski 2003-11-17 00:52:07 UTC
The problem is somehow related to having this line:
template<typename T> T foo(T);

Confirmed on the mainline and 3.3.2.
Comment 2 Andrew Pinski 2003-12-16 20:31:48 UTC
Some how the template is being marked as not inlinable (it does not inline even at -O3).
Comment 3 Andrew Pinski 2003-12-25 00:27:41 UTC
Too much changes for 3.3.3 to fix this one.
Comment 4 Andrew Pinski 2003-12-25 16:46:11 UTC
Maybe I was wrong, this might be fixable for 3.3.3.
Comment 5 Andrew Pinski 2003-12-25 17:24:04 UTC
The problem is that the followard template declaration:
template<typename T> T foo(T);
Causes all template functions not be defined as inline.
Comment 6 CVS Commits 2003-12-29 02:42:20 UTC
Subject: Bug 13081

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	mmitchel@gcc.gnu.org	2003-12-29 02:42:17

Modified files:
	gcc/cp         : ChangeLog decl.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/opt: inline6.C 
	gcc/testsuite/g++.dg/parse: error9.C 

Log message:
	PR c++/13081
	* decl.c (duplicate_decls): Preserve inline-ness when redeclaring
	a function template.
	
	PR c++/12613
	* decl.c (reshape_init): Reject GNU colon-style designated
	initializers in arrays.
	
	PR c++/13081
	* g++.dg/opt/inline6.C: New test.
	
	PR c++/12613
	* g++.dg/parse/error9.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3837&r2=1.3838
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&r1=1.1168&r2=1.1169
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3315&r2=1.3316
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/inline6.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/error9.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 7 Mark Mitchell 2003-12-29 02:44:11 UTC
Fixed in GCC 3.4.
Comment 8 Matthias Klose 2003-12-29 17:00:07 UTC
Subject: Re:  [3.3/3.4 regression] forward template declarations in <complex> let inlining fail

> Module name:	gcc
> Changes by:	mmitchel@gcc.gnu.org	2003-12-29 02:42:17
> 
> Modified files:
> 	gcc/cp         : ChangeLog decl.c 
> 	gcc/testsuite  : ChangeLog 
> Added files:
> 	gcc/testsuite/g++.dg/opt: inline6.C 
> 	gcc/testsuite/g++.dg/parse: error9.C 
> 
> Log message:
> 	PR c++/13081
> 	* decl.c (duplicate_decls): Preserve inline-ness when redeclaring
> 	a function template.
> 	
> 	PR c++/13081
> 	* g++.dg/opt/inline6.C: New test.

backported to the gcc-3_3-branch, no regressions on an i486-linux
bootstrap. Ok for the branch?

2003-12-28  Mark Mitchell  <mark@codesourcery.com>

	PR c++/13081
 	* decl.c (duplicate_decls): Preserve inline-ness when redeclaring
 	a function template.
 
 	PR c++/13081
 	* g++.dg/opt/inline6.C: New test.

--- gcc/testsuite/g++.dg/opt/inline6.C
+++ gcc/testsuite/g++.dg/opt/inline6.C	2003-12-29 09:12:36.000000000 +0000
@@ -0,0 +1,14 @@
+// PR c++/13081
+// { dg-options "-O2" }
+// { dg-final { scan-assembler-not "foo" } }
+
+template<typename T> T foo(T);
+ 
+template<typename T> inline T foo(T t)
+{
+  return t;
+}
+
+void bar (long& l) {
+  l = foo(l);
+}

--- gcc/cp/decl.c~	2003-12-29 10:18:13.000000000 +0100
+++ gcc/cp/decl.c	2003-12-29 10:25:57.000000000 +0100
@@ -3737,6 +3737,14 @@
 	    = DECL_SOURCE_LOCATION (newdecl);
 	}
 
+      if (DECL_FUNCTION_TEMPLATE_P (newdecl))
+	{
+	  DECL_INLINE (DECL_TEMPLATE_RESULT (olddecl)) 
+	    |= DECL_INLINE (DECL_TEMPLATE_RESULT (newdecl));
+	  DECL_DECLARED_INLINE_P (DECL_TEMPLATE_RESULT (olddecl))
+	    |= DECL_DECLARED_INLINE_P (DECL_TEMPLATE_RESULT (newdecl));
+	}
+
       return 1;
     }
 
Comment 9 Gabriel Dos Reis 2004-01-01 00:22:26 UTC
Subject: Re:  [3.3/3.4 regression] forward template declarations in <complex> let inlining fail

Matthias Klose <doko@cs.tu-berlin.de> writes:

| > Module name:	gcc
| > Changes by:	mmitchel@gcc.gnu.org	2003-12-29 02:42:17
| > 
| > Modified files:
| > 	gcc/cp         : ChangeLog decl.c 
| > 	gcc/testsuite  : ChangeLog 
| > Added files:
| > 	gcc/testsuite/g++.dg/opt: inline6.C 
| > 	gcc/testsuite/g++.dg/parse: error9.C 
| > 
| > Log message:
| > 	PR c++/13081
| > 	* decl.c (duplicate_decls): Preserve inline-ness when redeclaring
| > 	a function template.
| > 	
| > 	PR c++/13081
| > 	* g++.dg/opt/inline6.C: New test.
| 
| backported to the gcc-3_3-branch, no regressions on an i486-linux
| bootstrap. Ok for the branch?

Yes, thanks.

-- Gaby
Comment 10 CVS Commits 2004-01-02 11:15:08 UTC
Subject: Bug 13081

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_3-branch
Changes by:	doko@gcc.gnu.org	2004-01-02 11:15:04

Modified files:
	gcc/cp         : decl.c ChangeLog 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/opt: inline6.C 

Log message:
	2004-01-02  Matthias Klose  <doko@debian.org>
	
	Backport from mainline:
	2003-12-28  Mark Mitchell  <mark@codesourcery.com>
	
	PR c++/13081
	* decl.c (duplicate_decls): Preserve inline-ness when redeclaring
	a function template.
	
	PR c++/13081
	* g++.dg/opt/inline6.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/inline6.C.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.4.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.965.2.69&r2=1.965.2.70
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.3076.2.234&r2=1.3076.2.235
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.2261.2.350&r2=1.2261.2.351

Comment 11 Debian GCC Maintainers 2004-01-02 11:42:58 UTC
Fixed on the 3.3 branch as well.