diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-05-27 10:06:22 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-05-27 10:06:22 +0000 |
commit | d2b854bc935a18434b59f77d8a6e329e4146a2ba (patch) | |
tree | 5d62ebd89439d627b40ecb8026ad31c4827dbfae /gcc/recog.c | |
parent | 6add2e69343004dabec88d6e8c40229c930b4c7c (diff) | |
download | gcc-d2b854bc935a18434b59f77d8a6e329e4146a2ba.tar.gz |
gcc/
* system.h (TEST_BIT): New macro.
* recog.h (alternative_mask): New type.
(ALL_ALTERNATIVES, ALTERNATIVE_BIT): New macros.
(recog_data_d): Replace alternative_enabled_p array with
enabled_alternatives.
(target_recog): New structure.
(default_target_recog, this_target_recog): Declare.
(get_enabled_alternatives, recog_init): Likewise.
* recog.c (default_target_recog, this_target_recog): New variables.
(get_enabled_alternatives): New function.
(extract_insn): Use it.
(recog_init): New function.
(preprocess_constraints, constrain_operands): Adjust for change to
recog_data.
* postreload.c (reload_cse_simplify_operands): Likewise.
* reload.c (find_reloads): Likewise.
* ira-costs.c (record_reg_classes): Likewise.
* ira-lives.c (single_reg_class): Likewise. Fix bug in which
all alternatives after a disabled one would be skipped.
(ira_implicitly_set_insn_hard_regs): Likewise.
* ira.c (ira_setup_alts): Adjust for change to recog_data.
* lra-int.h (lra_insn_recog_data): Replace alternative_enabled_p
with enabled_alternatives.
* lra.c (free_insn_recog_data): Update accordingly.
(lra_update_insn_recog_data): Likewise.
(lra_set_insn_recog_data): Likewise. Use get_enabled_alternatives.
* lra-constraints.c (process_alt_operands): Likewise. Handle
only_alternative as part of the enabled mask.
* target-globals.h (this_target_recog): Declare.
(target_globals): Add a recog field.
(restore_target_globals): Restore this_target_recog.
* target-globals.c: Include recog.h.
(default_target_globals): Initialize recog field.
(save_target_globals): Likewise.
* reginfo.c (reinit_regs): Call recog_init.
* toplev.c (backend_init_target): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210964 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/recog.c')
-rw-r--r-- | gcc/recog.c | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/gcc/recog.c b/gcc/recog.c index 2f5cf8eb577..c4706940bec 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -61,6 +61,11 @@ static void validate_replace_rtx_1 (rtx *, rtx, rtx, rtx, bool); static void validate_replace_src_1 (rtx *, void *); static rtx split_insn (rtx); +struct target_recog default_target_recog; +#if SWITCHABLE_TARGET +struct target_recog *this_target_recog = &default_target_recog; +#endif + /* Nonzero means allow operands to be volatile. This should be 0 if you are generating rtl, such as if you are calling the functions in optabs.c and expmed.c (most of the time). @@ -2137,6 +2142,48 @@ mode_dependent_address_p (rtx addr, addr_space_t addrspace) return targetm.mode_dependent_address_p (addr, addrspace); } +/* Return the mask of operand alternatives that are allowed for INSN. + This mask depends only on INSN and on the current target; it does not + depend on things like the values of operands. */ + +alternative_mask +get_enabled_alternatives (rtx insn) +{ + /* Quick exit for asms and for targets that don't use the "enabled" + attribute. */ + int code = INSN_CODE (insn); + if (code < 0 || !HAVE_ATTR_enabled) + return ALL_ALTERNATIVES; + + /* Calling get_attr_enabled can be expensive, so cache the mask + for speed. */ + if (this_target_recog->x_enabled_alternatives[code]) + return this_target_recog->x_enabled_alternatives[code]; + + /* Temporarily install enough information for get_attr_enabled to assume + that the insn operands are already cached. As above, the attribute + mustn't depend on the values of operands, so we don't provide their + real values here. */ + rtx old_insn = recog_data.insn; + int old_alternative = which_alternative; + + recog_data.insn = insn; + alternative_mask enabled = ALL_ALTERNATIVES; + int n_alternatives = insn_data[code].n_alternatives; + for (int i = 0; i < n_alternatives; i++) + { + which_alternative = i; + if (!get_attr_enabled (insn)) + enabled &= ~ALTERNATIVE_BIT (i); + } + + recog_data.insn = old_insn; + which_alternative = old_alternative; + + this_target_recog->x_enabled_alternatives[code] = enabled; + return enabled; +} + /* Like extract_insn, but save insn extracted and don't extract again, when called again for the same insn expecting that recog_data still contain the valid information. This is used primary by gen_attr infrastructure that @@ -2269,19 +2316,7 @@ extract_insn (rtx insn) gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES); - if (INSN_CODE (insn) < 0) - for (i = 0; i < recog_data.n_alternatives; i++) - recog_data.alternative_enabled_p[i] = true; - else - { - recog_data.insn = insn; - for (i = 0; i < recog_data.n_alternatives; i++) - { - which_alternative = i; - recog_data.alternative_enabled_p[i] - = HAVE_ATTR_enabled ? get_attr_enabled (insn) : 1; - } - } + recog_data.enabled_alternatives = get_enabled_alternatives (insn); recog_data.insn = NULL; which_alternative = -1; @@ -2314,7 +2349,7 @@ preprocess_constraints (void) op_alt[j].matches = -1; op_alt[j].matched = -1; - if (!recog_data.alternative_enabled_p[j]) + if (!TEST_BIT (recog_data.enabled_alternatives, j)) { p = skip_alternative (p); continue; @@ -2490,7 +2525,7 @@ constrain_operands (int strict) int lose = 0; funny_match_index = 0; - if (!recog_data.alternative_enabled_p[which_alternative]) + if (!TEST_BIT (recog_data.enabled_alternatives, which_alternative)) { int i; @@ -4164,3 +4199,19 @@ make_pass_split_for_shorten_branches (gcc::context *ctxt) { return new pass_split_for_shorten_branches (ctxt); } + +/* (Re)initialize the target information after a change in target. */ + +void +recog_init () +{ + /* The information is zero-initialized, so we don't need to do anything + first time round. */ + if (!this_target_recog->x_initialized) + { + this_target_recog->x_initialized = true; + return; + } + memset (this_target_recog->x_enabled_alternatives, 0, + sizeof (this_target_recog->x_enabled_alternatives)); +} |