Message ID | 20190709223000.GA18842@ibm-toto.the-meissners.org |
---|---|
State | New |
Headers | show |
Series | , PowerPC, Patch #6, Create pc-relative addressing insns | expand |
Hi Mike, On Tue, Jul 09, 2019 at 06:30:00PM -0400, Michael Meissner wrote: > @@ -8760,12 +8762,34 @@ rs6000_cannot_force_const_mem (machine_m > static bool > use_toc_relative_ref (rtx sym, machine_mode mode) > { > - return ((constant_pool_expr_p (sym) > - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), > - get_pool_mode (sym))) > - || (TARGET_CMODEL == CMODEL_MEDIUM > - && SYMBOL_REF_LOCAL_P (sym) > - && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT)); > + if (!SYMBOL_REF_P (sym) || TARGET_PCREL || !TARGET_TOC) > + return false; Why the SYMBOL_REF test? The original didn't have any. But its comment says /* Return true iff the given SYMBOL_REF refers to a constant pool entry that we have put in the TOC, or for cmodel=medium, if the SYMBOL_REF can be addressed relative to the toc pointer. */ so perhaps you want an assert instead. > + > + if (constant_pool_expr_p (sym) > + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), > + get_pool_mode (sym))) > + return true; > + > + return (TARGET_CMODEL == CMODEL_MEDIUM && SYMBOL_REF_LOCAL_P (sym) > + && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT); Please don't put disparate things on one line, it was fine before. > +/* Return true iff the given SYMBOL_REF refers to a constant pool entry that we > + have put in the pc-relative constant area, or for cmodel=medium, if the > + SYMBOL_REF can be addressed via pc-relative instructions. */ > + > +static bool > +use_pc_relative_ref (rtx sym) > +{ > + if (!SYMBOL_REF_P (sym) || !TARGET_PCREL) > + return false; Same here, assert please. Or nothing, it will ICE not much later anyway. But don't silently return if something violates the call contract. > -static GTY(()) alias_set_type set = -1; > +/* Return the alias set for constants stored in either the TOC or via > + pc-relative addressing. */ > +static GTY(()) alias_set_type data_alias_set = -1; Please just make a separate alias set for pcrel. The new name isn't as bad as just "set" :-), but "data"? That's not great either. Conflating toc and pcrel isn't a good thing. (Variables don't "return" anything btw). > > alias_set_type > -get_TOC_alias_set (void) > +get_data_alias_set (void) This name is much worse than the old one. Just make separate functions for TOC and for pcrel? Or is there any reason you want to share them? Segher
On Wed, Jul 10, 2019 at 12:11:49PM -0500, Segher Boessenkool wrote: > Hi Mike, > > On Tue, Jul 09, 2019 at 06:30:00PM -0400, Michael Meissner wrote: > > @@ -8760,12 +8762,34 @@ rs6000_cannot_force_const_mem (machine_m > > static bool > > use_toc_relative_ref (rtx sym, machine_mode mode) > > { > > - return ((constant_pool_expr_p (sym) > > - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), > > - get_pool_mode (sym))) > > - || (TARGET_CMODEL == CMODEL_MEDIUM > > - && SYMBOL_REF_LOCAL_P (sym) > > - && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT)); > > + if (!SYMBOL_REF_P (sym) || TARGET_PCREL || !TARGET_TOC) > > + return false; > > Why the SYMBOL_REF test? The original didn't have any. But its comment > says > /* Return true iff the given SYMBOL_REF refers to a constant pool entry > that we have put in the TOC, or for cmodel=medium, if the SYMBOL_REF > can be addressed relative to the toc pointer. */ > so perhaps you want an assert instead. The only two callers had a test for SYMBOL_REF_P. By moving it into the function, it made the call to the function one line instead of two. But I can go back to the previous method. > > + > > + if (constant_pool_expr_p (sym) > > + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), > > + get_pool_mode (sym))) > > + return true; > > + > > + return (TARGET_CMODEL == CMODEL_MEDIUM && SYMBOL_REF_LOCAL_P (sym) > > + && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT); > > Please don't put disparate things on one line, it was fine before. I'm not sure what you mean, I was just trying to break up a long if statement. > > +/* Return true iff the given SYMBOL_REF refers to a constant pool entry that we > > + have put in the pc-relative constant area, or for cmodel=medium, if the > > + SYMBOL_REF can be addressed via pc-relative instructions. */ > > + > > +static bool > > +use_pc_relative_ref (rtx sym) > > +{ > > + if (!SYMBOL_REF_P (sym) || !TARGET_PCREL) > > + return false; > > Same here, assert please. Or nothing, it will ICE not much later anyway. > But don't silently return if something violates the call contract. Again, this was meant to simplify the call. > > -static GTY(()) alias_set_type set = -1; > > +/* Return the alias set for constants stored in either the TOC or via > > + pc-relative addressing. */ > > +static GTY(()) alias_set_type data_alias_set = -1; > > Please just make a separate alias set for pcrel. The new name isn't as > bad as just "set" :-), but "data"? That's not great either. Conflating > toc and pcrel isn't a good thing. > > (Variables don't "return" anything btw). > > > > > alias_set_type > > -get_TOC_alias_set (void) > > +get_data_alias_set (void) > > This name is much worse than the old one. Just make separate functions > for TOC and for pcrel? Or is there any reason you want to share them? Well in theory, an object file that contains some functions wtih pc-relative and some with TOC (due to #pragma target or attribute), using the same data set would flag that they are related, but I imagine in practice the two uses don't mix. It was more of a hangover from trying to have one function to create both addressing forms.
On Wed, Jul 10, 2019 at 01:56:07PM -0400, Michael Meissner wrote: > On Wed, Jul 10, 2019 at 12:11:49PM -0500, Segher Boessenkool wrote: > > On Tue, Jul 09, 2019 at 06:30:00PM -0400, Michael Meissner wrote: > > > @@ -8760,12 +8762,34 @@ rs6000_cannot_force_const_mem (machine_m > > > static bool > > > use_toc_relative_ref (rtx sym, machine_mode mode) > > > { > > > - return ((constant_pool_expr_p (sym) > > > - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), > > > - get_pool_mode (sym))) > > > - || (TARGET_CMODEL == CMODEL_MEDIUM > > > - && SYMBOL_REF_LOCAL_P (sym) > > > - && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT)); > > > + if (!SYMBOL_REF_P (sym) || TARGET_PCREL || !TARGET_TOC) > > > + return false; > > > > Why the SYMBOL_REF test? The original didn't have any. But its comment > > says > > /* Return true iff the given SYMBOL_REF refers to a constant pool entry > > that we have put in the TOC, or for cmodel=medium, if the SYMBOL_REF > > can be addressed relative to the toc pointer. */ > > so perhaps you want an assert instead. > > The only two callers had a test for SYMBOL_REF_P. By moving it into the > function, it made the call to the function one line instead of two. But I can > go back to the previous method. It makes more sense with the param as a symbol always (the function comment says it is, too, and the "sym" name suggests it is). So yes, please go back to that. Reducing number of lines of code isn't a goal; reducing complexity is, reducing astonishment. > > > + > > > + if (constant_pool_expr_p (sym) > > > + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), > > > + get_pool_mode (sym))) > > > + return true; > > > + > > > + return (TARGET_CMODEL == CMODEL_MEDIUM && SYMBOL_REF_LOCAL_P (sym) > > > + && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT); > > > > Please don't put disparate things on one line, it was fine before. > > I'm not sure what you mean, I was just trying to break up a long if statement. "TARGET_CMODEL == CMODEL_MEDIUM" and "SYMBOL_REF_LOCAL_P (sym)" are quite different things. > > > -static GTY(()) alias_set_type set = -1; > > > +/* Return the alias set for constants stored in either the TOC or via > > > + pc-relative addressing. */ > > > +static GTY(()) alias_set_type data_alias_set = -1; > > > > Please just make a separate alias set for pcrel. The new name isn't as > > bad as just "set" :-), but "data"? That's not great either. Conflating > > toc and pcrel isn't a good thing. > > > > (Variables don't "return" anything btw). > > > > > alias_set_type > > > -get_TOC_alias_set (void) > > > +get_data_alias_set (void) > > > > This name is much worse than the old one. Just make separate functions > > for TOC and for pcrel? Or is there any reason you want to share them? > > Well in theory, an object file that contains some functions wtih pc-relative > and some with TOC (due to #pragma target or attribute), using the same data set > would flag that they are related, but I imagine in practice the two uses don't > mix. It was more of a hangover from trying to have one function to create both > addressing forms. I think it would make things quite a bit simpler if you split them up. Could you please try that? Segher
Index: gcc/config/rs6000/rs6000-protos.h =================================================================== --- gcc/config/rs6000/rs6000-protos.h (revision 273255) +++ gcc/config/rs6000/rs6000-protos.h (working copy) @@ -189,7 +189,7 @@ extern void rs6000_gen_section_name (cha extern void output_function_profiler (FILE *, int); extern void output_profile_hook (int); extern int rs6000_trampoline_size (void); -extern alias_set_type get_TOC_alias_set (void); +extern alias_set_type get_data_alias_set (void); extern void rs6000_emit_prologue (void); extern void rs6000_emit_load_toc_table (int); extern unsigned int rs6000_dbx_register_number (unsigned int, unsigned int); Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 273310) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -7740,6 +7740,8 @@ create_TOC_reference (rtx symbol, rtx la { rtx tocrel, tocreg, hi; + gcc_assert (TARGET_TOC && !TARGET_PCREL); + if (TARGET_DEBUG_ADDR) { if (SYMBOL_REF_P (symbol)) @@ -8137,7 +8139,7 @@ rs6000_legitimize_address (rtx x, rtx ol emit_insn (gen_macho_high (reg, x)); return gen_rtx_LO_SUM (Pmode, reg, x); } - else if (TARGET_TOC + else if (TARGET_TOC && !TARGET_PCREL && SYMBOL_REF_P (x) && constant_pool_expr_p (x) && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode)) @@ -8441,7 +8443,7 @@ rs6000_legitimize_tls_address_aix (rtx a { tocref = create_TOC_reference (XEXP (sym, 0), NULL_RTX); mem = gen_const_mem (Pmode, tocref); - set_mem_alias_set (mem, get_TOC_alias_set ()); + set_mem_alias_set (mem, get_data_alias_set ()); } else return sym; @@ -8459,7 +8461,7 @@ rs6000_legitimize_tls_address_aix (rtx a SYMBOL_REF_FLAGS (modaddr) |= SYMBOL_FLAG_LOCAL; tocref = create_TOC_reference (modaddr, NULL_RTX); rtx modmem = gen_const_mem (Pmode, tocref); - set_mem_alias_set (modmem, get_TOC_alias_set ()); + set_mem_alias_set (modmem, get_data_alias_set ()); rtx modreg = gen_reg_rtx (Pmode); emit_insn (gen_rtx_SET (modreg, modmem)); @@ -8760,12 +8762,34 @@ rs6000_cannot_force_const_mem (machine_m static bool use_toc_relative_ref (rtx sym, machine_mode mode) { - return ((constant_pool_expr_p (sym) - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), - get_pool_mode (sym))) - || (TARGET_CMODEL == CMODEL_MEDIUM - && SYMBOL_REF_LOCAL_P (sym) - && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT)); + if (!SYMBOL_REF_P (sym) || TARGET_PCREL || !TARGET_TOC) + return false; + + if (constant_pool_expr_p (sym) + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), + get_pool_mode (sym))) + return true; + + return (TARGET_CMODEL == CMODEL_MEDIUM && SYMBOL_REF_LOCAL_P (sym) + && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT); +} + +/* Return true iff the given SYMBOL_REF refers to a constant pool entry that we + have put in the pc-relative constant area, or for cmodel=medium, if the + SYMBOL_REF can be addressed via pc-relative instructions. */ + +static bool +use_pc_relative_ref (rtx sym) +{ + if (!SYMBOL_REF_P (sym) || !TARGET_PCREL) + return false; + + if (constant_pool_expr_p (sym) + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), + get_pool_mode (sym))) + return true; + + return (TARGET_CMODEL == CMODEL_MEDIUM && SYMBOL_REF_LOCAL_P (sym)); } /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression @@ -9865,10 +9889,14 @@ rs6000_emit_move (rtx dest, rtx source, /* If this is a SYMBOL_REF that refers to a constant pool entry, and we have put it in the TOC, we just need to make a TOC-relative reference to it. */ - if (TARGET_TOC - && SYMBOL_REF_P (operands[1]) - && use_toc_relative_ref (operands[1], mode)) + if (use_toc_relative_ref (operands[1], mode)) operands[1] = create_TOC_reference (operands[1], operands[0]); + + /* If this is a pc-relative reference, we don't have to do anything + fancy. */ + else if (use_pc_relative_ref (operands[1])) + ; + else if (mode == Pmode && CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != HIGH @@ -9919,14 +9947,18 @@ rs6000_emit_move (rtx dest, rtx source, operands[1] = force_const_mem (mode, operands[1]); - if (TARGET_TOC - && SYMBOL_REF_P (XEXP (operands[1], 0)) - && use_toc_relative_ref (XEXP (operands[1], 0), mode)) + rtx addr = XEXP (operands[1], 0); + if (use_toc_relative_ref (addr, mode)) { - rtx tocref = create_TOC_reference (XEXP (operands[1], 0), - operands[0]); + rtx tocref = create_TOC_reference (addr, operands[0]); operands[1] = gen_const_mem (mode, tocref); - set_mem_alias_set (operands[1], get_TOC_alias_set ()); + set_mem_alias_set (operands[1], get_data_alias_set ()); + } + + else if (use_pc_relative_ref (addr)) + { + operands[1] = gen_const_mem (mode, addr); + set_mem_alias_set (operands[1], get_data_alias_set ()); } } break; @@ -23732,14 +23764,16 @@ rs6000_split_multireg_move (rtx dst, rtx } } -static GTY(()) alias_set_type set = -1; +/* Return the alias set for constants stored in either the TOC or via + pc-relative addressing. */ +static GTY(()) alias_set_type data_alias_set = -1; alias_set_type -get_TOC_alias_set (void) +get_data_alias_set (void) { - if (set == -1) - set = new_alias_set (); - return set; + if (data_alias_set == -1) + data_alias_set = new_alias_set (); + return data_alias_set; } /* Return the internal arg pointer used for function incoming Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (revision 273255) +++ gcc/config/rs6000/rs6000.md (working copy) @@ -11606,15 +11606,23 @@ (define_insn_and_split "*cmp<mode>_inter operands[15] = force_const_mem (DFmode, const_double_from_real_value (dconst0, DFmode)); - if (TARGET_TOC) + if (TARGET_PCREL) + { + operands[14] = gen_const_mem (DFmode, XEXP (operands[14], 0)); + operands[15] = gen_const_mem (DFmode, XEXP (operands[15], 0)); + set_mem_alias_set (operands[14], get_data_alias_set ()); + set_mem_alias_set (operands[15], get_data_alias_set ()); + } + + else if (TARGET_TOC) { rtx tocref; tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]); operands[14] = gen_const_mem (DFmode, tocref); tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]); operands[15] = gen_const_mem (DFmode, tocref); - set_mem_alias_set (operands[14], get_TOC_alias_set ()); - set_mem_alias_set (operands[15], get_TOC_alias_set ()); + set_mem_alias_set (operands[14], get_data_alias_set ()); + set_mem_alias_set (operands[15], get_data_alias_set ()); } })