This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Record that immediate_operand & co. can accept HIGHs
- From: Richard Sandiford <rsandifo at nildram dot co dot uk>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 02 May 2008 10:02:00 +0100
- Subject: Record that immediate_operand & co. can accept HIGHs
I'm about to post a patch that makes genrecog more sensitive to the
list of codes that each predicate accepts. While writing that patch,
I discovered that the current list is incomplete: predicates that accept
RTX_CONST_OBJs are not listed as allowing HIGHs. By inspection, they
also aren't listed as allowing CONST_FIXED.
I think this shows that duplicating the list of constant codes
is too error-prone. This patch instead adds an "allows_const_p"
field to the predication-definition structure.
Tested in combination with the other patches by building
cc1 and cc1plus for:
alpha-linux-gnu arc-elf arm-eabi avr-rtems bfin-elf cris-elf
fr30-elf frv-elf h8300-elf i686-linux-gnu x86_64-linux-gnu
iq2000-elf m32c-elf m32r-elf m68hc11-elf m68k-elf mcore-elf
mipsisa64-elf mmix-knuth-mmixware hppa2.0-linux-gnu pdp11-bsd
powerpc64-linux-gnu powerpc-linux-gnu s390-linux-gnu score-elf
sh-elf sh64-elf sparc-sun-solaris2.8 spu-elf xstormy16-elf
v850-elf vax-netbsdelf xtensa-elf
and making sure that there were no changes in the assembly output for
gcc.c-torture, gcc.dg and g++.dg (compiled once with -g and once with
-O2). Also bootstrapped & regression-tested on x86_64-linux-gnu.
OK to install?
Richard
gcc/
* gensupport.h (pred_data): Add a "num_codes" field.
(add_predicate_code): Declare.
* gensupport.c (add_predicate_code): New function.
(std_pred_table): Add an "allows_const_p" field.
(std_preds): Set this field for predicates that allow RTX_CONST_OBJs.
Remove the (incomplete) list of such codes from the codes field.
(init_predicate_table): Use add_predicate_code. Add all
RTX_CONST_OBJs if allows_const_p is true.
* genrecog.c (process_define_predicate): Use add_predicate_code.
Index: gcc/gensupport.h
===================================================================
--- gcc/gensupport.h 2008-05-01 19:03:59.000000000 +0100
+++ gcc/gensupport.h 2008-05-02 09:59:29.000000000 +0100
@@ -76,6 +76,7 @@ struct pred_data
/* data used primarily by genrecog.c */
enum rtx_code singleton; /* if pred takes only one code, that code */
+ int num_codes; /* number of codes accepted */
bool allows_non_lvalue; /* if pred allows non-lvalue expressions */
bool allows_non_const; /* if pred allows non-const expressions */
bool codes[NUM_RTX_CODE]; /* set of codes accepted */
@@ -83,6 +84,7 @@ struct pred_data
extern struct pred_data *first_predicate;
extern struct pred_data *lookup_predicate (const char *);
+extern void add_predicate_code (struct pred_data *, enum rtx_code);
extern void add_predicate (struct pred_data *);
#define FOR_ALL_PREDICATES(p) for (p = first_predicate; p; p = p->next)
Index: gcc/gensupport.c
===================================================================
--- gcc/gensupport.c 2008-05-01 19:03:59.000000000 +0100
+++ gcc/gensupport.c 2008-05-02 09:59:29.000000000 +0100
@@ -1299,6 +1299,34 @@ lookup_predicate (const char *name)
return (struct pred_data *) htab_find (predicate_table, &key);
}
+/* Record that predicate PRED can accept CODE. */
+
+void
+add_predicate_code (struct pred_data *pred, enum rtx_code code)
+{
+ if (!pred->codes[code])
+ {
+ pred->num_codes++;
+ pred->codes[code] = true;
+
+ if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
+ pred->allows_non_const = true;
+
+ if (code != REG
+ && code != SUBREG
+ && code != MEM
+ && code != CONCAT
+ && code != PARALLEL
+ && code != STRICT_LOW_PART)
+ pred->allows_non_lvalue = true;
+
+ if (pred->num_codes == 1)
+ pred->singleton = code;
+ else if (pred->num_codes == 2)
+ pred->singleton = UNKNOWN;
+ }
+}
+
void
add_predicate (struct pred_data *pred)
{
@@ -1320,32 +1348,31 @@ struct std_pred_table
{
const char *name;
bool special;
+ bool allows_const_p;
RTX_CODE codes[NUM_RTX_CODE];
};
static const struct std_pred_table std_preds[] = {
- {"general_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG, MEM }},
- {"address_operand", true, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG, MEM,
- PLUS, MINUS, MULT}},
- {"register_operand", false, {SUBREG, REG}},
- {"pmode_register_operand", true, {SUBREG, REG}},
- {"scratch_operand", false, {SCRATCH, REG}},
- {"immediate_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF}},
- {"const_int_operand", false, {CONST_INT}},
- {"const_double_operand", false, {CONST_INT, CONST_DOUBLE}},
- {"nonimmediate_operand", false, {SUBREG, REG, MEM}},
- {"nonmemory_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG}},
- {"push_operand", false, {MEM}},
- {"pop_operand", false, {MEM}},
- {"memory_operand", false, {SUBREG, MEM}},
- {"indirect_operand", false, {SUBREG, MEM}},
- {"comparison_operator", false, {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
- UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
- UNLT, LTGT}}
+ {"general_operand", false, true, {SUBREG, REG, MEM}},
+ {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT}},
+ {"register_operand", false, false, {SUBREG, REG}},
+ {"pmode_register_operand", true, false, {SUBREG, REG}},
+ {"scratch_operand", false, false, {SCRATCH, REG}},
+ {"immediate_operand", false, true, {0}},
+ {"const_int_operand", false, false, {CONST_INT}},
+ {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
+ {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
+ {"nonmemory_operand", false, true, {SUBREG, REG}},
+ {"push_operand", false, false, {MEM}},
+ {"pop_operand", false, false, {MEM}},
+ {"memory_operand", false, false, {SUBREG, MEM}},
+ {"indirect_operand", false, false, {SUBREG, MEM}},
+ {"comparison_operator", false, false, {EQ, NE,
+ LE, LT, GE, GT,
+ LEU, LTU, GEU, GTU,
+ UNORDERED, ORDERED,
+ UNEQ, UNGE, UNGT,
+ UNLE, UNLT, LTGT}}
};
#define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
@@ -1369,22 +1396,12 @@ init_predicate_table (void)
pred->special = std_preds[i].special;
for (j = 0; std_preds[i].codes[j] != 0; j++)
- {
- enum rtx_code code = std_preds[i].codes[j];
+ add_predicate_code (pred, std_preds[i].codes[j]);
- pred->codes[code] = true;
- if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
- pred->allows_non_const = true;
- if (code != REG
- && code != SUBREG
- && code != MEM
- && code != CONCAT
- && code != PARALLEL
- && code != STRICT_LOW_PART)
- pred->allows_non_lvalue = true;
- }
- if (j == 1)
- pred->singleton = std_preds[i].codes[0];
+ if (std_preds[i].allows_const_p)
+ for (j = 0; j < NUM_RTX_CODE; j++)
+ if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
+ add_predicate_code (pred, j);
add_predicate (pred);
}
Index: gcc/genrecog.c
===================================================================
--- gcc/genrecog.c 2008-05-01 19:03:59.000000000 +0100
+++ gcc/genrecog.c 2008-05-02 09:59:29.000000000 +0100
@@ -368,7 +368,6 @@ process_define_predicate (rtx desc)
{
struct pred_data *pred = xcalloc (sizeof (struct pred_data), 1);
char codes[NUM_RTX_CODE];
- bool seen_one = false;
int i;
pred->name = XSTR (desc, 0);
@@ -379,26 +378,8 @@ process_define_predicate (rtx desc)
for (i = 0; i < NUM_RTX_CODE; i++)
if (codes[i] != N)
- {
- pred->codes[i] = true;
- if (GET_RTX_CLASS (i) != RTX_CONST_OBJ)
- pred->allows_non_const = true;
- if (i != REG
- && i != SUBREG
- && i != MEM
- && i != CONCAT
- && i != PARALLEL
- && i != STRICT_LOW_PART)
- pred->allows_non_lvalue = true;
+ add_predicate_code (pred, i);
- if (seen_one)
- pred->singleton = UNKNOWN;
- else
- {
- pred->singleton = i;
- seen_one = true;
- }
- }
add_predicate (pred);
}
#undef I