This is the mail archive of the gcc@gcc.gnu.org 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]

Zero/Sign extension elimination using value ranges


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


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