From 2929029c50e34fdc22da8b8b029daa880dd70359 Mon Sep 17 00:00:00 2001 From: Wei Guozhi Date: Tue, 27 Oct 2009 09:06:36 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 18 ++++++++++++ gcc/bb-reorder.c | 6 ---- gcc/config/arm/arm.c | 12 ++++++++ gcc/doc/tm.texi | 6 ++++ gcc/final.c | 10 ++----- gcc/ifcvt.c | 13 ++++----- gcc/recog.c | 66 +++++++++++++++++++++++--------------------- gcc/sched-rgn.c | 6 ++-- gcc/target-def.h | 2 ++ gcc/target.h | 3 ++ gcc/targhooks.c | 10 +++++++ gcc/targhooks.h | 1 + 12 files changed, 98 insertions(+), 55 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3014db71c12..14d1ed1a59f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2009-10-27 Wei Guozhi + + 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 Michael Meissner Ulrich Weigand diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index 35b4f1724e4..47828bf28c1 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -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 */ } }; - - diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 93c35901116..35bd3946c57 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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" diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 8df014dad99..0f33d3d1a8d 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -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 diff --git a/gcc/final.c b/gcc/final.c index b8f5e513817..ef450d2fe3e 100644 --- a/gcc/final.c +++ b/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; diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index d8d15a59be1..4417e6e6b87 100644 --- a/gcc/ifcvt.c +++ b/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 diff --git a/gcc/recog.c b/gcc/recog.c index b03324146f1..4ad3be9dfaf 100644 --- a/gcc/recog.c +++ b/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. */ diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index de2dd0acd1d..0acdc4a2a47 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -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 */ } }; - diff --git a/gcc/target-def.h b/gcc/target-def.h index 547a5fb89f8..c5a73216780 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -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, \ diff --git a/gcc/target.h b/gcc/target.h index a243bcd3bfb..31a54f321df 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -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); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 35ed9eed4a6..dfc470c869e 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -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" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index cbbbee89d2e..365496b9825 100644 --- a/gcc/targhooks.h +++ b/gcc/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);