--- ./gcc/cp/optimize.c.orig Thu Jun 7 00:50:22 2001 +++ ./gcc/cp/optimize.c Wed Aug 22 20:20:26 2001 @@ -621,7 +621,23 @@ inline_data *id; { int inlinable; - + /* garloff@suse.de, 2001-08-22: The C++ inline throttling has + * bad side effects, sometimes, in our top-down inlining: we + * may end up inlining the trunk and not the leaves of the call tree, + * because we inlined too much before. Poor performance is the result. + * Real solution is bottom up inlining; here we just use a better + * heuristics: don't cut off inlining completely, but drop it off + * slowly. The further we are beyond the max limit the smaller the + * function needs to be to still get inlined. + */ + int max_inline_single = MAX_INLINE_INSNS/2; + int max_inline_recursive = MAX_INLINE_INSNS; + /* Functions that small can always be inlined: + * We have to trade arg saving and the call and ret insns against + * the function length itself, here. + */ + int min_inline = 130; + /* If we've already decided this function shouldn't be inlined, there's no need to check again. */ if (DECL_UNINLINABLE (fn)) @@ -641,7 +657,7 @@ else if (varargs_function_p (fn)) ; /* We can't inline functions that are too big. */ - else if (DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS) + else if (DECL_NUM_STMTS (fn) * INSNS_PER_STMT > max_inline_single) ; /* All is well. We can inline this function. Traditionally, GCC has refused to inline functions using alloca, or functions whose @@ -655,11 +671,22 @@ /* Even if this function is not itself too big to inline, it might be that we've done so much inlining already that we don't want to - risk inlining any more. */ - if ((DECL_NUM_STMTS (fn) + id->inlined_stmts) * INSNS_PER_STMT - > MAX_INLINE_INSNS) - inlinable = 0; - + risk inlining any more. + Only if it's smaller tham min_inline, we still go ahead, unless + we're really far beyond the recursive inlining limit. */ + if ((DECL_NUM_STMTS (fn) + id->inlined_stmts) * INSNS_PER_STMT + > max_inline_recursive + && ( DECL_NUM_STMTS (fn) * INSNS_PER_STMT > min_inline + || (DECL_NUM_STMTS (fn) + id->inlined_stmts) * INSNS_PER_STMT + > max_inline_recursive * 64 ) ) { + /* Use a linear function with a slope of -0.0625 + * we could also use an int approx of sqrt or similar things */ + signed int max_curr = max_inline_single + - ( (DECL_NUM_STMTS (fn) + id->inlined_stmts) * INSNS_PER_STMT + - max_inline_recursive ) / 16; + if ((signed int)(DECL_NUM_STMTS (fn) * INSNS_PER_STMT) > max_curr) + inlinable = 0; + } /* We can inline a template instantiation only if it's fully instantiated. */ if (inlinable --- ./gcc/cp/ChangeLog.orig Mon Aug 20 20:48:06 2001 +++ ./gcc/cp/ChangeLog Wed Aug 22 20:32:01 2001 @@ -1,3 +1,10 @@ +2001-08-22 Kurt Garloff + + * optimize.c (inlinable_function_p): Change heuristics of inlining: + Rather than allow one single function to exhaust the limit, + allow only half way. Afterwards don't cut abruptly, but get + more and more restrictive until a minimum size. + 2001-08-19 Release Manager * GCC 3.0.1 Released. --- ./gcc/cp/NEWS.orig Wed Aug 22 20:37:43 2001 +++ ./gcc/cp/NEWS Wed Aug 22 20:37:14 2001 @@ -1,3 +1,13 @@ +*** Changes in GCC 3.0.2: + +* The meaning of the -finline-limit changed for C++: We allow single + functions up to half the size. Once we have exhausted the size by + recursive inlining, we start to decrease the acceptable size for + inlining slowly up to until we're at 8 times the number. Then only + very small functions are still inlined. + Results in much improved C++ runtime performance (with about the + same compile time). + *** Changes in GCC 3.0.1: * -fhonor-std and -fno-honor-std have been removed. -fno-honor-std was --- gcc/doc/invoke.texi.orig Mon Aug 20 20:48:10 2001 +++ gcc/doc/invoke.texi Wed Aug 29 14:22:30 2001 @@ -3288,6 +3288,15 @@ means slower programs). This option is particularly useful for programs that use inlining heavily such as those based on recursive templates with C++. +Note that for C++, the rules are slightly more complicated. The +maximum size of a function that may be inlined is half of @var{n}. +For recursive inlining, we start to decrease the acceptable size for +inlining once we have inlined @var{n} pseudo instructions until we reach +many times @var{n}. Then only very small functions may still be inlined. +Experimenting with this parameter may be useful to improve +runtime performance (e.g. @var{n}=1500) or to decrease the size of the +executable (e.g. @var{n}=260). + @emph{Note:} pseudo instruction represents, in this particular context, an abstract measurement of function's size. In no way, it represents a count of assembly instructions and as such its exact meaning might change from one