This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Zero/Sign extension elimination using value ranges
- From: Kugan <kugan dot vivekanandarajah at linaro dot org>
- To: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Cc: Richard Biener <richard dot guenther at gmail dot com>, Jakub Jelinek <jakub at redhat dot com>, Eric Botcazou <ebotcazou at adacore dot com>
- Date: Tue, 20 May 2014 12:27:31 +1000
- Subject: Zero/Sign extension elimination using value ranges
- Authentication-results: sourceware.org; auth=none
This is based on my earlier patch
https://gcc.gnu.org/ml/gcc-patches/2013-10/msg00452.html. Before I post
the new set of patches, I would like to make sure that I understood
review comments and my idea makes sense and acceptable. Please let me
know If I am missing anything or my assumptions are wrong.
To recap the basic idea, when GIMPLE_ASSIGN stmts are expanded to RTL,
if we can prove that zero/sign extension to fit the type is redundant,
we can generate RTL without it. For example, when an expression is
evaluated and it's value is assigned to variable of type short, the
generated RTL currently look similar to (set (reg:SI 110)
(zero_extend:SI (subreg:HI (reg:SI 117) 0))). Using value ranges, if we
can show that the value of the expression which is present in register
117 is within the limits of short and there is no sign conversion, we do
not need to perform zero_extend.
Cases to handle here are :
1. Handling NOP_EXPR or CONVERT_EXPR that are in the IL because they
are required for type correctness. We have two cases here:
A) Mode is smaller than word_mode. This is usually from where the
zero/sign extensions are showing up in final assembly.
For example :
int = (int) short
which usually expands to
(set (reg:SI )
(sext:SI (subreg:HI (reg:SI ))))
We can expand this
(set (reg:SI ) (((reg:SI ))))
If following is true:
1. Value stored in RHS and LHS are of the same signedness
2. Type can hold the value. i.e., In cases like char = (char) short, we
check that the value in short is representable char type. (i.e. look at
the value range in RHS SSA_NAME and see if that can be represented in
types of LHS without overflowing)
Subreg here is not a paradoxical subreg. We are removing the subreg and
zero/sign extend here.
I am assuming here that QI/HI registers are represented in SImode
(basically word_mode) with zero/sign extend is used as in
(zero_extend:SI (subreg:HI (reg:SI 117)).
B) Mode is larger than word_mode
long = (long) int
which usually expands to
(set:DI (sext:DI (reg:SI)))
We have to expand this as paradoxical subreg
(set:DI (subreg:DI (reg:SI)))
I am not sure that these cases results in actual zero/sign extensions
being generated. Therefore I think we should skip this case altogether.
2. Second are promotions required by the target (PROMOTE_MODE) that do
arithmetic on wider registers like:
char = char + char
In this case we will have the value ranges of RHS char1 and char2. We
will have to compute the value range of (char1 + char2) in promoted mode
(from the values range stored in char1 SSANAME and char2 SSA_NAME) and
see if that value range can be represented in LHS type.
Once again, if following is true, we can remove the subreg and zero/sign
extension in assignment:
1. Value stored in RHS and LHS are of the same signedness
2. Type can hold the value.
And also, when LHS is promoted and thus the target is (subreg:XX N),
RHS has been expanded in XXmode. Dependent on the value-range and mode
XX which is bigger than word mode, set this to a paradoxical subreg of
the expanded result. However, since we are only interested in XXmode
lesser than word_mode (that is where most of the final zero/sign
extension asm are coming from), we don’t have to consider paradoxical
subreg here.
Does this make sense?
Thanks,
Kugan