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:
Wei Guozhi 2009-10-27 09:06:36 +00:00 committed by Wei Guozhi
parent 9c67ec2204
commit 2929029c50
12 changed files with 98 additions and 55 deletions

View File

@ -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>

View File

@ -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 */
}
};

View File

@ -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"

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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. */

View File

@ -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 */
}
};

View File

@ -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, \

View File

@ -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);

View File

@ -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"

View File

@ -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);