home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.gcc.bug
- Path: sparky!uunet!cis.ohio-state.edu!twinsun.COM!eggert
- From: eggert@twinsun.COM (Paul Eggert)
- Subject: GCC 2.2.2 patch to improve quality of code for (expr&const)!=0
- Message-ID: <9209012310.AA22819@farside.twinsun.com>
- Sender: gnulists@ai.mit.edu
- Organization: GNUs Not Usenet
- Distribution: gnu
- Date: Tue, 1 Sep 1992 23:10:58 GMT
- Approved: bug-gcc@prep.ai.mit.edu
- Lines: 191
-
- The following patch uniformly improves the quality of the generated code for
- for all programs that I have looked at on my machine (Sparc, SunOS 4.1.2);
- this includes the entire GCC source code. For example, given the program
-
- void f() { if (g() & 32768) h(); }
-
- the patched GCC generates two fewer machine instructions by avoiding an
- unnecessary shift and compare, as follows (diff --side-by-side output):
-
- ----- GCC 2.2.2 ----- ----- GCC 2.2.2 with patch -----
- _f: _f:
- save %sp,-112,%sp save %sp,-112,%sp
- call _g,0 call _g,0
- nop nop
- sethi %hi(-32768),%o1 | sethi %hi(32768),%o1
- and %o0,%o1,%o0 | andcc %o0,%o1,%g0
- sll %o0,16,%o0 <
- cmp %o0,0 <
- be L2 be L2
- nop nop
- call _h,0 call _h,0
- nop nop
- L2: L2:
- ret ret
- restore restore
-
-
- I'm fairly sure the patch does not introduce a compiler bug on any 2's
- complement host, but I'm not sure whether it leads to better quality code on
- all hosts. If this patch loses on some hosts, perhaps a configuration
- variable is needed to include it conditionally.
-
-
- Tue Sep 1 22:55:59 1992 Paul Eggert (eggert@twinsun.com)
-
- * c-convert.c, cp-cvt.c (convert_to_integer): Prefer unsigned
- arithmetic if the output type is unsigned and is no more precise than
- the computation type. This avoids unnecessary sign extension.
-
- ===================================================================
- RCS file: c-convert.c,v
- retrieving revision 2.2
- diff -c -r2.2 c-convert.c
- *** c-convert.c 1992/04/21 18:00:03 2.2
- --- c-convert.c 1992/09/01 22:55:59
- ***************
- *** 232,242 ****
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa.
- ! Exception: if either of the original operands were
- unsigned then can safely do the work as unsigned.
- And we may need to do it as unsigned
- if we truncate to the original size. */
- ! typex = ((TREE_UNSIGNED (TREE_TYPE (expr))
- || TREE_UNSIGNED (TREE_TYPE (arg0))
- || TREE_UNSIGNED (TREE_TYPE (arg1)))
- ? unsigned_type (typex) : signed_type (typex));
- --- 232,247 ----
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa.
- ! Exception 1: if we will eventually truncate
- ! the result to unsigned, then do the work as unsigned;
- ! this can prevent unnecessary sign-extension.
- ! Exception 2: if either of the original operands were
- unsigned then can safely do the work as unsigned.
- And we may need to do it as unsigned
- if we truncate to the original size. */
- ! typex = (((outprec <= TYPE_PRECISION (typex)
- ! && TREE_UNSIGNED (type))
- ! || TREE_UNSIGNED (TREE_TYPE (expr))
- || TREE_UNSIGNED (TREE_TYPE (arg0))
- || TREE_UNSIGNED (TREE_TYPE (arg1)))
- ? unsigned_type (typex) : signed_type (typex));
- ***************
- *** 284,290 ****
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa. */
- ! typex = (TREE_UNSIGNED (TREE_TYPE (expr))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- build_unary_op (ex_form,
- --- 289,297 ----
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa. */
- ! typex = (((outprec <= TYPE_PRECISION (typex)
- ! && TREE_UNSIGNED (type))
- ! || TREE_UNSIGNED (TREE_TYPE (expr)))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- build_unary_op (ex_form,
- ***************
- *** 327,333 ****
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa. */
- ! typex = (TREE_UNSIGNED (TREE_TYPE (expr))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- fold (build (COND_EXPR, typex,
- --- 334,342 ----
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa. */
- ! typex = (((outprec <= TYPE_PRECISION (typex)
- ! && TREE_UNSIGNED (type))
- ! || TREE_UNSIGNED (TREE_TYPE (expr)))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- fold (build (COND_EXPR, typex,
- ===================================================================
- RCS file: cp-cvt.c,v
- retrieving revision 2.2
- diff -c -r2.2 cp-cvt.c
- *** cp-cvt.c 1992/04/23 03:18:58 2.2
- --- cp-cvt.c 1992/09/01 22:56:05
- ***************
- *** 831,842 ****
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa.
- ! Exception: if the original operands were unsigned
- ! then can safely do the work as unsigned.
- And we may need to do it as unsigned
- if we truncate to the original size. */
- ! typex = ((TREE_UNSIGNED (TREE_TYPE (expr))
- ! || TREE_UNSIGNED (TREE_TYPE (arg0)))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- build_binary_op_nodefault (ex_form,
- --- 831,848 ----
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa.
- ! Exception 1: if we will eventually truncate
- ! the result, then do the work as unsigned;
- ! this can prevent unnecessary sign-extension.
- ! Exception 2: if either of the original operands were
- ! unsigned then can safely do the work as unsigned.
- And we may need to do it as unsigned
- if we truncate to the original size. */
- ! typex = (((outprec <= TYPE_PRECISION (typex)
- ! && TREE_UNSIGNED (type))
- ! || TREE_UNSIGNED (TREE_TYPE (expr))
- ! || TREE_UNSIGNED (TREE_TYPE (arg0))
- ! || TREE_UNSIGNED (TREE_TYPE (arg1)))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- build_binary_op_nodefault (ex_form,
- ***************
- *** 883,889 ****
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa. */
- ! typex = (TREE_UNSIGNED (TREE_TYPE (expr))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- build_unary_op (ex_form,
- --- 889,897 ----
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa. */
- ! typex = (((outprec <= TYPE_PRECISION (typex)
- ! && TREE_UNSIGNED (type))
- ! || TREE_UNSIGNED (TREE_TYPE (expr)))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- build_unary_op (ex_form,
- ***************
- *** 926,932 ****
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa. */
- ! typex = (TREE_UNSIGNED (TREE_TYPE (expr))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- fold (build (COND_EXPR, typex,
- --- 934,942 ----
- {
- /* Don't do unsigned arithmetic where signed was wanted,
- or vice versa. */
- ! typex = (((outprec <= TYPE_PRECISION (typex)
- ! && TREE_UNSIGNED (type))
- ! || TREE_UNSIGNED (TREE_TYPE (expr)))
- ? unsigned_type (typex) : signed_type (typex));
- return convert (type,
- fold (build (COND_EXPR, typex,
-
-