remove unused files
[platform/upstream/gcc48.git] / gcc / ifcvt.c
index e4e13ab..88967a6 100644 (file)
@@ -1,7 +1,5 @@
 /* If-conversion support.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010,
-   2011
-   Free Software Foundation, Inc.
+   Copyright (C) 2000-2013 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
 #include "tm_p.h"
 #include "cfgloop.h"
 #include "target.h"
-#include "timevar.h"
 #include "tree-pass.h"
 #include "df.h"
 #include "vec.h"
-#include "vecprim.h"
+#include "pointer-set.h"
 #include "dbgcnt.h"
 
 #ifndef HAVE_conditional_move
@@ -903,7 +900,7 @@ noce_emit_move_insn (rtx x, rtx y)
          switch (GET_RTX_CLASS (GET_CODE (y)))
            {
            case RTX_UNARY:
-             ot = code_to_optab[GET_CODE (y)];
+             ot = code_to_optab (GET_CODE (y));
              if (ot)
                {
                  start_sequence ();
@@ -920,7 +917,7 @@ noce_emit_move_insn (rtx x, rtx y)
 
            case RTX_BIN_ARITH:
            case RTX_COMM_ARITH:
-             ot = code_to_optab[GET_CODE (y)];
+             ot = code_to_optab (GET_CODE (y));
              if (ot)
                {
                  start_sequence ();
@@ -967,6 +964,8 @@ end_ifcvt_sequence (struct noce_if_info *if_info)
 
   set_used_flags (if_info->x);
   set_used_flags (if_info->cond);
+  set_used_flags (if_info->a);
+  set_used_flags (if_info->b);
   unshare_all_rtl_in_chain (seq);
   end_sequence ();
 
@@ -1020,7 +1019,7 @@ noce_try_move (struct noce_if_info *if_info)
            return FALSE;
 
          emit_insn_before_setloc (seq, if_info->jump,
-                                  INSN_LOCATOR (if_info->insn_a));
+                                  INSN_LOCATION (if_info->insn_a));
        }
       return TRUE;
     }
@@ -1065,7 +1064,7 @@ noce_try_store_flag (struct noce_if_info *if_info)
        return FALSE;
 
       emit_insn_before_setloc (seq, if_info->jump,
-                              INSN_LOCATOR (if_info->insn_a));
+                              INSN_LOCATION (if_info->insn_a));
       return TRUE;
     }
   else
@@ -1196,7 +1195,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
        return FALSE;
 
       emit_insn_before_setloc (seq, if_info->jump,
-                              INSN_LOCATOR (if_info->insn_a));
+                              INSN_LOCATION (if_info->insn_a));
       return TRUE;
     }
 
@@ -1244,7 +1243,7 @@ noce_try_addcc (struct noce_if_info *if_info)
                return FALSE;
 
              emit_insn_before_setloc (seq, if_info->jump,
-                                      INSN_LOCATOR (if_info->insn_a));
+                                      INSN_LOCATION (if_info->insn_a));
              return TRUE;
            }
          end_sequence ();
@@ -1284,7 +1283,7 @@ noce_try_addcc (struct noce_if_info *if_info)
                return FALSE;
 
              emit_insn_before_setloc (seq, if_info->jump,
-                                      INSN_LOCATOR (if_info->insn_a));
+                                      INSN_LOCATION (if_info->insn_a));
              return TRUE;
            }
          end_sequence ();
@@ -1333,7 +1332,7 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
            return FALSE;
 
          emit_insn_before_setloc (seq, if_info->jump,
-                                  INSN_LOCATOR (if_info->insn_a));
+                                  INSN_LOCATION (if_info->insn_a));
          return TRUE;
        }
 
@@ -1482,7 +1481,7 @@ noce_try_cmove (struct noce_if_info *if_info)
            return FALSE;
 
          emit_insn_before_setloc (seq, if_info->jump,
-                                  INSN_LOCATOR (if_info->insn_a));
+                                  INSN_LOCATION (if_info->insn_a));
          return TRUE;
        }
       else
@@ -1520,8 +1519,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
       && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b)
       && if_info->branch_cost >= 5)
     {
-      enum machine_mode address_mode
-       = targetm.addr_space.address_mode (MEM_ADDR_SPACE (a));
+      enum machine_mode address_mode = get_address_mode (a);
 
       a = XEXP (a, 0);
       b = XEXP (b, 0);
@@ -1684,7 +1682,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
   if (!tmp)
     return FALSE;
 
-  emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR (if_info->insn_a));
+  emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATION (if_info->insn_a));
   return TRUE;
 
  end_seq_and_fail:
@@ -1931,7 +1929,7 @@ noce_try_minmax (struct noce_if_info *if_info)
   if (!seq)
     return FALSE;
 
-  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
+  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
   if_info->cond = cond;
   if_info->cond_earliest = earliest;
 
@@ -2078,7 +2076,7 @@ noce_try_abs (struct noce_if_info *if_info)
   if (!seq)
     return FALSE;
 
-  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
+  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
   if_info->cond = cond;
   if_info->cond_earliest = earliest;
 
@@ -2157,7 +2155,7 @@ noce_try_sign_mask (struct noce_if_info *if_info)
   if (!seq)
     return FALSE;
 
-  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
+  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
   return TRUE;
 }
 
@@ -2257,7 +2255,7 @@ noce_try_bitop (struct noce_if_info *if_info)
        return FALSE;
 
       emit_insn_before_setloc (seq, if_info->jump,
-                              INSN_LOCATOR (if_info->insn_a));
+                              INSN_LOCATION (if_info->insn_a));
     }
   return TRUE;
 }
@@ -2416,7 +2414,7 @@ noce_can_store_speculate_p (basic_block top_bb, const_rtx mem)
                  || (CALL_P (insn) && (!RTL_CONST_CALL_P (insn)))))
            return false;
 
-         if (memory_modified_in_insn_p (mem, insn))
+         if (memory_must_be_modified_in_insn_p (mem, insn))
            return true;
          if (modified_in_p (XEXP (mem, 0), insn))
            return false;
@@ -2495,6 +2493,12 @@ noce_process_if_block (struct noce_if_info *if_info)
          || ! noce_operand_ok (SET_SRC (set_b))
          || reg_overlap_mentioned_p (x, SET_SRC (set_b))
          || modified_between_p (SET_SRC (set_b), insn_b, jump)
+         /* Avoid extending the lifetime of hard registers on small
+            register class machines.  */
+         || (REG_P (SET_SRC (set_b))
+             && HARD_REGISTER_P (SET_SRC (set_b))
+             && targetm.small_register_classes_for_mode_p
+                  (GET_MODE (SET_SRC (set_b))))
          /* Likewise with X.  In particular this can happen when
             noce_get_condition looks farther back in the instruction
             stream than one might expect.  */
@@ -2658,7 +2662,7 @@ noce_process_if_block (struct noce_if_info *if_info)
       unshare_all_rtl_in_chain (seq);
       end_sequence ();
 
-      emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATOR (insn_a));
+      emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATION (insn_a));
     }
 
   /* The original THEN and ELSE blocks may now be removed.  The test block
@@ -2689,12 +2693,14 @@ noce_process_if_block (struct noce_if_info *if_info)
 
 /* Check whether a block is suitable for conditional move conversion.
    Every insn must be a simple set of a register to a constant or a
-   register.  For each assignment, store the value in the array VALS,
-   indexed by register number, then store the register number in
-   REGS.  COND is the condition we will test.  */
+   register.  For each assignment, store the value in the pointer map
+   VALS, keyed indexed by register pointer, then store the register
+   pointer in REGS.  COND is the condition we will test.  */
 
 static int
-check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs,
+check_cond_move_block (basic_block bb,
+                      struct pointer_map_t *vals,
+                      vec<rtx> *regs,
                       rtx cond)
 {
   rtx insn;
@@ -2708,6 +2714,7 @@ check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs,
   FOR_BB_INSNS (bb, insn)
     {
       rtx set, dest, src;
+      void **slot;
 
       if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
        continue;
@@ -2734,14 +2741,14 @@ check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs,
       /* Don't try to handle this if the source register was
         modified earlier in the block.  */
       if ((REG_P (src)
-          && vals[REGNO (src)] != NULL)
+          && pointer_map_contains (vals, src))
          || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
-             && vals[REGNO (SUBREG_REG (src))] != NULL))
+             && pointer_map_contains (vals, SUBREG_REG (src))))
        return FALSE;
 
       /* Don't try to handle this if the destination register was
         modified earlier in the block.  */
-      if (vals[REGNO (dest)] != NULL)
+      if (pointer_map_contains (vals, dest))
        return FALSE;
 
       /* Don't try to handle this if the condition uses the
@@ -2755,17 +2762,18 @@ check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs,
          && modified_between_p (src, insn, NEXT_INSN (BB_END (bb))))
        return FALSE;
 
-      vals[REGNO (dest)] = src;
+      slot = pointer_map_insert (vals, (void *) dest);
+      *slot = (void *) src;
 
-      VEC_safe_push (int, heap, *regs, REGNO (dest));
+      regs->safe_push (dest);
     }
 
   return TRUE;
 }
 
 /* Given a basic block BB suitable for conditional move conversion,
-   a condition COND, and arrays THEN_VALS and ELSE_VALS containing the
-   register values depending on COND, emit the insns in the block as
+   a condition COND, and pointer maps THEN_VALS and ELSE_VALS containing
+   the register values depending on COND, emit the insns in the block as
    conditional moves.  If ELSE_BLOCK is true, THEN_BB was already
    processed.  The caller has started a sequence for the conversion.
    Return true if successful, false if something goes wrong.  */
@@ -2773,7 +2781,8 @@ check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs,
 static bool
 cond_move_convert_if_block (struct noce_if_info *if_infop,
                            basic_block bb, rtx cond,
-                           rtx *then_vals, rtx *else_vals,
+                           struct pointer_map_t *then_vals,
+                           struct pointer_map_t *else_vals,
                            bool else_block_p)
 {
   enum rtx_code code;
@@ -2786,7 +2795,7 @@ cond_move_convert_if_block (struct noce_if_info *if_infop,
   FOR_BB_INSNS (bb, insn)
     {
       rtx set, target, dest, t, e;
-      unsigned int regno;
+      void **then_slot, **else_slot;
 
       /* ??? Maybe emit conditional debug insn?  */
       if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
@@ -2795,10 +2804,11 @@ cond_move_convert_if_block (struct noce_if_info *if_infop,
       gcc_assert (set && REG_P (SET_DEST (set)));
 
       dest = SET_DEST (set);
-      regno = REGNO (dest);
 
-      t = then_vals[regno];
-      e = else_vals[regno];
+      then_slot = pointer_map_contains (then_vals, dest);
+      else_slot = pointer_map_contains (else_vals, dest);
+      t = then_slot ? (rtx) *then_slot : NULL_RTX;
+      e = else_slot ? (rtx) *else_slot : NULL_RTX;
 
       if (else_block_p)
        {
@@ -2842,31 +2852,25 @@ cond_move_process_if_block (struct noce_if_info *if_info)
   rtx jump = if_info->jump;
   rtx cond = if_info->cond;
   rtx seq, loc_insn;
-  int max_reg, size, c, reg;
-  rtx *then_vals;
-  rtx *else_vals;
-  VEC (int, heap) *then_regs = NULL;
-  VEC (int, heap) *else_regs = NULL;
+  rtx reg;
+  int c;
+  struct pointer_map_t *then_vals;
+  struct pointer_map_t *else_vals;
+  vec<rtx> then_regs = vNULL;
+  vec<rtx> else_regs = vNULL;
   unsigned int i;
+  int success_p = FALSE;
 
   /* Build a mapping for each block to the value used for each
      register.  */
-  max_reg = max_reg_num ();
-  size = (max_reg + 1) * sizeof (rtx);
-  then_vals = (rtx *) alloca (size);
-  else_vals = (rtx *) alloca (size);
-  memset (then_vals, 0, size);
-  memset (else_vals, 0, size);
+  then_vals = pointer_map_create ();
+  else_vals = pointer_map_create ();
 
   /* Make sure the blocks are suitable.  */
   if (!check_cond_move_block (then_bb, then_vals, &then_regs, cond)
       || (else_bb
          && !check_cond_move_block (else_bb, else_vals, &else_regs, cond)))
-    {
-      VEC_free (int, heap, then_regs);
-      VEC_free (int, heap, else_regs);
-      return FALSE;
-    }
+    goto done;
 
   /* Make sure the blocks can be used together.  If the same register
      is set in both blocks, and is not set to a constant in both
@@ -2875,41 +2879,38 @@ cond_move_process_if_block (struct noce_if_info *if_info)
      source register does not change after the assignment.  Also count
      the number of registers set in only one of the blocks.  */
   c = 0;
-  FOR_EACH_VEC_ELT (int, then_regs, i, reg)
+  FOR_EACH_VEC_ELT (then_regs, i, reg)
     {
-      if (!then_vals[reg] && !else_vals[reg])
-       continue;
+      void **then_slot = pointer_map_contains (then_vals, reg);
+      void **else_slot = pointer_map_contains (else_vals, reg);
 
-      if (!else_vals[reg])
+      gcc_checking_assert (then_slot);
+      if (!else_slot)
        ++c;
       else
        {
-         if (!CONSTANT_P (then_vals[reg])
-             && !CONSTANT_P (else_vals[reg])
-             && !rtx_equal_p (then_vals[reg], else_vals[reg]))
-           {
-             VEC_free (int, heap, then_regs);
-             VEC_free (int, heap, else_regs);
-             return FALSE;
-           }
+         rtx then_val = (rtx) *then_slot;
+         rtx else_val = (rtx) *else_slot;
+         if (!CONSTANT_P (then_val) && !CONSTANT_P (else_val)
+             && !rtx_equal_p (then_val, else_val))
+           goto done;
        }
     }
 
   /* Finish off c for MAX_CONDITIONAL_EXECUTE.  */
-  FOR_EACH_VEC_ELT (int, else_regs, i, reg)
-    if (!then_vals[reg])
-      ++c;
+  FOR_EACH_VEC_ELT (else_regs, i, reg)
+    {
+      gcc_checking_assert (pointer_map_contains (else_vals, reg));
+      if (!pointer_map_contains (then_vals, reg))
+       ++c;
+    }
 
   /* Make sure it is reasonable to convert this block.  What matters
      is the number of assignments currently made in only one of the
      branches, since if we convert we are going to always execute
      them.  */
   if (c > MAX_CONDITIONAL_EXECUTE)
-    {
-      VEC_free (int, heap, then_regs);
-      VEC_free (int, heap, else_regs);
-      return FALSE;
-    }
+    goto done;
 
   /* Try to emit the conditional moves.  First do the then block,
      then do anything left in the else blocks.  */
@@ -2921,17 +2922,11 @@ cond_move_process_if_block (struct noce_if_info *if_info)
                                          then_vals, else_vals, true)))
     {
       end_sequence ();
-      VEC_free (int, heap, then_regs);
-      VEC_free (int, heap, else_regs);
-      return FALSE;
+      goto done;
     }
   seq = end_ifcvt_sequence (if_info);
   if (!seq)
-    {
-      VEC_free (int, heap, then_regs);
-      VEC_free (int, heap, else_regs);
-      return FALSE;
-    }
+    goto done;
 
   loc_insn = first_active_insn (then_bb);
   if (!loc_insn)
@@ -2939,7 +2934,7 @@ cond_move_process_if_block (struct noce_if_info *if_info)
       loc_insn = first_active_insn (else_bb);
       gcc_assert (loc_insn);
     }
-  emit_insn_before_setloc (seq, jump, INSN_LOCATOR (loc_insn));
+  emit_insn_before_setloc (seq, jump, INSN_LOCATION (loc_insn));
 
   if (else_bb)
     {
@@ -2962,9 +2957,14 @@ cond_move_process_if_block (struct noce_if_info *if_info)
 
   num_updated_if_blocks++;
 
-  VEC_free (int, heap, then_regs);
-  VEC_free (int, heap, else_regs);
-  return TRUE;
+  success_p = TRUE;
+
+done:
+  pointer_map_destroy (then_vals);
+  pointer_map_destroy (else_vals);
+  then_regs.release ();
+  else_regs.release ();
+  return success_p;
 }
 
 \f
@@ -3256,8 +3256,8 @@ find_if_header (basic_block test_bb, int pass)
   ce_info.else_bb = else_edge->dest;
   ce_info.pass = pass;
 
-#ifdef IFCVT_INIT_EXTRA_FIELDS
-  IFCVT_INIT_EXTRA_FIELDS (&ce_info);
+#ifdef IFCVT_MACHDEP_INIT
+  IFCVT_MACHDEP_INIT (&ce_info);
 #endif
 
   if (!reload_completed
@@ -3475,7 +3475,7 @@ cond_exec_find_if_block (struct ce_if_block * ce_info)
      code processing.  ??? we should fix this in the future.  */
   if (EDGE_COUNT (then_bb->succs) == 0)
     {
-      if (single_pred_p (else_bb))
+      if (single_pred_p (else_bb) && else_bb != EXIT_BLOCK_PTR)
        {
          rtx last_insn = BB_END (then_bb);
 
@@ -3657,7 +3657,7 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
     return FALSE;
 
   /* Emit the new insns before cond_earliest.  */
-  emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATOR (trap));
+  emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATION (trap));
 
   /* Delete the trap block if possible.  */
   remove_edge (trap_bb == then_bb ? then_edge : else_edge);
@@ -3878,7 +3878,7 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
 
   /* We can avoid creating a new basic block if then_bb is immediately
      followed by else_bb, i.e. deleting then_bb allows test_bb to fall
-     thru to else_bb.  */
+     through to else_bb.  */
 
   if (then_bb->next_bb == else_bb
       && then_bb->prev_bb == test_bb
@@ -3927,6 +3927,11 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
   edge else_succ;
   int then_prob, else_prob;
 
+  /* We do not want to speculate (empty) loop latches.  */
+  if (current_loops
+      && else_bb->loop_father->latch == else_bb)
+    return FALSE;
+
   /* If we are partitioning hot/cold basic blocks, we don't want to
      mess up unconditional or indirect jumps that cross between hot
      and cold sections.
@@ -4388,12 +4393,7 @@ if_convert (void)
 
 #ifdef IFCVT_MULTIPLE_DUMPS
       if (dump_file && cond_exec_changed_p)
-       {
-         if (dump_flags & TDF_SLIM)
-           print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags);
-         else
-           print_rtl_with_bb (dump_file, get_insns ());
-       }
+       print_rtl_with_bb (dump_file, get_insns (), dump_flags);
 #endif
     }
   while (cond_exec_changed_p);
@@ -4450,7 +4450,10 @@ rest_of_handle_if_conversion (void)
   if (flag_if_conversion)
     {
       if (dump_file)
-        dump_flow_info (dump_file, dump_flags);
+       {
+         dump_reg_info (dump_file);
+         dump_flow_info (dump_file, dump_flags);
+       }
       cleanup_cfg (CLEANUP_EXPENSIVE);
       if_convert ();
     }
@@ -4464,6 +4467,7 @@ struct rtl_opt_pass pass_rtl_ifcvt =
  {
   RTL_PASS,
   "ce1",                                /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
   gate_handle_if_conversion,            /* gate */
   rest_of_handle_if_conversion,         /* execute */
   NULL,                                 /* sub */
@@ -4501,6 +4505,7 @@ struct rtl_opt_pass pass_if_after_combine =
  {
   RTL_PASS,
   "ce2",                                /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
   gate_handle_if_after_combine,         /* gate */
   rest_of_handle_if_after_combine,      /* execute */
   NULL,                                 /* sub */
@@ -4537,6 +4542,7 @@ struct rtl_opt_pass pass_if_after_reload =
  {
   RTL_PASS,
   "ce3",                                /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
   gate_handle_if_after_reload,          /* gate */
   rest_of_handle_if_after_reload,       /* execute */
   NULL,                                 /* sub */