This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Very simple constant propagation (revisited)

This patch is to address an efficiency problem in gcc. If you compile the following small loop
with -O3 -ffast-math, the optimizer converts the "a/b" into "a * 1/b", in the hopes of being
able to do some further optimizations. In this case it can't so ideally the combiner should
convert "a * 1/b" back into "a/b". Unfortunately, it can't figure out that it can do that because
the combiner only looks within the current basic block, and the constant 1 has been hoisted
out of the loop. This is unfortunate, because it causes an extra floating point multiplication to
be performed in every iteration of this loop, which is a major performance hit in the code this
originally came from. To fix this problem, I have implemented a very tiny, very specific,
very simple version of constant propagation: It goes over the RTL looking for a register that
is assigned a constant value once, and is never re-assigned another value anywhere in the
instructions for the function. For lack of a better name I called these "single set constants".
Whenever I find such a Single Set Constant, I replace uses of that register with the constant
value. This is performed just before the combiner is run, and it does fix this problem.

The test code for this problem is:

float *a, *b;

float foo () {
int i;
float sum = 1.0;
for (i = 0; i < 4; i++)
sum *= a[i]/b[i];

I originally submitted a version of this patch in January. Roger Sayle submitted an alternate patch that
we thought solved the same problem. After some performance investigations and other comparisons
we decided tentatively to go with Roger's patch. However Roger and I recently discovered that neither
version solved the problem on the i386 platform, which generated some (at least for me) unexpected code
sequences. On further investigation it appears to me that Roger's patch cannot be made to work on the
i386 without significant modifications to combine. Therefore I updated my patch to work on the i386 and
am now re-submitting it.

This patch has been tested on both the Apple G4, running apple-darwin, and in an i386 running Linux.
On both platform it bootstraps, solves the problem described above for our specific test cases, and successfully
passes all the SPEC Int tests (using this constant propagation) which 3.5 passes (without the propagation).
I am in the middle of running the DejaGnu tests on both platforms. Assuming it passes the DejaGnu tests,
is this okay to commit to mainline 3.5?

-- Caroline Tice

2004-03-02 Caroline Tice <>

* (const-prop.o): Add new file and instructions for
compiling the file.
* combine.c (try_combine): Initialize i2pat, and update
single-set constant information when appropriate.
* common.opt (fss-const-prop): Add new option.
* flags.h (flag_ss_const_prop): Add new flag.
* function.h (find_all_single_set_constants): New extern function
(cleanup_ss_constant_propagation): Likewise.
(ss_replace_assignment): Likewise.
(ss_constant_propagation): Likewise.
* opts.c (decode_options): Set flag_ss_const_prop if -O2 or
(common_handle_option): Add code to set flag_ss_const_prop.
* passes.c (rest_of_handle_combine): Add code to initialize
and clean up data structures for single-set constant propagation.
* simplify-rtx (simplify_binary_operation): Add calls to
* toplev.c (flag_ss_constant_propagation): New flag.
(f_options): Add flag_ss_constant_propagation to table.
* const-prop.c (All): New source file containing the code to
implement single-set constant propagation.
(initialize_const_prop_info): New function.
(process_assignment): New function.
(find_all_single_set_constants): New function.
(ss_replace_assignment): New function.
(ss_constant_propagation): New function.
(cleanup_ss_constant_propagation): New function.

Attachment: gcc5-const-prop.txt
Description: Text document

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]