mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-26 22:14:44 +08:00
re PR target/69299 (-mavx performance degradation with r232088)
2016-01-29 Vladimir Makarov <vmakarov@redhat.com> PR target/69299 * config/i386/constraints.md (Bm): Describe as special memory constraint. * doc/md.texi (DEFINE_SPECIAL_MEMORY_CONSTRAINT): Describe it. * genoutput.c (main): Process DEFINE_SPECIAL_MEMORY_CONSTRAINT. * genpreds.c (struct constraint_data): Add is_special_memory. (have_special_memory_constraints, special_memory_start): New static vars. (special_memory_end): Ditto. (add_constraint): Add new arg is_special_memory. Add code to process its true value. Update have_special_memory_constraints. (process_define_constraint): Pass the new arg. (process_define_register_constraint): Ditto. (choose_enum_order): Process special memory. (write_tm_preds_h): Generate enum const CT_SPECIAL_MEMORY and function insn_extra_special_memory_constraint. (main): Process DEFINE_SPECIAL_MEMORY_CONSTRAINT. * gensupport.c (process_rtx): Process DEFINE_SPECIAL_MEMORY_CONSTRAINT. * ira-costs.c (record_reg_classes): Process CT_SPECIAL_MEMORY. * ira-lives.c (single_reg_class): Use insn_extra_special_memory_constraint. * ira.c (ira_setup_alts): Process CT_SPECIAL_MEMORY. * lra-constraints.c (process_alt_operands): Ditto. (curr_insn_transform): Use insn_extra_special_memory_constraint. * recog.c (asm_operand_ok, preprocess_constraints): Process CT_SPECIAL_MEMORY. * reload.c (find_reloads): Ditto. * rtl.def (DEFINE_SPECIFAL_MEMORY_CONSTRAINT): New. * stmt.c (parse_input_constraint): Use insn_extra_special_memory_constraint. From-SVN: r232993
This commit is contained in:
parent
6bbacdb544
commit
9eb1ca69e1
@ -1,3 +1,37 @@
|
||||
2016-01-29 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
PR target/69299
|
||||
* config/i386/constraints.md (Bm): Describe as special memory
|
||||
constraint.
|
||||
* doc/md.texi (DEFINE_SPECIAL_MEMORY_CONSTRAINT): Describe it.
|
||||
* genoutput.c (main): Process DEFINE_SPECIAL_MEMORY_CONSTRAINT.
|
||||
* genpreds.c (struct constraint_data): Add is_special_memory.
|
||||
(have_special_memory_constraints, special_memory_start): New
|
||||
static vars.
|
||||
(special_memory_end): Ditto.
|
||||
(add_constraint): Add new arg is_special_memory. Add code to
|
||||
process its true value. Update have_special_memory_constraints.
|
||||
(process_define_constraint): Pass the new arg.
|
||||
(process_define_register_constraint): Ditto.
|
||||
(choose_enum_order): Process special memory.
|
||||
(write_tm_preds_h): Generate enum const CT_SPECIAL_MEMORY and
|
||||
function insn_extra_special_memory_constraint.
|
||||
(main): Process DEFINE_SPECIAL_MEMORY_CONSTRAINT.
|
||||
* gensupport.c (process_rtx): Process
|
||||
DEFINE_SPECIAL_MEMORY_CONSTRAINT.
|
||||
* ira-costs.c (record_reg_classes): Process CT_SPECIAL_MEMORY.
|
||||
* ira-lives.c (single_reg_class): Use
|
||||
insn_extra_special_memory_constraint.
|
||||
* ira.c (ira_setup_alts): Process CT_SPECIAL_MEMORY.
|
||||
* lra-constraints.c (process_alt_operands): Ditto.
|
||||
(curr_insn_transform): Use insn_extra_special_memory_constraint.
|
||||
* recog.c (asm_operand_ok, preprocess_constraints): Process
|
||||
CT_SPECIAL_MEMORY.
|
||||
* reload.c (find_reloads): Ditto.
|
||||
* rtl.def (DEFINE_SPECIFAL_MEMORY_CONSTRAINT): New.
|
||||
* stmt.c (parse_input_constraint): Use
|
||||
insn_extra_special_memory_constraint.
|
||||
|
||||
2016-01-29 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/69530
|
||||
|
@ -162,7 +162,7 @@
|
||||
"@internal GOT memory operand."
|
||||
(match_operand 0 "GOT_memory_operand"))
|
||||
|
||||
(define_constraint "Bm"
|
||||
(define_special_memory_constraint "Bm"
|
||||
"@internal Vector memory operand."
|
||||
(match_operand 0 "vector_memory_operand"))
|
||||
|
||||
|
@ -4424,6 +4424,20 @@ The syntax and semantics are otherwise identical to
|
||||
@code{define_constraint}.
|
||||
@end deffn
|
||||
|
||||
@deffn {MD Expression} define_special_memory_constraint name docstring exp
|
||||
Use this expression for constraints that match a subset of all memory
|
||||
operands: that is, @code{reload} can not make them match by reloading
|
||||
the address as it is described for @code{define_memory_constraint} or
|
||||
such address reload is undesirable with the performance point of view.
|
||||
|
||||
For example, @code{define_special_memory_constraint} can be useful if
|
||||
specifically aligned memory is necessary or desirable for some insn
|
||||
operand.
|
||||
|
||||
The syntax and semantics are otherwise identical to
|
||||
@code{define_constraint}.
|
||||
@end deffn
|
||||
|
||||
@deffn {MD Expression} define_address_constraint name docstring exp
|
||||
Use this expression for constraints that match a subset of all address
|
||||
operands: that is, @code{reload} can make the constraint match by
|
||||
|
@ -1019,6 +1019,7 @@ main (int argc, char **argv)
|
||||
case DEFINE_REGISTER_CONSTRAINT:
|
||||
case DEFINE_ADDRESS_CONSTRAINT:
|
||||
case DEFINE_MEMORY_CONSTRAINT:
|
||||
case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
|
||||
note_constraint (&info);
|
||||
break;
|
||||
|
||||
|
@ -659,11 +659,11 @@ write_one_predicate_function (struct pred_data *p)
|
||||
|
||||
/* Constraints fall into two categories: register constraints
|
||||
(define_register_constraint), and others (define_constraint,
|
||||
define_memory_constraint, define_address_constraint). We
|
||||
work out automatically which of the various old-style macros
|
||||
they correspond to, and produce appropriate code. They all
|
||||
go in the same hash table so we can verify that there are no
|
||||
duplicate names. */
|
||||
define_memory_constraint, define_special_memory_constraint,
|
||||
define_address_constraint). We work out automatically which of the
|
||||
various old-style macros they correspond to, and produce
|
||||
appropriate code. They all go in the same hash table so we can
|
||||
verify that there are no duplicate names. */
|
||||
|
||||
/* All data from one constraint definition. */
|
||||
struct constraint_data
|
||||
@ -681,6 +681,7 @@ struct constraint_data
|
||||
unsigned int is_const_dbl : 1;
|
||||
unsigned int is_extra : 1;
|
||||
unsigned int is_memory : 1;
|
||||
unsigned int is_special_memory: 1;
|
||||
unsigned int is_address : 1;
|
||||
unsigned int maybe_allows_reg : 1;
|
||||
unsigned int maybe_allows_mem : 1;
|
||||
@ -718,6 +719,7 @@ static const char const_dbl_constraints[] = "GH";
|
||||
static unsigned int constraint_max_namelen;
|
||||
static bool have_register_constraints;
|
||||
static bool have_memory_constraints;
|
||||
static bool have_special_memory_constraints;
|
||||
static bool have_address_constraints;
|
||||
static bool have_extra_constraints;
|
||||
static bool have_const_int_constraints;
|
||||
@ -728,6 +730,7 @@ static unsigned int register_start, register_end;
|
||||
static unsigned int satisfied_start;
|
||||
static unsigned int const_int_start, const_int_end;
|
||||
static unsigned int memory_start, memory_end;
|
||||
static unsigned int special_memory_start, special_memory_end;
|
||||
static unsigned int address_start, address_end;
|
||||
static unsigned int maybe_allows_none_start, maybe_allows_none_end;
|
||||
static unsigned int maybe_allows_reg_start, maybe_allows_reg_end;
|
||||
@ -754,20 +757,22 @@ mangle (const char *name)
|
||||
|
||||
/* Add one constraint, of any sort, to the tables. NAME is its name;
|
||||
REGCLASS is the register class, if any; EXP is the expression to
|
||||
test, if any; IS_MEMORY and IS_ADDRESS indicate memory and address
|
||||
constraints, respectively; LOC is the .md file location.
|
||||
test, if any; IS_MEMORY, IS_SPECIAL_MEMORY and IS_ADDRESS indicate
|
||||
memory, special memory, and address constraints, respectively; LOC
|
||||
is the .md file location.
|
||||
|
||||
Not all combinations of arguments are valid; most importantly, REGCLASS
|
||||
is mutually exclusive with EXP, and IS_MEMORY/IS_ADDRESS are only
|
||||
meaningful for constraints with EXP.
|
||||
Not all combinations of arguments are valid; most importantly,
|
||||
REGCLASS is mutually exclusive with EXP, and
|
||||
IS_MEMORY/IS_SPECIAL_MEMORY/IS_ADDRESS are only meaningful for
|
||||
constraints with EXP.
|
||||
|
||||
This function enforces all syntactic and semantic rules about what
|
||||
constraints can be defined. */
|
||||
|
||||
static void
|
||||
add_constraint (const char *name, const char *regclass,
|
||||
rtx exp, bool is_memory, bool is_address,
|
||||
file_location loc)
|
||||
rtx exp, bool is_memory, bool is_special_memory,
|
||||
bool is_address, file_location loc)
|
||||
{
|
||||
struct constraint_data *c, **iter, **slot;
|
||||
const char *p;
|
||||
@ -878,6 +883,17 @@ add_constraint (const char *name, const char *regclass,
|
||||
name, name[0]);
|
||||
return;
|
||||
}
|
||||
else if (is_special_memory)
|
||||
{
|
||||
if (name[1] == '\0')
|
||||
error_at (loc, "constraint letter '%c' cannot be a "
|
||||
"special memory constraint", name[0]);
|
||||
else
|
||||
error_at (loc, "constraint name '%s' begins with '%c', "
|
||||
"and therefore cannot be a special memory constraint",
|
||||
name, name[0]);
|
||||
return;
|
||||
}
|
||||
else if (is_address)
|
||||
{
|
||||
if (name[1] == '\0')
|
||||
@ -904,6 +920,7 @@ add_constraint (const char *name, const char *regclass,
|
||||
c->is_const_dbl = is_const_dbl;
|
||||
c->is_extra = !(regclass || is_const_int || is_const_dbl);
|
||||
c->is_memory = is_memory;
|
||||
c->is_special_memory = is_special_memory;
|
||||
c->is_address = is_address;
|
||||
c->maybe_allows_reg = true;
|
||||
c->maybe_allows_mem = true;
|
||||
@ -930,17 +947,20 @@ add_constraint (const char *name, const char *regclass,
|
||||
have_const_int_constraints |= c->is_const_int;
|
||||
have_extra_constraints |= c->is_extra;
|
||||
have_memory_constraints |= c->is_memory;
|
||||
have_special_memory_constraints |= c->is_special_memory;
|
||||
have_address_constraints |= c->is_address;
|
||||
num_constraints += 1;
|
||||
}
|
||||
|
||||
/* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT, or
|
||||
DEFINE_ADDRESS_CONSTRAINT expression, C. */
|
||||
/* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT,
|
||||
DEFINE_SPECIAL_MEMORY_CONSTRAINT, or DEFINE_ADDRESS_CONSTRAINT
|
||||
expression, C. */
|
||||
static void
|
||||
process_define_constraint (md_rtx_info *info)
|
||||
{
|
||||
add_constraint (XSTR (info->def, 0), 0, XEXP (info->def, 2),
|
||||
GET_CODE (info->def) == DEFINE_MEMORY_CONSTRAINT,
|
||||
GET_CODE (info->def) == DEFINE_SPECIAL_MEMORY_CONSTRAINT,
|
||||
GET_CODE (info->def) == DEFINE_ADDRESS_CONSTRAINT,
|
||||
info->loc);
|
||||
}
|
||||
@ -950,7 +970,7 @@ static void
|
||||
process_define_register_constraint (md_rtx_info *info)
|
||||
{
|
||||
add_constraint (XSTR (info->def, 0), XSTR (info->def, 1),
|
||||
0, false, false, info->loc);
|
||||
0, false, false, false, info->loc);
|
||||
}
|
||||
|
||||
/* Put the constraints into enum order. We want to keep constraints
|
||||
@ -984,6 +1004,12 @@ choose_enum_order (void)
|
||||
enum_order[next++] = c;
|
||||
memory_end = next;
|
||||
|
||||
special_memory_start = next;
|
||||
FOR_ALL_CONSTRAINTS (c)
|
||||
if (c->is_special_memory)
|
||||
enum_order[next++] = c;
|
||||
special_memory_end = next;
|
||||
|
||||
address_start = next;
|
||||
FOR_ALL_CONSTRAINTS (c)
|
||||
if (c->is_address)
|
||||
@ -992,27 +1018,31 @@ choose_enum_order (void)
|
||||
|
||||
maybe_allows_none_start = next;
|
||||
FOR_ALL_CONSTRAINTS (c)
|
||||
if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
|
||||
if (!c->is_register && !c->is_const_int && !c->is_memory
|
||||
&& !c->is_special_memory && !c->is_address
|
||||
&& !c->maybe_allows_reg && !c->maybe_allows_mem)
|
||||
enum_order[next++] = c;
|
||||
maybe_allows_none_end = next;
|
||||
|
||||
maybe_allows_reg_start = next;
|
||||
FOR_ALL_CONSTRAINTS (c)
|
||||
if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
|
||||
if (!c->is_register && !c->is_const_int && !c->is_memory
|
||||
&& !c->is_special_memory && !c->is_address
|
||||
&& c->maybe_allows_reg && !c->maybe_allows_mem)
|
||||
enum_order[next++] = c;
|
||||
maybe_allows_reg_end = next;
|
||||
|
||||
maybe_allows_mem_start = next;
|
||||
FOR_ALL_CONSTRAINTS (c)
|
||||
if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
|
||||
if (!c->is_register && !c->is_const_int && !c->is_memory
|
||||
&& !c->is_special_memory && !c->is_address
|
||||
&& !c->maybe_allows_reg && c->maybe_allows_mem)
|
||||
enum_order[next++] = c;
|
||||
maybe_allows_mem_end = next;
|
||||
|
||||
FOR_ALL_CONSTRAINTS (c)
|
||||
if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
|
||||
if (!c->is_register && !c->is_const_int && !c->is_memory
|
||||
&& !c->is_special_memory && !c->is_address
|
||||
&& c->maybe_allows_reg && c->maybe_allows_mem)
|
||||
enum_order[next++] = c;
|
||||
gcc_assert (next == num_constraints);
|
||||
@ -1431,6 +1461,8 @@ write_tm_preds_h (void)
|
||||
register_start, register_end);
|
||||
write_range_function ("insn_extra_memory_constraint",
|
||||
memory_start, memory_end);
|
||||
write_range_function ("insn_extra_special_memory_constraint",
|
||||
special_memory_start, special_memory_end);
|
||||
write_range_function ("insn_extra_address_constraint",
|
||||
address_start, address_end);
|
||||
write_allows_reg_mem_function ();
|
||||
@ -1479,6 +1511,7 @@ write_tm_preds_h (void)
|
||||
" CT_REGISTER,\n"
|
||||
" CT_CONST_INT,\n"
|
||||
" CT_MEMORY,\n"
|
||||
" CT_SPECIAL_MEMORY,\n"
|
||||
" CT_ADDRESS,\n"
|
||||
" CT_FIXED_FORM\n"
|
||||
"};\n"
|
||||
@ -1491,6 +1524,8 @@ write_tm_preds_h (void)
|
||||
values.safe_push (std::make_pair (const_int_start, "CT_CONST_INT"));
|
||||
if (memory_start != memory_end)
|
||||
values.safe_push (std::make_pair (memory_start, "CT_MEMORY"));
|
||||
if (special_memory_start != special_memory_end)
|
||||
values.safe_push (std::make_pair (special_memory_start, "CT_SPECIAL_MEMORY"));
|
||||
if (address_start != address_end)
|
||||
values.safe_push (std::make_pair (address_start, "CT_ADDRESS"));
|
||||
if (address_end != num_constraints)
|
||||
@ -1602,6 +1637,7 @@ main (int argc, char **argv)
|
||||
|
||||
case DEFINE_CONSTRAINT:
|
||||
case DEFINE_MEMORY_CONSTRAINT:
|
||||
case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
|
||||
case DEFINE_ADDRESS_CONSTRAINT:
|
||||
process_define_constraint (&info);
|
||||
break;
|
||||
|
@ -521,6 +521,7 @@ process_rtx (rtx desc, file_location loc)
|
||||
case DEFINE_CONSTRAINT:
|
||||
case DEFINE_REGISTER_CONSTRAINT:
|
||||
case DEFINE_MEMORY_CONSTRAINT:
|
||||
case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
|
||||
case DEFINE_ADDRESS_CONSTRAINT:
|
||||
queue_pattern (desc, &define_pred_tail, loc);
|
||||
break;
|
||||
|
@ -783,6 +783,12 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
|
||||
win = 1;
|
||||
break;
|
||||
|
||||
case CT_SPECIAL_MEMORY:
|
||||
insn_allows_mem[i] = allows_mem[i] = 1;
|
||||
if (MEM_P (op) && constraint_satisfied_p (op, cn))
|
||||
win = 1;
|
||||
break;
|
||||
|
||||
case CT_ADDRESS:
|
||||
/* Every address can be reloaded to fit. */
|
||||
allows_addr = 1;
|
||||
|
@ -774,6 +774,7 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
|
||||
/* ??? Is this the best way to handle memory constraints? */
|
||||
cn = lookup_constraint (constraints);
|
||||
if (insn_extra_memory_constraint (cn)
|
||||
|| insn_extra_special_memory_constraint (cn)
|
||||
|| insn_extra_address_constraint (cn))
|
||||
return NO_REGS;
|
||||
if (constraint_satisfied_p (op, cn)
|
||||
|
@ -1868,6 +1868,7 @@ ira_setup_alts (rtx_insn *insn, HARD_REG_SET &alts)
|
||||
|
||||
case CT_ADDRESS:
|
||||
case CT_MEMORY:
|
||||
case CT_SPECIAL_MEMORY:
|
||||
goto op_success;
|
||||
|
||||
case CT_FIXED_FORM:
|
||||
|
@ -400,7 +400,7 @@ valid_address_p (struct address_info *ad)
|
||||
}
|
||||
|
||||
/* Return true if the eliminated form of memory reference OP satisfies
|
||||
extra memory constraint CONSTRAINT. */
|
||||
extra (special) memory constraint CONSTRAINT. */
|
||||
static bool
|
||||
satisfies_memory_constraint_p (rtx op, enum constraint_num constraint)
|
||||
{
|
||||
@ -2038,6 +2038,14 @@ process_alt_operands (int only_alternative)
|
||||
if (constraint_satisfied_p (op, cn))
|
||||
win = true;
|
||||
break;
|
||||
|
||||
case CT_SPECIAL_MEMORY:
|
||||
if (MEM_P (op)
|
||||
&& satisfies_memory_constraint_p (op, cn))
|
||||
win = true;
|
||||
else if (spilled_pseudo_p (op))
|
||||
win = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3701,7 +3709,8 @@ curr_insn_transform (bool check_only_p)
|
||||
constraint += CONSTRAINT_LEN (c, constraint))
|
||||
{
|
||||
enum constraint_num cn = lookup_constraint (constraint);
|
||||
if (insn_extra_memory_constraint (cn)
|
||||
if ((insn_extra_memory_constraint (cn)
|
||||
|| insn_extra_special_memory_constraint (cn))
|
||||
&& satisfies_memory_constraint_p (tem, cn))
|
||||
break;
|
||||
}
|
||||
|
@ -1791,6 +1791,7 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
|
||||
break;
|
||||
|
||||
case CT_MEMORY:
|
||||
case CT_SPECIAL_MEMORY:
|
||||
/* Every memory operand can be reloaded to fit. */
|
||||
result = result || memory_operand (op, VOIDmode);
|
||||
break;
|
||||
@ -2403,6 +2404,7 @@ preprocess_constraints (int n_operands, int n_alternatives,
|
||||
break;
|
||||
|
||||
case CT_MEMORY:
|
||||
case CT_SPECIAL_MEMORY:
|
||||
op_alt[i].memory_ok = 1;
|
||||
break;
|
||||
|
||||
|
17
gcc/reload.c
17
gcc/reload.c
@ -3471,6 +3471,23 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
|
||||
offmemok = 1;
|
||||
break;
|
||||
|
||||
case CT_SPECIAL_MEMORY:
|
||||
if (force_reload)
|
||||
break;
|
||||
if (constraint_satisfied_p (operand, cn))
|
||||
win = 1;
|
||||
/* Likewise if the address will be reloaded because
|
||||
reg_equiv_address is nonzero. For reg_equiv_mem
|
||||
we have to check. */
|
||||
else if (REG_P (operand)
|
||||
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
|
||||
&& reg_renumber[REGNO (operand)] < 0
|
||||
&& reg_equiv_mem (REGNO (operand)) != 0
|
||||
&& (constraint_satisfied_p
|
||||
(reg_equiv_mem (REGNO (operand)), cn)))
|
||||
win = 1;
|
||||
break;
|
||||
|
||||
case CT_ADDRESS:
|
||||
if (constraint_satisfied_p (operand, cn))
|
||||
win = 1;
|
||||
|
@ -1035,6 +1035,7 @@ DEF_RTL_EXPR(DEFINE_REGISTER_CONSTRAINT, "define_register_constraint", "sss", RT
|
||||
RTL object. */
|
||||
DEF_RTL_EXPR(DEFINE_CONSTRAINT, "define_constraint", "sse", RTX_EXTRA)
|
||||
DEF_RTL_EXPR(DEFINE_MEMORY_CONSTRAINT, "define_memory_constraint", "sse", RTX_EXTRA)
|
||||
DEF_RTL_EXPR(DEFINE_SPECIAL_MEMORY_CONSTRAINT, "define_special_memory_constraint", "sse", RTX_EXTRA)
|
||||
DEF_RTL_EXPR(DEFINE_ADDRESS_CONSTRAINT, "define_address_constraint", "sse", RTX_EXTRA)
|
||||
|
||||
|
||||
|
@ -434,7 +434,8 @@ parse_input_constraint (const char **constraint_p, int input_num,
|
||||
if (reg_class_for_constraint (cn) != NO_REGS
|
||||
|| insn_extra_address_constraint (cn))
|
||||
*allows_reg = true;
|
||||
else if (insn_extra_memory_constraint (cn))
|
||||
else if (insn_extra_memory_constraint (cn)
|
||||
|| insn_extra_special_memory_constraint (cn))
|
||||
*allows_mem = true;
|
||||
else
|
||||
insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
|
||||
|
Loading…
Reference in New Issue
Block a user