On 11/13/20 1:18 AM, Richard Sandiford via Gcc-patches wrote: > One of the recurring warts of RTL is that multiplication by a power > of 2 is represented as a MULT inside a MEM but as an ASHIFT outside > a MEM. It would obviously be better if we didn't have this kind of > context sensitivity, but it would be difficult to remove. > > Currently the simplify-rtx.c routines are hard-coded for the > ASHIFT form. This means that some callers have to convert the > ASHIFTs “back” into MULTs after calling the simplify-rtx.c > routines; see fwprop.c:canonicalize_address for an example. > > I think we can relieve some of the pain by wrapping the simplify-rtx.c > routines in a simple class that tracks whether the expression occurs > in a MEM or not, so that no post-processing is needed. > > An obvious concern is whether passing the “this” pointer around > will slow things down or bloat the code. I can't measure any > increase in compile time after applying the patch. Sizewise, > simplify-rtx.o text increases by 2.3% in default-checking builds > and 4.1% in release-checking builds. > > I realise the MULT/ASHIFT thing isn't the most palatable > reason for doing this, but I think it might be useful for > other things in future, such as using local nonzero_bits > hooks/virtual functions instead of the global hooks. > > The obvious alternative would be to add a static variable > and hope that it is always updated correctly. I think a static would be step in the wrong direction and I'm generally in favor using classes, particularly when there's contextual information we want to query. Shoving things into a class allows us to reason about when/how that contextual information is used. > > Later patches make use of this. > > gcc/ > * rtl.h (simplify_context): New class. > (simplify_unary_operation, simplify_binary_operation): Use it. > (simplify_ternary_operation, simplify_relational_operation): Likewise. > (simplify_subreg, simplify_gen_unary, simplify_gen_binary): Likewise. > (simplify_gen_ternary, simplify_gen_relational): Likewise. > (simplify_gen_subreg, lowpart_subreg): Likewise. > * simplify-rtx.c (simplify_gen_binary): Turn into a member function > of simplify_context. > (simplify_gen_unary, simplify_gen_ternary, simplify_gen_relational) > (simplify_truncation, simplify_unary_operation): Likewise. > (simplify_unary_operation_1, simplify_byte_swapping_operation) > (simplify_associative_operation, simplify_logical_relational_operation) > (simplify_binary_operation, simplify_binary_operation_series) > (simplify_distributive_operation, simplify_plus_minus): Likewise. > (simplify_relational_operation, simplify_relational_operation_1) > (simplify_cond_clz_ctz, simplify_merge_mask): Likewise. > (simplify_ternary_operation, simplify_subreg, simplify_gen_subreg) > (lowpart_subreg): Likewise. > (simplify_binary_operation_1): Likewise. Test mem_depth when > deciding whether the ASHIFT or MULT form is canonical. > (simplify_merge_mask): Use simplify_context. I like it. OK for the trunk. jeff