diff options
author | Zack Weinberg <zack@gcc.gnu.org> | 2002-07-29 18:02:47 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 2002-07-29 18:02:47 +0000 |
commit | 2199e5fade2d41cbdb19bb730e494613b9b7e262 (patch) | |
tree | 8880ef10951d3d1fbca761d1c3b95b762f0409e5 /gcc/gensupport.c | |
parent | 6ab185d6a53a5d77b86144d26414b5167778384a (diff) | |
download | gcc-2199e5fade2d41cbdb19bb730e494613b9b7e262.tar.gz |
gensupport.c: Include hashtab.h.
* gensupport.c: Include hashtab.h.
(insn_elision, condition_table, hash_c_test, cmp_c_test,
maybe_eval_c_test): New routines and data structures to
support insn elision.
(init_md_reader): Read and initialize the condition_table.
(read_md_rtx): Discard insn patterns whose C test is provably
always false.
* gensupport.h: Declare new functions and data structures.
* genconditions.c, dummy-conditions.c: New files.
* Makefile.in: Build genconditions; run it to construct
insn-conditions.c; build that and link it into most gen*
programs.
(HOST_SUPPORT, HOST_EARLY_SUPPORT): New variables.
(GEN): Delete, unused.
(STAGESTUFF): Update.
* gencodes.c: (gen_insn): #define CODE_FOR_xxx equal to
CODE_FOR_nothing for all elided patterns.
(main): Tweaked to support this.
* genflags.c (gen_proto): Emit a static inline generator
function here for all elided patterns, which simply returns
NULL_RTX.
(gen_insn): Do not define HAVE_xxx for elided patterns.
(main): Tweaked to support this. No need to forward-declare
struct rtx_def.
* genrecog.c: Do not bother emitting the C test if it's known
to be true at compile time.
From-SVN: r55839
Diffstat (limited to 'gcc/gensupport.c')
-rw-r--r-- | gcc/gensupport.c | 100 |
1 files changed, 99 insertions, 1 deletions
diff --git a/gcc/gensupport.c b/gcc/gensupport.c index 9e3d0bbcb1f..5a9ff21f978 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -23,12 +23,15 @@ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "hashtab.h" #include "gensupport.h" /* In case some macros used by files we include need it, define this here. */ int target_flags; +int insn_elision = 1; + static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -39,6 +42,8 @@ static int predicable_default; static const char *predicable_true; static const char *predicable_false; +static htab_t condition_table; + static char *base_dir = NULL; /* We initially queue all patterns, process the define_insn and @@ -950,6 +955,7 @@ init_md_reader (filename) { FILE *input_file; int c; + size_t i; char *lastsl; lastsl = strrchr (filename, '/'); @@ -964,6 +970,14 @@ init_md_reader (filename) return FATAL_EXIT_CODE; } + /* Initialize the table of insn conditions. */ + condition_table = htab_create (n_insn_conditions, + hash_c_test, cmp_c_test, NULL); + + for (i = 0; i < n_insn_conditions; i++) + *(htab_find_slot (condition_table, (PTR) &insn_conditions[i], INSERT)) + = (PTR) &insn_conditions[i]; + obstack_init (rtl_obstack); errors = 0; sequence_num = 0; @@ -1002,6 +1016,8 @@ read_md_rtx (lineno, seqnr) struct queue_elem **queue, *elem; rtx desc; + discard: + /* Read all patterns from a given queue before moving on to the next. */ if (define_attr_queue != NULL) queue = &define_attr_queue; @@ -1021,14 +1037,29 @@ read_md_rtx (lineno, seqnr) free (elem); + /* Discard insn patterns which we know can never match (because + their C test is provably always false). If insn_elision is + false, our caller needs to see all the patterns. Note that the + elided patterns are never counted by the sequence numbering; it + it is the caller's responsibility, when insn_elision is false, not + to use elided pattern numbers for anything. */ switch (GET_CODE (desc)) { case DEFINE_INSN: case DEFINE_EXPAND: + if (maybe_eval_c_test (XSTR (desc, 2)) != 0) + sequence_num++; + else if (insn_elision) + goto discard; + break; + case DEFINE_SPLIT: case DEFINE_PEEPHOLE: case DEFINE_PEEPHOLE2: - sequence_num++; + if (maybe_eval_c_test (XSTR (desc, 1)) != 0) + sequence_num++; + else if (insn_elision) + goto discard; break; default: @@ -1038,6 +1069,73 @@ read_md_rtx (lineno, seqnr) return desc; } +/* Helper functions for insn elision. */ + +/* Compute a hash function of a c_test structure, which is keyed + by its ->expr field. */ +hashval_t +hash_c_test (x) + const PTR x; +{ + const struct c_test *a = (const struct c_test *) x; + const unsigned char *base, *s = (const unsigned char *) a->expr; + hashval_t hash; + unsigned char c; + unsigned int len; + + base = s; + hash = 0; + + while ((c = *s++) != '\0') + { + hash += c + (c << 17); + hash ^= hash >> 2; + } + + len = s - base; + hash += len + (len << 17); + hash ^= hash >> 2; + + return hash; +} + +/* Compare two c_test expression structures. */ +int +cmp_c_test (x, y) + const PTR x; + const PTR y; +{ + const struct c_test *a = (const struct c_test *) x; + const struct c_test *b = (const struct c_test *) y; + + return !strcmp (a->expr, b->expr); +} + +/* Given a string representing a C test expression, look it up in the + condition_table and report whether or not its value is known + at compile time. Returns a tristate: 1 for known true, 0 for + known false, -1 for unknown. */ +int +maybe_eval_c_test (expr) + const char *expr; +{ + const struct c_test *test; + struct c_test dummy; + + if (expr[0] == 0) + return 1; + + if (insn_elision_unavailable) + return -1; + + dummy.expr = expr; + test = (const struct c_test *) htab_find (condition_table, &dummy); + if (!test) + abort (); + + return test->value; +} + /* Given a string, return the number of comma-separated elements in it. Return 0 for the null string. */ int |