This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH: PR target/41705] Enable if conversion for thumb1 by new HAVE_conditional_execution definition


The new patch added a new target hook have_conditional_execution to do the same
work as original macro HAVE_conditional_execution. But now we can have more
flexibility to return different result according to different target mode at
runtime. For arm it returns true when the target is not thumb1.

All the usage of macro HAVE_conditional_execution has been changed to the new
target hook call.

Test:
This patch was applied to trunk GCC and tested on the arm emulator with newlib.
No new failure.


ChangeLog:
2009-10-19  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.
        * config/arm/arm-protos.h (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.

thanks
Guozhi



Index: target.h
===================================================================
--- target.h    (revision 152888)
+++ target.h    (working copy)
@@ -615,6 +615,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);


Index: target-def.h
===================================================================
--- target-def.h        (revision 152888)
+++ target-def.h        (working copy)
@@ -492,6 +492,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
@@ -892,6 +893,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,                                \


Index: targhooks.h
===================================================================
--- targhooks.h (revision 152888)
+++ targhooks.h (working copy)
@@ -120,3 +120,4 @@ extern bool default_target_option_valid_
 extern bool default_target_option_pragma_parse (tree, tree);
 extern bool default_target_can_inline_p (tree, tree);
 extern unsigned int default_case_values_threshold (void);
+extern bool default_have_conditional_execution (void);


Index: targhooks.c
===================================================================
--- targhooks.c (revision 152888)
+++ targhooks.c (working copy)
@@ -892,4 +892,13 @@ unsigned int default_case_values_thresho
   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"


Index: doc/tm.texi
===================================================================
--- doc/tm.texi (revision 152888)
+++ doc/tm.texi (working copy)
@@ -10733,6 +10733,12 @@ to have to make special provisions in @c
 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


Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c    (revision 152888)
+++ config/arm/arm.c    (working copy)
@@ -445,6 +445,9 @@ static const struct attribute_spec arm_a
 #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

@@ -21173,4 +21176,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.  */
+bool
+arm_have_conditional_execution (void)
+{
+  return !TARGET_THUMB1;
+}
+
 #include "gt-arm.h"


Index: config/arm/arm-protos.h
===================================================================
--- config/arm/arm-protos.h     (revision 152888)
+++ config/arm/arm-protos.h     (working copy)
@@ -41,7 +41,8 @@ extern HOST_WIDE_INT thumb_compute_initi
                                                               unsigned int);
 extern unsigned int arm_dbx_register_number (unsigned int);
 extern void arm_output_fn_unwind (FILE *, bool);
-
+extern bool arm_have_conditional_execution (void);
+

 #ifdef RTX_CODE
 extern bool arm_vector_mode_supported_p (enum machine_mode);
@@ -146,7 +147,8 @@ extern const char *vfp_output_fstmd (rtx
 extern void arm_set_return_address (rtx, rtx);
 extern int arm_eliminable_register (rtx);
 extern const char *arm_output_shift(rtx *, int);
-
+extern bool removable_cmp_0 (rtx cmp_op);
+extern const char *emit_branch_after_movs (rtx *operands);
 extern bool arm_output_addr_const_extra (FILE *, rtx);

 #if defined TREE_CODE


Index: ifcvt.c
===================================================================
--- ifcvt.c     (revision 152888)
+++ ifcvt.c     (working copy)
@@ -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
@@ -2419,7 +2416,7 @@ noce_process_if_block (struct noce_if_in
   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;
@@ -3063,7 +3060,7 @@ find_if_header (basic_block test_bb, int
       && 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;

@@ -3073,7 +3070,7 @@ find_if_header (basic_block test_bb, int
     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;
@@ -3180,7 +3177,7 @@ cond_exec_find_if_block (struct ce_if_bl

   /* 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
@@ -3858,7 +3855,7 @@ dead_or_predicable (basic_block test_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


Index: recog.c
===================================================================
--- recog.c     (revision 152888)
+++ recog.c     (working copy)
@@ -3267,40 +3267,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 (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);
+                  if (targetm.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 (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;
-#endif
+                      peep2_current = i;
+                    }

                  /* If we generated a jump instruction, it won't have
                     JUMP_LABEL set.  Recompute after we're done.  */


Index: sched-rgn.c
===================================================================
--- sched-rgn.c (revision 152888)
+++ sched-rgn.c (working copy)
@@ -2508,7 +2508,9 @@ add_branch_dependences (rtx head, rtx ta
          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 ta
       if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == COND_EXEC)
        add_dependence (tail, insn, REG_DEP_ANTI);
     }
-#endif
 }


Index: final.c
===================================================================
--- final.c     (revision 152888)
+++ final.c     (working copy)
@@ -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, i
        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, i
        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;


Index: bb-reorder.c
===================================================================
--- bb-reorder.c        (revision 152888)
+++ bb-reorder.c        (working copy)
@@ -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.*/



On Sat, Oct 17, 2009 at 2:01 PM, Ian Lance Taylor <iant@google.com> wrote:
>>> The quick solution would be to introduce a new target hook and change
>>> every place that checks HAVE_conditional_execution to check that.
>>
>> I'm afraid simply replacing all HAVE_conditional_execution with new target hook
>> may break other targets have HAVE_conditional_execution enabled.
>
> Just make the default value for the target hook return
> HAVE_conditional_execution.
>
> Ian
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]