------- Comment #2 from rguenth at gcc dot gnu dot org 2008-01-11 09:42 -------
Confirmed.
void foo(char *p);
void test1(char * p)
{
foo(p++);
foo(p++);
foo(p++);
foo(p++);
}
void test2(char * p)
{
foo(p); p++;
foo(p); p++;
foo(p); p++;
foo(p); p++;
}
The problem is with the first variant we have two registers life over each
function call, while with the second variant only one. This can be seen
from the optimized tree-dump already:
test1 (p)
{
<bb 2>:
p_3 = p_1(D) + 1;
foo (p_1(D));
p_5 = p_3 + 1;
foo (p_3);
p_7 = p_5 + 1;
foo (p_5);
foo (p_7) [tail call];
return;
}
test2 (p)
{
<bb 2>:
foo (p_1(D));
p_2 = p_1(D) + 1;
foo (p_2);
p_3 = p_2 + 1;
foo (p_3);
p_4 = p_3 + 1;
foo (p_4) [tail call];
return;
}
and is initially caused by gimplification which produces
p.0 = p;
p = p + 1;
foo (p.0);
from
foo (p++ );
no further pass undos this transformation.
With GCC 4.0 TER produced
foo (p);
foo (p + 1B);
foo (p + 2B);
...
where we can generate good code from. From 4.1 on this is no longer done.
--
rguenth at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |rguenth at gcc dot gnu dot
| |org
Severity|normal |enhancement
Status|UNCONFIRMED |NEW
Component|c |tree-optimization
Ever Confirmed|0 |1
GCC target triplet|multiple-none-none |
Keywords| |missed-optimization
Last reconfirmed|0000-00-00 00:00:00 |2008-01-11 09:42:38
date| |
Summary|missed optimization, foo(p);|Inefficient gimplification
|p++ is better then foo(p++) |of post-modified function
| |arguments, TER doesn't do
| |its work
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34737