From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8218 invoked by alias); 29 Jul 2003 12:25:27 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 8205 invoked from network); 29 Jul 2003 12:25:26 -0000 Received: from unknown (HELO steven.lr-s.tudelft.nl) (62.234.22.215) by sources.redhat.com with SMTP; 29 Jul 2003 12:25:26 -0000 Received: from steven.lr-s.tudelft.nl (localhost.localdomain [127.0.0.1]) by steven.lr-s.tudelft.nl (8.12.8/8.12.8) with ESMTP id h6TCRTiU030788; Tue, 29 Jul 2003 14:27:29 +0200 Received: (from steven@localhost) by steven.lr-s.tudelft.nl (8.12.8/8.12.8/Submit) id h6TCRS2K030786; Tue, 29 Jul 2003 14:27:28 +0200 X-Authentication-Warning: steven.lr-s.tudelft.nl: steven set sender to s.bosscher@student.tudelft.nl using -f Subject: Re: std::pow implementation From: Steven Bosscher To: Gabriel Dos Reis Cc: Richard Guenther , gcc@gcc.gnu.org In-Reply-To: References: Content-Type: text/plain Content-Transfer-Encoding: 7bit Message-Id: <1059481647.3651.120.camel@steven.lr-s.tudelft.nl> Mime-Version: 1.0 Date: Tue, 29 Jul 2003 12:53:00 -0000 X-SW-Source: 2003-07/txt/msg01971.txt.bz2 Op di 29-07-2003, om 14:04 schreef Gabriel Dos Reis: > Richard Guenther writes: > > | for my scientific app. If this ends up the same way as the > | __attribute__((leafify)) discussion, I'll stop complaining now and instead > | just file a PR for the record. > > I bet your application will benefit much more from a better inlining > support in the compiler than obfuscating the library. > (Note that it need not be a sophisticated inliner). We get to that point > because, at some point it was decided that the compiler knows better > than the programmer. Can you stop bashing and be reasonable for once? If you were so great you would have declated __cmath_power inline in the first place. If I do that, and compile with the tree-ssa branch at -O3 for this test case: ============================================= namespace std { // NB inline keyword which is not in libstdc++v3 __cmath_power template inline _Tp __cmath_power(_Tp __x, unsigned int __n) { _Tp __y = __n % 2 ? __x : 1; while (__n >>= 1) { __x = __x * __x; if (__n % 2) __y = __y * __x; } return __y; } template inline _Tp __pow_helper(_Tp __x, int __n) { return __n < 0 ? _Tp(1)/__cmath_power(__x, -__n) : __cmath_power(__x, __n); } inline double pow(double __x, int __i) { return __pow_helper(__x, __i); } } double foo(double x) { return std::pow(x, 2); } ============================================= I get the following tree dump after inlining: ============================================= ;; Function double foo(double) (_Z3food) double foo(double) (x) { double retval.12; double retval.11; double retval.10; double retval.9; { { int __i; double __x; double ; __x = x; __i = 2; { double T.1; { { int __n; double __x; double ; __x = __x; __n = __i; { double iftmp.4; int T.5; unsigned int T.6; double T.7; unsigned int __n.8; { if (__n < 0) { T.5 = -__n; T.6 = (unsigned int)T.5; { unsigned int __n; double __x; double ; __x = __x; __n = T.6; { double iftmp.2; unsigned int T.3; { double __y; T.3 = __n % 2; if (T.3 != 0) { iftmp.2 = __x } else { iftmp.2 = 1.0e+0 }; __y = iftmp.2; while (1) { __n = __n >> 1; if (__n == 0) { goto ; } else { (void)0 }; { { __x = __x * __x; { T.3 = __n % 2; if (T.3 != 0) { { __y = __y * __x } } else { (void)0 } } } } }; :;; { = __y; goto ; } } }; :;; retval.11 = }; T.7 = retval.11; iftmp.4 = 1.0e+0 / T.7 } else { __n.8 = (unsigned int)__n; { unsigned int __n; double __x; double ; __x = __x; __n = __n.8; { double iftmp.2; unsigned int T.3; { double __y; T.3 = __n % 2; if (T.3 != 0) { iftmp.2 = __x } else { iftmp.2 = 1.0e+0 }; __y = iftmp.2; while (1) { __n = __n >> 1; if (__n == 0) { goto ; } else { (void)0 }; { { __x = __x * __x; { T.3 = __n % 2; if (T.3 != 0) { { __y = __y * __x } } else { (void)0 } } } } }; :;; { = __y; goto ; } } }; :;; retval.12 = }; iftmp.4 = retval.12 }; (void)0; { = iftmp.4; goto ; } } }; :;; retval.10 = }; T.1 = retval.10; (void)0; { = T.1; goto ; } } }; :;; retval.9 = }; return retval.9; } } ============================================= which looks like this after tree-optimizing: ============================================= ;; Function double foo(double) (_Z3food) double foo(double) (x) { { { if (0) { { (void)0 } } else { { unsigned int __n; double __x; { unsigned int T.3; { double __y; __x = x; __y = 1.0e+0; __n = 2; while (1) { __n = __n >> 1; if (__n == 0) { goto ; } else { (void)0 }; __x = __x * __x; T.3 = __n % 2; if (T.3 != 0) { __y = __y * __x } else { (void)0 } }; :; } }; :; } }; :; }; :; }; return __y; } ============================================= Now cut away all the redundant labels and other cruft, and you end up with: ;; Function double foo(double) (_Z3food) double foo(double) (x) { unsigned int __n; double __x; unsigned int T.3; double __y; __x = x; __y = 1.0e+0; __n = 2; while (1) { __n = __n >> 1; if (__n == 0) goto ; __x = __x * __x; T.3 = __n % 2; if (T.3 != 0) __y = __y * __x } :; return __y; } which is exactly what you want, is it not?? Gr. Steven