ivopts: Call valid_mem_ref_p with ifn [PR110248]
As PR110248 shows, to get the expected query results for that internal functions LEN_{LOAD,STORE} is able to adopt some addressing modes, we need to pass down the related IFN code as well. This patch is to make IVOPTs pass down ifn code for USE_PTR_ADDRESS type uses, it adjusts the related functions {strict_,}memory_address_addr_space_p, and valid_mem_ref_p as well. PR tree-optimization/110248 gcc/ChangeLog: * recog.cc (memory_address_addr_space_p): Add one more argument ch of type code_helper and pass it to targetm.addr_space.legitimate_address_p instead of ERROR_MARK. (offsettable_address_addr_space_p): Update one function pointer with one more argument of type code_helper as its assignees memory_address_addr_space_p and strict_memory_address_addr_space_p have been adjusted, and adjust some call sites with ERROR_MARK. * recog.h (tree.h): New include header file for tree_code ERROR_MARK. (memory_address_addr_space_p): Adjust with one more unnamed argument of type code_helper with default ERROR_MARK. (strict_memory_address_addr_space_p): Likewise. * reload.cc (strict_memory_address_addr_space_p): Add one unnamed argument of type code_helper. * tree-ssa-address.cc (valid_mem_ref_p): Add one more argument ch of type code_helper and pass it to memory_address_addr_space_p. * tree-ssa-address.h (valid_mem_ref_p): Adjust the declaration with one more unnamed argument of type code_helper with default value ERROR_MARK. * tree-ssa-loop-ivopts.cc (get_address_cost): Use ERROR_MARK as code by default, change it with ifn code for USE_PTR_ADDRESS type use, and pass it to all valid_mem_ref_p calls.
This commit is contained in:
parent
165b1f6ad1
commit
4a8e6fa801
6 changed files with 31 additions and 19 deletions
13
gcc/recog.cc
13
gcc/recog.cc
|
@ -1802,8 +1802,8 @@ pop_operand (rtx op, machine_mode mode)
|
|||
for mode MODE in address space AS. */
|
||||
|
||||
bool
|
||||
memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
|
||||
rtx addr, addr_space_t as)
|
||||
memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED, rtx addr,
|
||||
addr_space_t as, code_helper ch)
|
||||
{
|
||||
#ifdef GO_IF_LEGITIMATE_ADDRESS
|
||||
gcc_assert (ADDR_SPACE_GENERIC_P (as));
|
||||
|
@ -1813,8 +1813,7 @@ memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
|
|||
win:
|
||||
return true;
|
||||
#else
|
||||
return targetm.addr_space.legitimate_address_p (mode, addr, 0, as,
|
||||
ERROR_MARK);
|
||||
return targetm.addr_space.legitimate_address_p (mode, addr, 0, as, ch);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2430,7 +2429,7 @@ offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
|
|||
rtx z;
|
||||
rtx y1 = y;
|
||||
rtx *y2;
|
||||
bool (*addressp) (machine_mode, rtx, addr_space_t) =
|
||||
bool (*addressp) (machine_mode, rtx, addr_space_t, code_helper) =
|
||||
(strictp ? strict_memory_address_addr_space_p
|
||||
: memory_address_addr_space_p);
|
||||
poly_int64 mode_sz = GET_MODE_SIZE (mode);
|
||||
|
@ -2469,7 +2468,7 @@ offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
|
|||
*y2 = plus_constant (address_mode, *y2, mode_sz - 1);
|
||||
/* Use QImode because an odd displacement may be automatically invalid
|
||||
for any wider mode. But it should be valid for a single byte. */
|
||||
good = (*addressp) (QImode, y, as);
|
||||
good = (*addressp) (QImode, y, as, ERROR_MARK);
|
||||
|
||||
/* In any case, restore old contents of memory. */
|
||||
*y2 = y1;
|
||||
|
@ -2504,7 +2503,7 @@ offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
|
|||
|
||||
/* Use QImode because an odd displacement may be automatically invalid
|
||||
for any wider mode. But it should be valid for a single byte. */
|
||||
return (*addressp) (QImode, z, as);
|
||||
return (*addressp) (QImode, z, as, ERROR_MARK);
|
||||
}
|
||||
|
||||
/* Return true if ADDR is an address-expression whose effect depends
|
||||
|
|
10
gcc/recog.h
10
gcc/recog.h
|
@ -20,6 +20,9 @@ along with GCC; see the file COPYING3. If not see
|
|||
#ifndef GCC_RECOG_H
|
||||
#define GCC_RECOG_H
|
||||
|
||||
/* For enum tree_code ERROR_MARK. */
|
||||
#include "tree.h"
|
||||
|
||||
/* Random number that should be large enough for all purposes. Also define
|
||||
a type that has at least MAX_RECOG_ALTERNATIVES + 1 bits, with the extra
|
||||
bit giving an invalid value that can be used to mean "uninitialized". */
|
||||
|
@ -200,11 +203,12 @@ extern void temporarily_undo_changes (int);
|
|||
extern void redo_changes (int);
|
||||
extern bool constrain_operands (int, alternative_mask);
|
||||
extern bool constrain_operands_cached (rtx_insn *, int);
|
||||
extern bool memory_address_addr_space_p (machine_mode, rtx, addr_space_t);
|
||||
extern bool memory_address_addr_space_p (machine_mode, rtx, addr_space_t,
|
||||
code_helper = ERROR_MARK);
|
||||
#define memory_address_p(mode,addr) \
|
||||
memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
|
||||
extern bool strict_memory_address_addr_space_p (machine_mode, rtx,
|
||||
addr_space_t);
|
||||
extern bool strict_memory_address_addr_space_p (machine_mode, rtx, addr_space_t,
|
||||
code_helper = ERROR_MARK);
|
||||
#define strict_memory_address_p(mode,addr) \
|
||||
strict_memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
|
||||
extern bool validate_replace_rtx_subexp (rtx, rtx, rtx_insn *, rtx *);
|
||||
|
|
|
@ -2162,7 +2162,7 @@ hard_reg_set_here_p (unsigned int beg_regno, unsigned int end_regno, rtx x)
|
|||
|
||||
bool
|
||||
strict_memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
|
||||
rtx addr, addr_space_t as)
|
||||
rtx addr, addr_space_t as, code_helper)
|
||||
{
|
||||
#ifdef GO_IF_LEGITIMATE_ADDRESS
|
||||
gcc_assert (ADDR_SPACE_GENERIC_P (as));
|
||||
|
|
|
@ -344,7 +344,7 @@ tree_mem_ref_addr (tree type, tree mem_ref)
|
|||
|
||||
bool
|
||||
valid_mem_ref_p (machine_mode mode, addr_space_t as,
|
||||
struct mem_address *addr)
|
||||
struct mem_address *addr, code_helper ch)
|
||||
{
|
||||
rtx address;
|
||||
|
||||
|
@ -352,7 +352,7 @@ valid_mem_ref_p (machine_mode mode, addr_space_t as,
|
|||
if (!address)
|
||||
return false;
|
||||
|
||||
return memory_address_addr_space_p (mode, address, as);
|
||||
return memory_address_addr_space_p (mode, address, as, ch);
|
||||
}
|
||||
|
||||
/* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR
|
||||
|
|
|
@ -31,7 +31,8 @@ extern rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
|
|||
extern rtx addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand);
|
||||
extern void get_address_description (tree, struct mem_address *);
|
||||
extern tree tree_mem_ref_addr (tree, tree);
|
||||
extern bool valid_mem_ref_p (machine_mode, addr_space_t, struct mem_address *);
|
||||
extern bool valid_mem_ref_p (machine_mode, addr_space_t, struct mem_address *,
|
||||
code_helper = ERROR_MARK);
|
||||
extern void move_fixed_address_to_symbol (struct mem_address *,
|
||||
class aff_tree *);
|
||||
tree create_mem_ref (gimple_stmt_iterator *, tree,
|
||||
|
|
|
@ -4704,17 +4704,25 @@ get_address_cost (struct ivopts_data *data, struct iv_use *use,
|
|||
/* Only true if ratio != 1. */
|
||||
bool ok_with_ratio_p = false;
|
||||
bool ok_without_ratio_p = false;
|
||||
code_helper code = ERROR_MARK;
|
||||
|
||||
if (use->type == USE_PTR_ADDRESS)
|
||||
{
|
||||
gcall *call = as_a<gcall *> (use->stmt);
|
||||
gcc_assert (gimple_call_internal_p (call));
|
||||
code = gimple_call_internal_fn (call);
|
||||
}
|
||||
|
||||
if (!aff_combination_const_p (aff_inv))
|
||||
{
|
||||
parts.index = integer_one_node;
|
||||
/* Addressing mode "base + index". */
|
||||
ok_without_ratio_p = valid_mem_ref_p (mem_mode, as, &parts);
|
||||
ok_without_ratio_p = valid_mem_ref_p (mem_mode, as, &parts, code);
|
||||
if (ratio != 1)
|
||||
{
|
||||
parts.step = wide_int_to_tree (type, ratio);
|
||||
/* Addressing mode "base + index << scale". */
|
||||
ok_with_ratio_p = valid_mem_ref_p (mem_mode, as, &parts);
|
||||
ok_with_ratio_p = valid_mem_ref_p (mem_mode, as, &parts, code);
|
||||
if (!ok_with_ratio_p)
|
||||
parts.step = NULL_TREE;
|
||||
}
|
||||
|
@ -4724,7 +4732,7 @@ get_address_cost (struct ivopts_data *data, struct iv_use *use,
|
|||
{
|
||||
parts.offset = wide_int_to_tree (sizetype, aff_inv->offset);
|
||||
/* Addressing mode "base + index [<< scale] + offset". */
|
||||
if (!valid_mem_ref_p (mem_mode, as, &parts))
|
||||
if (!valid_mem_ref_p (mem_mode, as, &parts, code))
|
||||
parts.offset = NULL_TREE;
|
||||
else
|
||||
aff_inv->offset = 0;
|
||||
|
@ -4737,7 +4745,7 @@ get_address_cost (struct ivopts_data *data, struct iv_use *use,
|
|||
|
||||
/* Addressing mode "symbol + base + index [<< scale] [+ offset]". */
|
||||
if (parts.symbol != NULL_TREE
|
||||
&& !valid_mem_ref_p (mem_mode, as, &parts))
|
||||
&& !valid_mem_ref_p (mem_mode, as, &parts, code))
|
||||
{
|
||||
aff_combination_add_elt (aff_inv, parts.symbol, 1);
|
||||
parts.symbol = NULL_TREE;
|
||||
|
@ -4775,7 +4783,7 @@ get_address_cost (struct ivopts_data *data, struct iv_use *use,
|
|||
{
|
||||
parts.offset = wide_int_to_tree (sizetype, aff_inv->offset);
|
||||
/* Addressing mode "base + offset". */
|
||||
if (!valid_mem_ref_p (mem_mode, as, &parts))
|
||||
if (!valid_mem_ref_p (mem_mode, as, &parts, code))
|
||||
parts.offset = NULL_TREE;
|
||||
else
|
||||
aff_inv->offset = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue