Related articles |
---|
Re: Are C logical operators being lowered too soon? cdg@nullstone.com (1995-02-27) |
Newsgroups: | comp.compilers |
From: | cdg@nullstone.com (Christopher Glaeser) |
Keywords: | C, optimize |
Organization: | Compilers Central |
Refercenes: | 95-02-147 |
Date: | Mon, 27 Feb 1995 08:31:19 GMT |
cdg@nullstone.com (Christopher Glaeser) writes:
> The logical operators && and || are relatively common in C programs.
> However, analysis shows that many compilers fail to optimize
> expressions that contain logical operators.
Bill.Leonard@mail.hcsc.com (Bill Leonard) writes:
> ... the likelihood of finding a CSE
> opportunity for && or || is so low that this complication is just not worth
> it.
What evidence do you have to support the assertion that CSE opportunities
for && and || are not likely? Are you referring ONLY to the result of the
logical expression, or do you also include CSE's within a logical
expression, an example being ((e1 op e2) || (e1 op e3))?
When designing new compiler performance tests for Nullstone, I review
applications and benchmarks to better understand how various language
features are used. In a recent study of logical expressions, I observed
that logical expressions are common in some C applications, and CSE's
within logical expressions are also common.
Consider the GNU gcc compiler (which is both a *real* application and a
SPEC benchmark). This application defines approximately 1000 macros in
the header files. A random sampling suggests that about 15% of these
macros contain logical expressions, and over 50% of these logical
expressions contain CSE's.
An example is the following:
#define CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
|| (GET_CODE (X) == CONST \
&& ! (flag_pic && pic_address_needs_scratch (X))))
Note that the argument (X) is used six times across the logical expressions.
Scanning the .c source files reveals code fragments like the following:
... && CONSTANT_ADDRESS_P (XEXP (DECL_RTL (exp), 0)))) ...
When expanded, this code fragment becomes:
&& (((((((exp)->decl.rtl))->fld[0].rtx))->code) == LABEL_REF
|| ((((((exp)->decl.rtl))->fld[0].rtx))->code) == SYMBOL_REF
|| ((((((exp)->decl.rtl))->fld[0].rtx))->code) == CONST_INT
|| ((((((exp)->decl.rtl))->fld[0].rtx))->code) == HIGH
|| (((((((exp)->decl.rtl))->fld[0].rtx))->code) == CONST
&& ! (flag_pic && pic_address_needs_scratch (((((exp)->decl.rtl))->fld[0].rtx)))))))
return change_address (((exp)->decl.rtl) , VOIDmode,
copy_rtx (((((exp)->decl.rtl))->fld[0].rtx)));
This example is not contrived nor unique. Scanning other macro definitions
within gcc and other applications revealed many similar examples.
Best regards,
Christopher Glaeser
Nullstone Corporation
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.