PR c++/68795: fix uninitialized close_paren_loc in cp_parser_postfix_expression
[gcc.git] / gcc / auto-inc-dec.c
index 47f516dd33d079a15a2ad89c1ebe1616c681e3cd..bf4959baabc4291023a8981986dffb6819cbc4fa 100644 (file)
@@ -1,5 +1,5 @@
 /* Discovery of auto-inc and auto-dec instructions.
-   Copyright (C) 2006-2014 Free Software Foundation, Inc.
+   Copyright (C) 2006-2016 Free Software Foundation, Inc.
    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
 
 This file is part of GCC.
@@ -21,24 +21,20 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
+#include "backend.h"
+#include "target.h"
 #include "rtl.h"
-#include "tm_p.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
+#include "tree.h"
+#include "predict.h"
+#include "df.h"
 #include "insn-config.h"
-#include "regs.h"
-#include "flags.h"
-#include "function.h"
-#include "except.h"
-#include "diagnostic-core.h"
+#include "emit-rtl.h"
 #include "recog.h"
+#include "cfgrtl.h"
 #include "expr.h"
 #include "tree-pass.h"
-#include "df.h"
 #include "dbgcnt.h"
-#include "target.h"
+#include "print-rtl.h"
 
 /* This pass was originally removed from flow.c. However there is
    almost nothing that remains of that code.
@@ -110,7 +106,6 @@ along with GCC; see the file COPYING3.  If not see
   before the ref or +c if the increment was after the ref, then if we
   can do the combination but switch the pre/post bit.  */
 
-#ifdef AUTO_INC_DEC
 
 enum form
 {
@@ -295,7 +290,7 @@ init_decision_table (void)
 
 static struct inc_insn
 {
-  rtx insn;           /* The insn being parsed.  */
+  rtx_insn *insn;     /* The insn being parsed.  */
   rtx pat;            /* The pattern of the insn.  */
   bool reg1_is_const; /* True if reg1 is const, false if reg1 is a reg.  */
   enum form form;
@@ -355,7 +350,7 @@ dump_inc_insn (FILE *file)
 
 static struct mem_insn
 {
-  rtx insn;           /* The insn being parsed.  */
+  rtx_insn *insn;     /* The insn being parsed.  */
   rtx pat;            /* The pattern of the insn.  */
   rtx *mem_loc;       /* The address of the field that holds the mem */
                       /* that is to be replaced.  */
@@ -397,9 +392,9 @@ dump_mem_insn (FILE *file)
    must be compared with the current block.
 */
 
-static rtx *reg_next_use = NULL;
-static rtx *reg_next_inc_use = NULL;
-static rtx *reg_next_def = NULL;
+static rtx_insn **reg_next_use = NULL;
+static rtx_insn **reg_next_inc_use = NULL;
+static rtx_insn **reg_next_def = NULL;
 
 
 /* Move dead note that match PATTERN to TO_INSN from FROM_INSN.  We do
@@ -408,7 +403,7 @@ static rtx *reg_next_def = NULL;
    does not appear that there are any other kinds of relevant notes.  */
 
 static void
-move_dead_notes (rtx to_insn, rtx from_insn, rtx pattern)
+move_dead_notes (rtx_insn *to_insn, rtx_insn *from_insn, rtx pattern)
 {
   rtx note;
   rtx next_note;
@@ -432,24 +427,6 @@ move_dead_notes (rtx to_insn, rtx from_insn, rtx pattern)
     }
 }
 
-
-/* Create a mov insn DEST_REG <- SRC_REG and insert it before
-   NEXT_INSN.  */
-
-static rtx
-insert_move_insn_before (rtx next_insn, rtx dest_reg, rtx src_reg)
-{
-  rtx insns;
-
-  start_sequence ();
-  emit_move_insn (dest_reg, src_reg);
-  insns = get_insns ();
-  end_sequence ();
-  emit_insn_before (insns, next_insn);
-  return insns;
-}
-
-
 /* Change mem_insn.mem_loc so that uses NEW_ADDR which has an
    increment of INC_REG.  To have reached this point, the change is a
    legitimate one from a dataflow point of view.  The only questions
@@ -469,10 +446,10 @@ attempt_change (rtx new_addr, rtx inc_reg)
      handled mov free.  */
 
   basic_block bb = BLOCK_FOR_INSN (mem_insn.insn);
-  rtx mov_insn = NULL;
+  rtx_insn *mov_insn = NULL;
   int regno;
   rtx mem = *mem_insn.mem_loc;
-  enum machine_mode mode = GET_MODE (mem);
+  machine_mode mode = GET_MODE (mem);
   rtx new_mem;
   int old_cost = 0;
   int new_cost = 0;
@@ -481,9 +458,22 @@ attempt_change (rtx new_addr, rtx inc_reg)
   PUT_MODE (mem_tmp, mode);
   XEXP (mem_tmp, 0) = new_addr;
 
-  old_cost = (set_src_cost (mem, speed)
+  old_cost = (set_src_cost (mem, mode, speed)
              + set_rtx_cost (PATTERN (inc_insn.insn), speed));
-  new_cost = set_src_cost (mem_tmp, speed);
+
+  new_cost = set_src_cost (mem_tmp, mode, speed);
+
+  /* In the FORM_PRE_ADD and FORM_POST_ADD cases we emit an extra move
+     whose cost we should account for.  */
+  if (inc_insn.form == FORM_PRE_ADD
+      || inc_insn.form == FORM_POST_ADD)
+    {
+      start_sequence ();
+      emit_move_insn (inc_insn.reg_res, inc_insn.reg0);
+      mov_insn = get_insns ();
+      end_sequence ();
+      new_cost += seq_cost (mov_insn, speed);
+    }
 
   /* The first item of business is to see if this is profitable.  */
   if (old_cost < new_cost)
@@ -515,8 +505,8 @@ attempt_change (rtx new_addr, rtx inc_reg)
       /* Replace the addition with a move.  Do it at the location of
         the addition since the operand of the addition may change
         before the memory reference.  */
-      mov_insn = insert_move_insn_before (inc_insn.insn,
-                                         inc_insn.reg_res, inc_insn.reg0);
+      gcc_assert (mov_insn);
+      emit_insn_before (mov_insn, inc_insn.insn);
       move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
 
       regno = REGNO (inc_insn.reg_res);
@@ -541,8 +531,8 @@ attempt_change (rtx new_addr, rtx inc_reg)
       break;
 
     case FORM_POST_ADD:
-      mov_insn = insert_move_insn_before (mem_insn.insn,
-                                         inc_insn.reg_res, inc_insn.reg0);
+      gcc_assert (mov_insn);
+      emit_insn_before (mov_insn, mem_insn.insn);
       move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
 
       /* Do not move anything to the mov insn because the instruction
@@ -611,8 +601,8 @@ try_merge (void)
 
   /* The width of the mem being accessed.  */
   int size = GET_MODE_SIZE (GET_MODE (mem));
-  rtx last_insn = NULL;
-  enum machine_mode reg_mode = GET_MODE (inc_reg);
+  rtx_insn *last_insn = NULL;
+  machine_mode reg_mode = GET_MODE (inc_reg);
 
   switch (inc_insn.form)
     {
@@ -738,10 +728,10 @@ try_merge (void)
    NEXT_ARRAY) or defines (if reg_next_def is passed in NEXT_ARRAY)
    REGNO in BB.  */
 
-static rtx
-get_next_ref (int regno, basic_block bb, rtx *next_array)
+static rtx_insn *
+get_next_ref (int regno, basic_block bb, rtx_insn **next_array)
 {
-  rtx insn = next_array[regno];
+  rtx_insn *insn = next_array[regno];
 
   /* Lazy about cleaning out the next_arrays.  */
   if (insn && BLOCK_FOR_INSN (insn) != bb)
@@ -754,28 +744,6 @@ get_next_ref (int regno, basic_block bb, rtx *next_array)
 }
 
 
-/* Reverse the operands in a mem insn.  */
-
-static void
-reverse_mem (void)
-{
-  rtx tmp = mem_insn.reg1;
-  mem_insn.reg1 = mem_insn.reg0;
-  mem_insn.reg0 = tmp;
-}
-
-
-/* Reverse the operands in a inc insn.  */
-
-static void
-reverse_inc (void)
-{
-  rtx tmp = inc_insn.reg1;
-  inc_insn.reg1 = inc_insn.reg0;
-  inc_insn.reg0 = tmp;
-}
-
-
 /* Return true if INSN is of a form "a = b op c" where a and b are
    regs.  op is + if c is a reg and +|- if c is a const.  Fill in
    INC_INSN with what is found.
@@ -787,7 +755,7 @@ reverse_inc (void)
    processed.  */
 
 static bool
-parse_add_or_inc (rtx insn, bool before_mem)
+parse_add_or_inc (rtx_insn *insn, bool before_mem)
 {
   rtx pat = single_set (insn);
   if (!pat)
@@ -844,7 +812,7 @@ parse_add_or_inc (rtx insn, bool before_mem)
        {
          /* Reverse the two operands and turn *_ADD into *_INC since
             a = c + a.  */
-         reverse_inc ();
+         std::swap (inc_insn.reg0, inc_insn.reg1);
          inc_insn.form = before_mem ? FORM_PRE_INC : FORM_POST_INC;
          return true;
        }
@@ -966,10 +934,10 @@ find_address (rtx *address_of_x)
 static bool
 find_inc (bool first_try)
 {
-  rtx insn;
+  rtx_insn *insn;
   basic_block bb = BLOCK_FOR_INSN (mem_insn.insn);
-  rtx other_insn;
-  df_ref *def_rec;
+  rtx_insn *other_insn;
+  df_ref def;
 
   /* Make sure this reg appears only once in this insn.  */
   if (count_occurrences (PATTERN (mem_insn.insn), mem_insn.reg0, 1) != 1)
@@ -1004,7 +972,7 @@ find_inc (bool first_try)
         find this.  Only try it once though.  */
       if (first_try && !mem_insn.reg1_is_const)
        {
-         reverse_mem ();
+         std::swap (mem_insn.reg0, mem_insn.reg1);
          return find_inc (false);
        }
       else
@@ -1013,9 +981,8 @@ find_inc (bool first_try)
 
   /* Need to assure that none of the operands of the inc instruction are
      assigned to by the mem insn.  */
-  for (def_rec = DF_INSN_DEFS (mem_insn.insn); *def_rec; def_rec++)
+  FOR_EACH_INSN_DEF (def, mem_insn.insn)
     {
-      df_ref def = *def_rec;
       unsigned int regno = DF_REF_REGNO (def);
       if ((regno == REGNO (inc_insn.reg0))
          || (regno == REGNO (inc_insn.reg_res)))
@@ -1039,9 +1006,9 @@ find_inc (bool first_try)
     {
       /* Make sure that there is no insn that assigns to inc_insn.res
         between the mem_insn and the inc_insn.  */
-      rtx other_insn = get_next_ref (REGNO (inc_insn.reg_res),
-                                    BLOCK_FOR_INSN (mem_insn.insn),
-                                    reg_next_def);
+      rtx_insn *other_insn = get_next_ref (REGNO (inc_insn.reg_res),
+                                          BLOCK_FOR_INSN (mem_insn.insn),
+                                          reg_next_def);
       if (other_insn != inc_insn.insn)
        {
          if (dump_file)
@@ -1106,7 +1073,7 @@ find_inc (bool first_try)
                    return false;
 
                  if (!rtx_equal_p (mem_insn.reg0, inc_insn.reg0))
-                   reverse_inc ();
+                   std::swap (inc_insn.reg0, inc_insn.reg1);
                }
 
              other_insn
@@ -1130,7 +1097,7 @@ find_inc (bool first_try)
         then we just abandon this.  */
 
       int luid = DF_INSN_LUID (inc_insn.insn);
-      rtx other_insn;
+      rtx_insn *other_insn;
 
       /* Make sure this reg appears only once in this insn.  */
       if (count_occurrences (PATTERN (mem_insn.insn), mem_insn.reg1, 1) != 1)
@@ -1156,7 +1123,7 @@ find_inc (bool first_try)
                  /* See comment above on find_inc (false) call.  */
                  if (first_try)
                    {
-                     reverse_mem ();
+                     std::swap (mem_insn.reg0, mem_insn.reg1);
                      return find_inc (false);
                    }
                  else
@@ -1175,7 +1142,7 @@ find_inc (bool first_try)
            {
              /* We know that mem_insn.reg0 must equal inc_insn.reg1
                 or else we would not have found the inc insn.  */
-             reverse_mem ();
+             std::swap (mem_insn.reg0, mem_insn.reg1);
              if (!rtx_equal_p (mem_insn.reg0, inc_insn.reg0))
                {
                  /* See comment above on find_inc (false) call.  */
@@ -1214,7 +1181,7 @@ find_inc (bool first_try)
            {
              if (first_try)
                {
-                 reverse_mem ();
+                 std::swap (mem_insn.reg0, mem_insn.reg1);
                  return find_inc (false);
                }
              else
@@ -1333,8 +1300,8 @@ find_mem (rtx *address_of_x)
 static void
 merge_in_block (int max_reg, basic_block bb)
 {
-  rtx insn;
-  rtx curr;
+  rtx_insn *insn;
+  rtx_insn *curr;
   int success_in_block = 0;
 
   if (dump_file)
@@ -1342,7 +1309,6 @@ merge_in_block (int max_reg, basic_block bb)
 
   FOR_BB_INSNS_REVERSE_SAFE (bb, insn, curr)
     {
-      unsigned int uid = INSN_UID (insn);
       bool insn_is_add_or_inc = true;
 
       if (!NONDEBUG_INSN_P (insn))
@@ -1379,7 +1345,7 @@ merge_in_block (int max_reg, basic_block bb)
                         clear of c because the inc insn is going to move
                         into the mem_insn.insn.  */
                      int luid = DF_INSN_LUID (mem_insn.insn);
-                     rtx other_insn
+                     rtx_insn *other_insn
                        = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_use);
 
                      if (other_insn && luid > DF_INSN_LUID (other_insn))
@@ -1418,22 +1384,20 @@ merge_in_block (int max_reg, basic_block bb)
 
       /* If the inc insn was merged with a mem, the inc insn is gone
         and there is noting to update.  */
-      if (DF_INSN_UID_GET (uid))
+      if (df_insn_info *insn_info = DF_INSN_INFO_GET (insn))
        {
-         df_ref *def_rec;
-         df_ref *use_rec;
+         df_ref def, use;
+
          /* Need to update next use.  */
-         for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+         FOR_EACH_INSN_INFO_DEF (def, insn_info)
            {
-             df_ref def = *def_rec;
              reg_next_use[DF_REF_REGNO (def)] = NULL;
              reg_next_inc_use[DF_REF_REGNO (def)] = NULL;
              reg_next_def[DF_REF_REGNO (def)] = insn;
            }
 
-         for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
+         FOR_EACH_INSN_INFO_USE (use, insn_info)
            {
-             df_ref use = *use_rec;
              reg_next_use[DF_REF_REGNO (use)] = insn;
              if (insn_is_add_or_inc)
                reg_next_inc_use[DF_REF_REGNO (use)] = insn;
@@ -1442,7 +1406,8 @@ merge_in_block (int max_reg, basic_block bb)
            }
        }
       else if (dump_file)
-       fprintf (dump_file, "skipping update of deleted insn %d\n", uid);
+       fprintf (dump_file, "skipping update of deleted insn %d\n",
+                INSN_UID (insn));
     }
 
   /* If we were successful, try again.  There may have been several
@@ -1460,52 +1425,8 @@ merge_in_block (int max_reg, basic_block bb)
     }
 }
 
-#endif
-
-static unsigned int
-rest_of_handle_auto_inc_dec (void)
-{
-#ifdef AUTO_INC_DEC
-  basic_block bb;
-  int max_reg = max_reg_num ();
-
-  if (!initialized)
-    init_decision_table ();
-
-  mem_tmp = gen_rtx_MEM (Pmode, NULL_RTX);
-
-  df_note_add_problem ();
-  df_analyze ();
-
-  reg_next_use = XCNEWVEC (rtx, max_reg);
-  reg_next_inc_use = XCNEWVEC (rtx, max_reg);
-  reg_next_def = XCNEWVEC (rtx, max_reg);
-  FOR_EACH_BB_FN (bb, cfun)
-    merge_in_block (max_reg, bb);
-
-  free (reg_next_use);
-  free (reg_next_inc_use);
-  free (reg_next_def);
-
-  mem_tmp = NULL;
-#endif
-  return 0;
-}
-
-
 /* Discover auto-inc auto-dec instructions.  */
 
-static bool
-gate_auto_inc_dec (void)
-{
-#ifdef AUTO_INC_DEC
-  return (optimize > 0 && flag_auto_inc_dec);
-#else
-  return false;
-#endif
-}
-
-
 namespace {
 
 const pass_data pass_data_inc_dec =
@@ -1513,8 +1434,6 @@ const pass_data pass_data_inc_dec =
   RTL_PASS, /* type */
   "auto_inc_dec", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
-  true, /* has_gate */
-  true, /* has_execute */
   TV_AUTO_INC_DEC, /* tv_id */
   0, /* properties_required */
   0, /* properties_provided */
@@ -1531,11 +1450,51 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_auto_inc_dec (); }
-  unsigned int execute () { return rest_of_handle_auto_inc_dec (); }
+  virtual bool gate (function *)
+    {
+      if (!AUTO_INC_DEC)
+       return false;
+
+      return (optimize > 0 && flag_auto_inc_dec);
+    }
+
+
+  unsigned int execute (function *);
 
 }; // class pass_inc_dec
 
+unsigned int
+pass_inc_dec::execute (function *fun ATTRIBUTE_UNUSED)
+{
+  if (!AUTO_INC_DEC)
+    return 0;
+
+  basic_block bb;
+  int max_reg = max_reg_num ();
+
+  if (!initialized)
+    init_decision_table ();
+
+  mem_tmp = gen_rtx_MEM (Pmode, NULL_RTX);
+
+  df_note_add_problem ();
+  df_analyze ();
+
+  reg_next_use = XCNEWVEC (rtx_insn *, max_reg);
+  reg_next_inc_use = XCNEWVEC (rtx_insn *, max_reg);
+  reg_next_def = XCNEWVEC (rtx_insn *, max_reg);
+  FOR_EACH_BB_FN (bb, fun)
+    merge_in_block (max_reg, bb);
+
+  free (reg_next_use);
+  free (reg_next_inc_use);
+  free (reg_next_def);
+
+  mem_tmp = NULL;
+
+  return 0;
+}
+
 } // anon namespace
 
 rtl_opt_pass *