Merge from trunk.
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Apr 2014 13:19:46 +0000 (13:19 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Apr 2014 13:19:46 +0000 (13:19 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@209485 138bc75d-0d04-0410-961f-82ee72b054a4

70 files changed:
1  2 
gcc/Makefile.in
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/utils.c
gcc/alias.c
gcc/c-family/c-common.c
gcc/c-family/c-format.c
gcc/c-family/cilk.c
gcc/cfgloop.h
gcc/cgraph.c
gcc/config/arc/arc.c
gcc/config/arm/arm.c
gcc/config/avr/avr.c
gcc/config/i386/i386.c
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/mangle.c
gcc/cp/tree.c
gcc/cse.c
gcc/dbxout.c
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/dwarf2out.c
gcc/explow.c
gcc/expmed.c
gcc/expr.c
gcc/final.c
gcc/fold-const.c
gcc/fortran/trans-array.c
gcc/fortran/trans-expr.c
gcc/fortran/trans-types.c
gcc/gimple-ssa-strength-reduction.c
gcc/gimple.c
gcc/go/go-gcc.cc
gcc/godump.c
gcc/graphite-sese-to-poly.c
gcc/ipa-devirt.c
gcc/lto-streamer-in.c
gcc/lto-streamer-out.c
gcc/lto/lto.c
gcc/omp-low.c
gcc/real.c
gcc/simplify-rtx.c
gcc/stor-layout.c
gcc/tree-cfg.c
gcc/tree-core.h
gcc/tree-inline.c
gcc/tree-pretty-print.c
gcc/tree-ssa-alias.c
gcc/tree-ssa-forwprop.c
gcc/tree-ssa-loop-ivcanon.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree-ssa-math-opts.c
gcc/tree-ssa-phiopt.c
gcc/tree-ssa-pre.c
gcc/tree-ssa-reassoc.c
gcc/tree-ssa-structalias.c
gcc/tree-ssa-uninit.c
gcc/tree-ssanames.c
gcc/tree-streamer-out.c
gcc/tree-switch-conversion.c
gcc/tree-vect-data-refs.c
gcc/tree-vect-loop.c
gcc/tree-vect-stmts.c
gcc/tree.c
gcc/tree.def
gcc/tree.h
gcc/varasm.c

diff --cc gcc/Makefile.in
Simple merge
Simple merge
Simple merge
diff --cc gcc/alias.c
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc gcc/cfgloop.h
Simple merge
diff --cc gcc/cgraph.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc gcc/cp/call.c
Simple merge
diff --cc gcc/cp/class.c
Simple merge
diff --cc gcc/cp/decl.c
Simple merge
diff --cc gcc/cp/mangle.c
Simple merge
diff --cc gcc/cp/tree.c
Simple merge
diff --cc gcc/cse.c
Simple merge
diff --cc gcc/dbxout.c
Simple merge
diff --cc gcc/doc/tm.texi
Simple merge
Simple merge
diff --cc gcc/dwarf2out.c
@@@ -16372,21 -16203,33 +16377,32 @@@ add_bound_info (dw_die_ref subrange_die
            && tree_to_shwi (bound) == dflt)
          ;
  
-       /* Otherwise represent the bound as an unsigned value with the
-          precision of its type.  The precision and signedness of the
-          type will be necessary to re-interpret it unambiguously.  */
-       else if (prec < HOST_BITS_PER_WIDE_INT)
+       /* If HOST_WIDE_INT is big enough then represent the bound as
+          a constant value.  We need to choose a form based on
+          whether the type is signed or unsigned.  We cannot just
+          call add_AT_unsigned if the value itself is positive
+          (add_AT_unsigned might add the unsigned value encoded as
+          DW_FORM_data[1248]).  Some DWARF consumers will lookup the
+          bounds type and then sign extend any unsigned values found
+          for signed types.  This is needed only for
+          DW_AT_{lower,upper}_bound, since for most other attributes,
+          consumers will treat DW_FORM_data[1248] as unsigned values,
+          regardless of the underlying type.  */
+       else if (prec <= HOST_BITS_PER_WIDE_INT
 -               || TREE_INT_CST_HIGH (bound) == 0)
++               || tree_fits_uhwi_p (bound))
          {
-           unsigned HOST_WIDE_INT mask
-             = ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
-           add_AT_unsigned (subrange_die, bound_attr,
-                            TREE_INT_CST_LOW (bound) & mask);
+           if (TYPE_UNSIGNED (TREE_TYPE (bound)))
+             add_AT_unsigned (subrange_die, bound_attr,
+                              TREE_INT_CST_LOW (bound));
+           else
+             add_AT_int (subrange_die, bound_attr, TREE_INT_CST_LOW (bound));
          }
-       else if (prec == HOST_BITS_PER_WIDE_INT || tree_fits_uhwi_p (bound))
-         add_AT_unsigned (subrange_die, bound_attr,
-                          TREE_INT_CST_LOW (bound));
        else
 -        add_AT_double (subrange_die, bound_attr, TREE_INT_CST_HIGH (bound),
 -                       TREE_INT_CST_LOW (bound));
+         /* Otherwise represent the bound as an unsigned value with
+            the precision of its type.  The precision and signedness
+            of the type will be necessary to re-interpret it
+            unambiguously.  */
 +        add_AT_wide (subrange_die, bound_attr, bound);
        }
        break;
  
@@@ -17528,23 -17371,25 +17544,24 @@@ gen_enumeration_type_die (tree type, dw
  
          if (simple_type_size_in_bits (TREE_TYPE (value))
              <= HOST_BITS_PER_WIDE_INT || tree_fits_shwi_p (value))
-           /* DWARF2 does not provide a way of indicating whether or
-              not enumeration constants are signed or unsigned.  GDB
-              always assumes the values are signed, so we output all
-              values as if they were signed.  That means that
-              enumeration constants with very large unsigned values
-              will appear to have negative values in the debugger.
-              TODO: the above comment is wrong, DWARF2 does provide
-              DW_FORM_sdata/DW_FORM_udata to represent signed/unsigned data.
-              This should be re-worked to use correct signed/unsigned
-              int/double tags for all cases, instead of always treating as
-              signed.  */
-           add_AT_int (enum_die, DW_AT_const_value, TREE_INT_CST_LOW (value));
+           {
+             /* For constant forms created by add_AT_unsigned DWARF
+                consumers (GDB, elfutils, etc.) always zero extend
+                the value.  Only when the actual value is negative
+                do we need to use add_AT_int to generate a constant
+                form that can represent negative values.  */
+             HOST_WIDE_INT val = TREE_INT_CST_LOW (value);
+             if (TYPE_UNSIGNED (TREE_TYPE (value)) || val >= 0)
+               add_AT_unsigned (enum_die, DW_AT_const_value,
+                                (unsigned HOST_WIDE_INT) val);
+             else
+               add_AT_int (enum_die, DW_AT_const_value, val);
+           }
          else
            /* Enumeration constants may be wider than HOST_WIDE_INT.  Handle
-              that here.  */
+              that here.  TODO: This should be re-worked to use correct
+              signed/unsigned double tags for all cases.  */
 -          add_AT_double (enum_die, DW_AT_const_value,
 -                         TREE_INT_CST_HIGH (value), TREE_INT_CST_LOW (value));
 +          add_AT_wide (enum_die, DW_AT_const_value, value);
        }
  
        add_gnat_descriptive_type_attribute (type_die, type, context_die);
diff --cc gcc/explow.c
Simple merge
diff --cc gcc/expmed.c
@@@ -4966,16 -5013,24 +4966,16 @@@ make_tree (tree type, rtx x
    switch (GET_CODE (x))
      {
      case CONST_INT:
 -      {
 -      HOST_WIDE_INT hi = 0;
 -
 -      if (INTVAL (x) < 0
 -          && !(TYPE_UNSIGNED (type)
 -               && (GET_MODE_BITSIZE (TYPE_MODE (type))
 -                   < HOST_BITS_PER_WIDE_INT)))
 -        hi = -1;
 -
 -      t = build_int_cst_wide (type, INTVAL (x), hi);
 -
 -      return t;
 -      }
 +    case CONST_WIDE_INT:
 +      t = wide_int_to_tree (type, std::make_pair (x, TYPE_MODE (type)));
 +      return t;
  
      case CONST_DOUBLE:
-       STATIC_ASSERT (HOST_BITS_PER_WIDE_INT * 2 <= MAX_BITSIZE_MODE_ANY_INT);
 -      if (GET_MODE (x) == VOIDmode)
 -      t = build_int_cst_wide (type,
 -                              CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x));
++      gcc_assert (HOST_BITS_PER_WIDE_INT * 2 <= MAX_BITSIZE_MODE_ANY_INT);
 +      if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (x) == VOIDmode)
 +      t = wide_int_to_tree (type,
 +                            wide_int::from_array (&CONST_DOUBLE_LOW (x), 2,
 +                                                  HOST_BITS_PER_WIDE_INT * 2));
        else
        {
          REAL_VALUE_TYPE d;
diff --cc gcc/expr.c
Simple merge
diff --cc gcc/final.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -2991,11 -3000,11 +2991,11 @@@ ncd_with_phi (slsr_cand_t c, const wide
          else 
            {
              slsr_cand_t arg_cand = base_cand_from_table (arg);
 -            double_int diff = arg_cand->index - basis->index;
 +            widest_int diff = arg_cand->index - basis->index;
+             basic_block pred = gimple_phi_arg_edge (phi, i)->src;
  
              if ((incr == diff) || (!address_arithmetic_p && incr == -diff))
-               ncd = ncd_for_two_cands (ncd, gimple_bb (arg_cand->cand_stmt),
-                                        *where, arg_cand, where);
+               ncd = ncd_for_two_cands (ncd, pred, *where, NULL, where);
            }
        }
      }
diff --cc gcc/gimple.c
Simple merge
Simple merge
diff --cc gcc/godump.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc gcc/lto/lto.c
Simple merge
diff --cc gcc/omp-low.c
Simple merge
diff --cc gcc/real.c
@@@ -1412,47 -1415,35 +1412,47 @@@ real_to_integer (const REAL_VALUE_TYPE 
         undefined, so it doesn't matter what we return, and some callers
         expect to be able to use this routine for both signed and
         unsigned conversions.  */
 -      if (exp > HOST_BITS_PER_DOUBLE_INT)
 +      if (exp > precision)
        goto overflow;
  
 -      rshift_significand (&t, r, HOST_BITS_PER_DOUBLE_INT - exp);
 -      if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
 +      words = (precision + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT;
 +
 +      for (unsigned int i = 0; i < ARRAY_SIZE (val); i++)
 +      val[i] = 0;
 +
 +#if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
 +      for (int i = 0; i < words; i++)
        {
 -        high = t.sig[SIGSZ-1];
 -        low = t.sig[SIGSZ-2];
 +        int j = SIGSZ - words + i;
 +        val[i] = (j < 0) ? 0 : r->sig[j];
        }
 -      else
 +#else
 +      gcc_assert (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG);
 +      for (int i = 0; i < words; i++)
        {
 -        gcc_assert (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG);
 -        high = t.sig[SIGSZ-1];
 -        high = high << (HOST_BITS_PER_LONG - 1) << 1;
 -        high |= t.sig[SIGSZ-2];
 -
 -        low = t.sig[SIGSZ-3];
 -        low = low << (HOST_BITS_PER_LONG - 1) << 1;
 -        low |= t.sig[SIGSZ-4];
 +        int j = SIGSZ - (words * 2) + (i + 2) + 1;
 +        if (j < 0)
 +          val[i] = 0;
 +        else
 +          {
 +            val[i] = r->sig[j];
 +            unsigned HOST_WIDE_INT v = val[i];
 +            v <<= HOST_BITS_PER_LONG;
 +            val[i] = v;
 +            val[i] |= r->sig[j - 1];
 +          }
        }
-       tmp = wi::lrshift (tmp, (words * HOST_BITS_PER_WIDE_INT) - exp);
 +#endif
 +      w = SIGSZ * HOST_BITS_PER_LONG + words * HOST_BITS_PER_WIDE_INT;
 +      tmp = real_int::from_array
 +      (val, (w + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT, w);
++      tmp = wi::lrshift<real_int> (tmp, (words * HOST_BITS_PER_WIDE_INT) - exp);
 +      result = wide_int::from (tmp, precision, UNSIGNED);
  
        if (r->sign)
 -      {
 -        if (low == 0)
 -          high = -high;
 -        else
 -          low = -low, high = ~high;
 -      }
 -      break;
 +      return -result;
 +      else
 +      return result;
  
      default:
        gcc_unreachable ();
@@@ -5365,30 -5807,24 +5365,29 @@@ simplify_immed_subreg (enum machine_mod
        case MODE_INT:
        case MODE_PARTIAL_INT:
          {
 -          unsigned HOST_WIDE_INT hi = 0, lo = 0;
 -
 -          for (i = 0;
 -               i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
 -               i += value_bit)
 -            lo |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
 -          for (; i < elem_bitsize; i += value_bit)
 -            hi |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask)
 -                   << (i - HOST_BITS_PER_WIDE_INT);
 -
 -          /* immed_double_const doesn't call trunc_int_for_mode.  I don't
 -             know why.  */
 -          if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
 -            elems[elem] = gen_int_mode (lo, outer_submode);
 -          else if (elem_bitsize <= HOST_BITS_PER_DOUBLE_INT)
 -            elems[elem] = immed_double_const (lo, hi, outer_submode);
 -          else
 -            return NULL_RTX;
 +          int u;
 +          int base = 0;
 +          int units
 +            = (GET_MODE_BITSIZE (outer_submode) + HOST_BITS_PER_WIDE_INT - 1)
 +            / HOST_BITS_PER_WIDE_INT;
 +          HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT];
 +          wide_int r;
 +
 +          for (u = 0; u < units; u++)
 +            {
 +              unsigned HOST_WIDE_INT buf = 0;
 +              for (i = 0;
 +                   i < HOST_BITS_PER_WIDE_INT && base + i < elem_bitsize;
 +                   i += value_bit)
 +                buf |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
 +
 +              tmp[u] = buf;
 +              base += HOST_BITS_PER_WIDE_INT;
 +            }
-           gcc_assert (GET_MODE_PRECISION (outer_submode)
-                       <= MAX_BITSIZE_MODE_ANY_INT);
++          gcc_assert (GET_MODE_PRECISION (outer_submode) <= MAX_BITSIZE_MODE_ANY_INT);
 +          r = wide_int::from_array (tmp, units,
 +                                    GET_MODE_PRECISION (outer_submode));
 +          elems[elem] = immed_wide_int_const (r, outer_submode);
          }
          break;
  
        case MODE_DECIMAL_FLOAT:
          {
            REAL_VALUE_TYPE r;
-           long tmp[MAX_BITSIZE_MODE_ANY_MODE / 32];
 -          long tmp[max_bitsize / 32];
++          long tmp[MAX_BITSIZE_MODE_ANY_INT / 32];
  
            /* real_from_target wants its input in words affected by
               FLOAT_WORDS_BIG_ENDIAN.  However, we ignore this,
Simple merge
diff --cc gcc/tree-cfg.c
Simple merge
diff --cc gcc/tree-core.h
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc gcc/tree.c
Simple merge
diff --cc gcc/tree.def
Simple merge
diff --cc gcc/tree.h
Simple merge
diff --cc gcc/varasm.c
Simple merge