target.h (have_conditional_execution): Add a new target hook function.
* target.h (have_conditional_execution): Add a new target hook function. * target-def.h (TARGET_HAVE_CONDITIONAL_EXECUTION): Likewise. * targhooks.h (default_have_conditional_execution): Likewise. * targhooks.c (default_have_conditional_execution): Likewise. * doc/tm.texi (TARGET_HAVE_CONDITIONAL_EXECUTION): Document it. * config/arm/arm.c (TARGET_HAVE_CONDITIONAL_EXECUTION): Define it. (arm_have_conditional_execution): New function. * ifcvt.c (noce_process_if_block, find_if_header, cond_exec_find_if_block, dead_or_predicable): Change the usage of macro HAVE_conditional_execution to a target hook call. * recog.c (peephole2_optimize): Likewise. * sched-rgn.c (add_branch_dependences): Likewise. * final.c (asm_insn_count, final_scan_insn): Likewise. * bb-reorder.c (HAVE_conditional_execution): Remove it. From-SVN: r153584
This commit is contained in:
parent
9c67ec2204
commit
2929029c50
|
@ -1,3 +1,21 @@
|
|||
2009-10-27 Wei Guozhi <carrot@google.com>
|
||||
|
||||
PR target/41705
|
||||
* target.h (have_conditional_execution): Add a new target hook function.
|
||||
* target-def.h (TARGET_HAVE_CONDITIONAL_EXECUTION): Likewise.
|
||||
* targhooks.h (default_have_conditional_execution): Likewise.
|
||||
* targhooks.c (default_have_conditional_execution): Likewise.
|
||||
* doc/tm.texi (TARGET_HAVE_CONDITIONAL_EXECUTION): Document it.
|
||||
* config/arm/arm.c (TARGET_HAVE_CONDITIONAL_EXECUTION): Define it.
|
||||
(arm_have_conditional_execution): New function.
|
||||
* ifcvt.c (noce_process_if_block, find_if_header,
|
||||
cond_exec_find_if_block, dead_or_predicable): Change the usage of macro
|
||||
HAVE_conditional_execution to a target hook call.
|
||||
* recog.c (peephole2_optimize): Likewise.
|
||||
* sched-rgn.c (add_branch_dependences): Likewise.
|
||||
* final.c (asm_insn_count, final_scan_insn): Likewise.
|
||||
* bb-reorder.c (HAVE_conditional_execution): Remove it.
|
||||
|
||||
2009-10-26 Ben Elliston <bje@au.ibm.com>
|
||||
Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
|
|
@ -86,10 +86,6 @@
|
|||
#include "tree-pass.h"
|
||||
#include "df.h"
|
||||
|
||||
#ifndef HAVE_conditional_execution
|
||||
#define HAVE_conditional_execution 0
|
||||
#endif
|
||||
|
||||
/* The number of rounds. In most cases there will only be 4 rounds, but
|
||||
when partitioning hot and cold basic blocks into separate sections of
|
||||
the .o file there will be an extra round.*/
|
||||
|
@ -2297,5 +2293,3 @@ struct rtl_opt_pass pass_partition_blocks =
|
|||
TODO_dump_func | TODO_verify_rtl_sharing/* todo_flags_finish */
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ static rtx arm_libcall_value (enum machine_mode, const_rtx);
|
|||
static void arm_internal_label (FILE *, const char *, unsigned long);
|
||||
static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
|
||||
tree);
|
||||
static bool arm_have_conditional_execution (void);
|
||||
static bool arm_rtx_costs_1 (rtx, enum rtx_code, int*, bool);
|
||||
static bool arm_size_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
|
||||
static bool arm_slowmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
|
||||
|
@ -445,6 +446,9 @@ static const struct attribute_spec arm_attribute_table[] =
|
|||
#define TARGET_HAVE_TLS true
|
||||
#endif
|
||||
|
||||
#undef TARGET_HAVE_CONDITIONAL_EXECUTION
|
||||
#define TARGET_HAVE_CONDITIONAL_EXECUTION arm_have_conditional_execution
|
||||
|
||||
#undef TARGET_CANNOT_FORCE_CONST_MEM
|
||||
#define TARGET_CANNOT_FORCE_CONST_MEM arm_cannot_force_const_mem
|
||||
|
||||
|
@ -21183,4 +21187,12 @@ arm_frame_pointer_required (void)
|
|||
|| (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()));
|
||||
}
|
||||
|
||||
/* Only thumb1 can't support conditional execution, so return true if
|
||||
the target is not thumb1. */
|
||||
static bool
|
||||
arm_have_conditional_execution (void)
|
||||
{
|
||||
return !TARGET_THUMB1;
|
||||
}
|
||||
|
||||
#include "gt-arm.h"
|
||||
|
|
|
@ -10842,6 +10842,12 @@ to have to make special provisions in @code{INITIAL_ELIMINATION_OFFSET}
|
|||
to reserve space for caller-saved target registers.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} bool TARGET_HAVE_CONDITIONAL_EXECUTION (void)
|
||||
This target hook returns true if the target supports conditional execution.
|
||||
This target hook is required only when the target has several different
|
||||
modes and they have different conditional execution capability, such as ARM.
|
||||
@end deftypefn
|
||||
|
||||
@defmac POWI_MAX_MULTS
|
||||
If defined, this macro is interpreted as a signed integer C expression
|
||||
that specifies the maximum number of floating point multiplications
|
||||
|
|
10
gcc/final.c
10
gcc/final.c
|
@ -204,10 +204,8 @@ rtx final_sequence;
|
|||
static int dialect_number;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_conditional_execution
|
||||
/* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */
|
||||
rtx current_insn_predicate;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATTR_length
|
||||
static int asm_insn_count (rtx);
|
||||
|
@ -2102,10 +2100,9 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
|
|||
const char *templ;
|
||||
bool is_stmt;
|
||||
|
||||
#ifdef HAVE_conditional_execution
|
||||
/* Reset this early so it is correct for ASM statements. */
|
||||
current_insn_predicate = NULL_RTX;
|
||||
#endif
|
||||
|
||||
/* An INSN, JUMP_INSN or CALL_INSN.
|
||||
First check for special kinds that recog doesn't recognize. */
|
||||
|
||||
|
@ -2590,10 +2587,9 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
|
|||
FINAL_PRESCAN_INSN (insn, recog_data.operand, recog_data.n_operands);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_conditional_execution
|
||||
if (GET_CODE (PATTERN (insn)) == COND_EXEC)
|
||||
if (targetm.have_conditional_execution ()
|
||||
&& GET_CODE (PATTERN (insn)) == COND_EXEC)
|
||||
current_insn_predicate = COND_EXEC_TEST (PATTERN (insn));
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
cc_prev_status = cc_status;
|
||||
|
|
13
gcc/ifcvt.c
13
gcc/ifcvt.c
|
@ -47,9 +47,6 @@
|
|||
#include "vecprim.h"
|
||||
#include "dbgcnt.h"
|
||||
|
||||
#ifndef HAVE_conditional_execution
|
||||
#define HAVE_conditional_execution 0
|
||||
#endif
|
||||
#ifndef HAVE_conditional_move
|
||||
#define HAVE_conditional_move 0
|
||||
#endif
|
||||
|
@ -2426,7 +2423,7 @@ noce_process_if_block (struct noce_if_info *if_info)
|
|||
if (HAVE_conditional_move
|
||||
&& noce_try_cmove (if_info))
|
||||
goto success;
|
||||
if (! HAVE_conditional_execution)
|
||||
if (! targetm.have_conditional_execution ())
|
||||
{
|
||||
if (noce_try_store_flag_constants (if_info))
|
||||
goto success;
|
||||
|
@ -3070,7 +3067,7 @@ find_if_header (basic_block test_bb, int pass)
|
|||
&& noce_find_if_block (test_bb, then_edge, else_edge, pass))
|
||||
goto success;
|
||||
|
||||
if (HAVE_conditional_execution && reload_completed
|
||||
if (targetm.have_conditional_execution () && reload_completed
|
||||
&& cond_exec_find_if_block (&ce_info))
|
||||
goto success;
|
||||
|
||||
|
@ -3080,7 +3077,7 @@ find_if_header (basic_block test_bb, int pass)
|
|||
goto success;
|
||||
|
||||
if (dom_info_state (CDI_POST_DOMINATORS) >= DOM_NO_FAST_QUERY
|
||||
&& (! HAVE_conditional_execution || reload_completed))
|
||||
&& (! targetm.have_conditional_execution () || reload_completed))
|
||||
{
|
||||
if (find_if_case_1 (test_bb, then_edge, else_edge))
|
||||
goto success;
|
||||
|
@ -3187,7 +3184,7 @@ cond_exec_find_if_block (struct ce_if_block * ce_info)
|
|||
|
||||
/* We only ever should get here after reload,
|
||||
and only if we have conditional execution. */
|
||||
gcc_assert (HAVE_conditional_execution && reload_completed);
|
||||
gcc_assert (targetm.have_conditional_execution () && reload_completed);
|
||||
|
||||
/* Discover if any fall through predecessors of the current test basic block
|
||||
were && tests (which jump to the else block) or || tests (which jump to
|
||||
|
@ -3865,7 +3862,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
|
|||
/* Disable handling dead code by conditional execution if the machine needs
|
||||
to do anything funny with the tests, etc. */
|
||||
#ifndef IFCVT_MODIFY_TESTS
|
||||
if (HAVE_conditional_execution)
|
||||
if (targetm.have_conditional_execution ())
|
||||
{
|
||||
/* In the conditional execution case, we have things easy. We know
|
||||
the condition is reversible. We don't have to check life info
|
||||
|
|
66
gcc/recog.c
66
gcc/recog.c
|
@ -3279,40 +3279,44 @@ peephole2_optimize (void)
|
|||
do_cleanup_cfg |= purge_dead_edges (bb);
|
||||
}
|
||||
|
||||
#ifdef HAVE_conditional_execution
|
||||
for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
|
||||
peep2_insn_data[i].insn = NULL_RTX;
|
||||
peep2_insn_data[peep2_current].insn = PEEP2_EOB;
|
||||
peep2_current_count = 0;
|
||||
#else
|
||||
/* Back up lifetime information past the end of the
|
||||
newly created sequence. */
|
||||
if (++i >= MAX_INSNS_PER_PEEP2 + 1)
|
||||
i = 0;
|
||||
bitmap_copy (live, peep2_insn_data[i].live_before);
|
||||
|
||||
/* Update life information for the new sequence. */
|
||||
x = attempt;
|
||||
do
|
||||
if (targetm.have_conditional_execution ())
|
||||
{
|
||||
if (INSN_P (x))
|
||||
{
|
||||
if (--i < 0)
|
||||
i = MAX_INSNS_PER_PEEP2;
|
||||
if (peep2_current_count < MAX_INSNS_PER_PEEP2
|
||||
&& peep2_insn_data[i].insn == NULL_RTX)
|
||||
peep2_current_count++;
|
||||
peep2_insn_data[i].insn = x;
|
||||
df_insn_rescan (x);
|
||||
df_simulate_one_insn_backwards (bb, x, live);
|
||||
bitmap_copy (peep2_insn_data[i].live_before, live);
|
||||
}
|
||||
x = PREV_INSN (x);
|
||||
for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
|
||||
peep2_insn_data[i].insn = NULL_RTX;
|
||||
peep2_insn_data[peep2_current].insn = PEEP2_EOB;
|
||||
peep2_current_count = 0;
|
||||
}
|
||||
while (x != prev);
|
||||
else
|
||||
{
|
||||
/* Back up lifetime information past the end of the
|
||||
newly created sequence. */
|
||||
if (++i >= MAX_INSNS_PER_PEEP2 + 1)
|
||||
i = 0;
|
||||
bitmap_copy (live, peep2_insn_data[i].live_before);
|
||||
|
||||
peep2_current = i;
|
||||
#endif
|
||||
/* Update life information for the new sequence. */
|
||||
x = attempt;
|
||||
do
|
||||
{
|
||||
if (INSN_P (x))
|
||||
{
|
||||
if (--i < 0)
|
||||
i = MAX_INSNS_PER_PEEP2;
|
||||
if (peep2_current_count < MAX_INSNS_PER_PEEP2
|
||||
&& peep2_insn_data[i].insn == NULL_RTX)
|
||||
peep2_current_count++;
|
||||
peep2_insn_data[i].insn = x;
|
||||
df_insn_rescan (x);
|
||||
df_simulate_one_insn_backwards (bb, x, live);
|
||||
bitmap_copy (peep2_insn_data[i].live_before,
|
||||
live);
|
||||
}
|
||||
x = PREV_INSN (x);
|
||||
}
|
||||
while (x != prev);
|
||||
|
||||
peep2_current = i;
|
||||
}
|
||||
|
||||
/* If we generated a jump instruction, it won't have
|
||||
JUMP_LABEL set. Recompute after we're done. */
|
||||
|
|
|
@ -2508,7 +2508,9 @@ add_branch_dependences (rtx head, rtx tail)
|
|||
add_dependence (last, insn, REG_DEP_ANTI);
|
||||
}
|
||||
|
||||
#ifdef HAVE_conditional_execution
|
||||
if (!targetm.have_conditional_execution ())
|
||||
return;
|
||||
|
||||
/* Finally, if the block ends in a jump, and we are doing intra-block
|
||||
scheduling, make sure that the branch depends on any COND_EXEC insns
|
||||
inside the block to avoid moving the COND_EXECs past the branch insn.
|
||||
|
@ -2557,7 +2559,6 @@ add_branch_dependences (rtx head, rtx tail)
|
|||
if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == COND_EXEC)
|
||||
add_dependence (tail, insn, REG_DEP_ANTI);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Data structures for the computation of data dependences in a regions. We
|
||||
|
@ -3588,4 +3589,3 @@ struct rtl_opt_pass pass_sched2 =
|
|||
TODO_ggc_collect /* todo_flags_finish */
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -534,6 +534,7 @@
|
|||
#define TARGET_BRANCH_TARGET_REGISTER_CLASS \
|
||||
default_branch_target_register_class
|
||||
#define TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED hook_bool_bool_false
|
||||
#define TARGET_HAVE_CONDITIONAL_EXECUTION default_have_conditional_execution
|
||||
#define TARGET_CANNOT_FORCE_CONST_MEM hook_bool_rtx_false
|
||||
#define TARGET_CANNOT_COPY_INSN_P NULL
|
||||
#define TARGET_COMMUTATIVE_P hook_bool_const_rtx_commutative_p
|
||||
|
@ -934,6 +935,7 @@
|
|||
TARGET_CANNOT_MODIFY_JUMPS_P, \
|
||||
TARGET_BRANCH_TARGET_REGISTER_CLASS, \
|
||||
TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED, \
|
||||
TARGET_HAVE_CONDITIONAL_EXECUTION, \
|
||||
TARGET_CANNOT_FORCE_CONST_MEM, \
|
||||
TARGET_CANNOT_COPY_INSN_P, \
|
||||
TARGET_COMMUTATIVE_P, \
|
||||
|
|
|
@ -621,6 +621,9 @@ struct gcc_target
|
|||
already been generated. */
|
||||
bool (* branch_target_register_callee_saved) (bool after_pe_gen);
|
||||
|
||||
/* Return true if the target supports conditional execution. */
|
||||
bool (* have_conditional_execution) (void);
|
||||
|
||||
/* True if the constant X cannot be placed in the constant pool. */
|
||||
bool (* cannot_force_const_mem) (rtx);
|
||||
|
||||
|
|
|
@ -998,4 +998,14 @@ unsigned int default_case_values_threshold (void)
|
|||
return (HAVE_casesi ? 4 : 5);
|
||||
}
|
||||
|
||||
bool
|
||||
default_have_conditional_execution (void)
|
||||
{
|
||||
#ifdef HAVE_conditional_execution
|
||||
return HAVE_conditional_execution;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "gt-targhooks.h"
|
||||
|
|
|
@ -131,3 +131,4 @@ extern rtx default_addr_space_legitimize_address (rtx, rtx, enum machine_mode,
|
|||
extern bool default_addr_space_subset_p (addr_space_t, addr_space_t);
|
||||
extern rtx default_addr_space_convert (rtx, tree, tree);
|
||||
extern unsigned int default_case_values_threshold (void);
|
||||
extern bool default_have_conditional_execution (void);
|
||||
|
|
Loading…
Reference in New Issue