OSDN Git Service

* dwarf2out.c (add_var_loc_to_decl): Add LABEL argument. Drop
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Apr 2010 07:05:00 +0000 (07:05 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 05:34:37 +0000 (14:34 +0900)
last chain entry if it starts with the still current label.
(add_location_or_const_value_attribute): Check that
loc_list->first->next is NULL instead of comparing ->first with
->last.
(dwarf2out_var_location): Pass last_label resp. last_postcall_label
to add_var_loc_to_decl.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158590 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dwarf2out.c

index 94612c2..9a6a1b3 100644 (file)
@@ -1,5 +1,13 @@
 2010-04-21  Jakub Jelinek  <jakub@redhat.com>
 
+       * dwarf2out.c (add_var_loc_to_decl): Add LABEL argument.  Drop
+       last chain entry if it starts with the still current label.
+       (add_location_or_const_value_attribute): Check that
+       loc_list->first->next is NULL instead of comparing ->first with
+       ->last.
+       (dwarf2out_var_location): Pass last_label resp. last_postcall_label
+       to add_var_loc_to_decl.
+
        * dwarf2out.c (output_call_frame_info): For dw_cie_version
        >= 4 add also address size and segment size fields into CIE
        header.
index ed5257d..8d56938 100644 (file)
@@ -79,6 +79,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dwarf2out.h"
 #include "dwarf2asm.h"
 #include "toplev.h"
+#include "varray.h"
 #include "ggc.h"
 #include "md5.h"
 #include "tm_p.h"
@@ -91,7 +92,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "input.h"
 #include "gimple.h"
 #include "tree-pass.h"
-#include "tree-flow.h"
 
 #ifdef DWARF2_DEBUGGING_INFO
 static void dwarf2out_source_line (unsigned int, const char *, int, bool);
@@ -1040,7 +1040,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p)
 
   cfi = new_cfi ();
 
-  if (loc.reg == old_cfa.reg && !loc.indirect && !old_cfa.indirect)
+  if (loc.reg == old_cfa.reg && !loc.indirect)
     {
       /* Construct a "DW_CFA_def_cfa_offset <offset>" instruction, indicating
         the CFA register did not change but the offset did.  The data
@@ -1056,8 +1056,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p)
 #ifndef MIPS_DEBUGGING_INFO  /* SGI dbx thinks this means no offset.  */
   else if (loc.offset == old_cfa.offset
           && old_cfa.reg != INVALID_REGNUM
-          && !loc.indirect
-          && !old_cfa.indirect)
+          && !loc.indirect)
     {
       /* Construct a "DW_CFA_def_cfa_register <register>" instruction,
         indicating the CFA register has changed to <register> but the
@@ -4785,10 +4784,6 @@ size_of_loc_descr (dw_loc_descr_ref loc)
     case DW_OP_piece:
       size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
       break;
-    case DW_OP_bit_piece:
-      size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
-      size += size_of_uleb128 (loc->dw_loc_oprnd2.v.val_unsigned);
-      break;
     case DW_OP_deref_size:
     case DW_OP_xderef_size:
       size += 1;
@@ -5013,10 +5008,6 @@ output_loc_operands (dw_loc_descr_ref loc)
     case DW_OP_piece:
       dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
       break;
-    case DW_OP_bit_piece:
-      dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
-      dw2_asm_output_data_uleb128 (val2->v.val_unsigned, NULL);
-      break;
     case DW_OP_deref_size:
     case DW_OP_xderef_size:
       dw2_asm_output_data (1, val1->v.val_int, NULL);
@@ -5132,12 +5123,6 @@ output_loc_operands_raw (dw_loc_descr_ref loc)
       dw2_asm_output_data_uleb128_raw (val1->v.val_unsigned);
       break;
 
-    case DW_OP_bit_piece:
-      fputc (',', asm_out_file);
-      dw2_asm_output_data_uleb128_raw (val1->v.val_unsigned);
-      dw2_asm_output_data_uleb128_raw (val2->v.val_unsigned);
-      break;
-
     case DW_OP_consts:
     case DW_OP_breg0:
     case DW_OP_breg1:
@@ -5754,15 +5739,7 @@ DEF_VEC_ALLOC_O(die_arg_entry,gc);
 
 /* Node of the variable location list.  */
 struct GTY ((chain_next ("%h.next"))) var_loc_node {
-  /* Either NOTE_INSN_VAR_LOCATION, or, for SRA optimized variables,
-     EXPR_LIST chain.  For small bitsizes, bitsize is encoded
-     in mode of the EXPR_LIST node and first EXPR_LIST operand
-     is either NOTE_INSN_VAR_LOCATION for a piece with a known
-     location or NULL for padding.  For larger bitsizes,
-     mode is 0 and first operand is a CONCAT with bitsize
-     as first CONCAT operand and NOTE_INSN_VAR_LOCATION resp.
-     NULL as second operand.  */
-  rtx GTY (()) loc;
+  rtx GTY (()) var_loc_note;
   const char * GTY (()) label;
   struct var_loc_node * GTY (()) next;
 };
@@ -6139,7 +6116,6 @@ static void add_AT_location_description   (dw_die_ref, enum dwarf_attribute,
 static void add_data_member_location_attribute (dw_die_ref, tree);
 static bool add_const_value_attribute (dw_die_ref, rtx);
 static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
-static void insert_double (double_int, unsigned char *);
 static void insert_float (const_rtx, unsigned char *);
 static rtx rtl_for_decl_location (tree);
 static bool add_location_or_const_value_attribute (dw_die_ref, tree,
@@ -7780,175 +7756,16 @@ equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
   decl_die->decl_id = decl_id;
 }
 
-/* Return how many bits covers PIECE EXPR_LIST.  */
-
-static int
-decl_piece_bitsize (rtx piece)
-{
-  int ret = (int) GET_MODE (piece);
-  if (ret)
-    return ret;
-  gcc_assert (GET_CODE (XEXP (piece, 0)) == CONCAT
-             && CONST_INT_P (XEXP (XEXP (piece, 0), 0)));
-  return INTVAL (XEXP (XEXP (piece, 0), 0));
-}
-
-/* Return pointer to the location of location note in PIECE EXPR_LIST.  */
-
-static rtx *
-decl_piece_varloc_ptr (rtx piece)
-{
-  if ((int) GET_MODE (piece))
-    return &XEXP (piece, 0);
-  else
-    return &XEXP (XEXP (piece, 0), 1);
-}
-
-/* Create an EXPR_LIST for location note LOC_NOTE covering BITSIZE bits.
-   Next is the chain of following piece nodes.  */
-
-static rtx
-decl_piece_node (rtx loc_note, HOST_WIDE_INT bitsize, rtx next)
-{
-  if (bitsize <= (int) MAX_MACHINE_MODE)
-    return alloc_EXPR_LIST (bitsize, loc_note, next);
-  else
-    return alloc_EXPR_LIST (0, gen_rtx_CONCAT (VOIDmode,
-                                              GEN_INT (bitsize),
-                                              loc_note), next);
-}
-
-/* Return rtx that should be stored into loc field for
-   LOC_NOTE and BITPOS/BITSIZE.  */
-
-static rtx
-construct_piece_list (rtx loc_note, HOST_WIDE_INT bitpos,
-                     HOST_WIDE_INT bitsize)
-{
-  if (bitsize != -1)
-    {
-      loc_note = decl_piece_node (loc_note, bitsize, NULL_RTX);
-      if (bitpos != 0)
-       loc_note = decl_piece_node (NULL_RTX, bitpos, loc_note);
-    }
-  return loc_note;
-}
-
-/* This function either modifies location piece list *DEST in
-   place (if SRC and INNER is NULL), or copies location piece list
-   *SRC to *DEST while modifying it.  Location BITPOS is modified
-   to contain LOC_NOTE, any pieces overlapping it are removed resp.
-   not copied and if needed some padding around it is added.
-   When modifying in place, DEST should point to EXPR_LIST where
-   earlier pieces cover PIECE_BITPOS bits, when copying SRC points
-   to the start of the whole list and INNER points to the EXPR_LIST
-   where earlier pieces cover PIECE_BITPOS bits.  */
-
-static void
-adjust_piece_list (rtx *dest, rtx *src, rtx *inner,
-                  HOST_WIDE_INT bitpos, HOST_WIDE_INT piece_bitpos,
-                  HOST_WIDE_INT bitsize, rtx loc_note)
-{
-  int diff;
-  bool copy = inner != NULL;
-
-  if (copy)
-    {
-      /* First copy all nodes preceeding the current bitpos.  */
-      while (src != inner)
-       {
-         *dest = decl_piece_node (*decl_piece_varloc_ptr (*src),
-                                  decl_piece_bitsize (*src), NULL_RTX);
-         dest = &XEXP (*dest, 1);
-         src = &XEXP (*src, 1);
-       }
-    }
-  /* Add padding if needed.  */
-  if (bitpos != piece_bitpos)
-    {
-      *dest = decl_piece_node (NULL_RTX, bitpos - piece_bitpos,
-                              copy ? NULL_RTX : *dest);
-      dest = &XEXP (*dest, 1);
-    }
-  else if (*dest && decl_piece_bitsize (*dest) == bitsize)
-    {
-      gcc_assert (!copy);
-      /* A piece with correct bitpos and bitsize already exist,
-        just update the location for it and return.  */
-      *decl_piece_varloc_ptr (*dest) = loc_note;
-      return;
-    }
-  /* Add the piece that changed.  */
-  *dest = decl_piece_node (loc_note, bitsize, copy ? NULL_RTX : *dest);
-  dest = &XEXP (*dest, 1);
-  /* Skip over pieces that overlap it.  */
-  diff = bitpos - piece_bitpos + bitsize;
-  if (!copy)
-    src = dest;
-  while (diff > 0 && *src)
-    {
-      rtx piece = *src;
-      diff -= decl_piece_bitsize (piece);
-      if (copy)
-       src = &XEXP (piece, 1);
-      else
-       {
-         *src = XEXP (piece, 1);
-         free_EXPR_LIST_node (piece);
-       }
-    }
-  /* Add padding if needed.  */
-  if (diff < 0 && *src)
-    {
-      if (!copy)
-       dest = src;
-      *dest = decl_piece_node (NULL_RTX, -diff, copy ? NULL_RTX : *dest);
-      dest = &XEXP (*dest, 1);
-    }
-  if (!copy)
-    return;
-  /* Finally copy all nodes following it.  */
-  while (*src)
-    {
-      *dest = decl_piece_node (*decl_piece_varloc_ptr (*src),
-                              decl_piece_bitsize (*src), NULL_RTX);
-      dest = &XEXP (*dest, 1);
-      src = &XEXP (*src, 1);
-    }
-}
-
 /* Add a variable location node to the linked list for DECL.  */
 
 static struct var_loc_node *
 add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
 {
-  unsigned int decl_id;
+  unsigned int decl_id = DECL_UID (decl);
   var_loc_list *temp;
   void **slot;
   struct var_loc_node *loc = NULL;
-  HOST_WIDE_INT bitsize = -1, bitpos = -1;
-
-  if (DECL_DEBUG_EXPR_IS_FROM (decl))
-    {
-      tree realdecl = DECL_DEBUG_EXPR (decl);
-      if (realdecl && handled_component_p (realdecl))
-       {
-         HOST_WIDE_INT maxsize;
-         tree innerdecl;
-         innerdecl
-           = get_ref_base_and_extent (realdecl, &bitpos, &bitsize, &maxsize);
-         if (!DECL_P (innerdecl)
-             || DECL_IGNORED_P (innerdecl)
-             || TREE_STATIC (innerdecl)
-             || bitsize <= 0
-             || bitpos + bitsize > 256
-             || bitsize != maxsize)
-           return NULL;
-         decl = innerdecl;
-       }
-    }
 
-  decl_id = DECL_UID (decl);
   slot = htab_find_slot_with_hash (decl_loc_table, decl, decl_id, INSERT);
   if (*slot == NULL)
     {
@@ -7962,40 +7779,17 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
   if (temp->last)
     {
       struct var_loc_node *last = temp->last, *unused = NULL;
-      rtx *piece_loc = NULL, last_loc_note;
-      int piece_bitpos = 0;
       if (last->next)
        {
          last = last->next;
          gcc_assert (last->next == NULL);
        }
-      if (bitsize != -1 && GET_CODE (last->loc) == EXPR_LIST)
-       {
-         piece_loc = &last->loc;
-         do
-           {
-             int cur_bitsize = decl_piece_bitsize (*piece_loc);
-             if (piece_bitpos + cur_bitsize > bitpos)
-               break;
-             piece_bitpos += cur_bitsize;
-             piece_loc = &XEXP (*piece_loc, 1);
-           }
-         while (*piece_loc);
-       }
       /* TEMP->LAST here is either pointer to the last but one or
         last element in the chained list, LAST is pointer to the
         last element.  */
+      /* If the last note doesn't cover any instructions, remove it.  */
       if (label && strcmp (last->label, label) == 0)
        {
-         /* For SRA optimized variables if there weren't any real
-            insns since last note, just modify the last node.  */
-         if (piece_loc != NULL)
-           {
-             adjust_piece_list (piece_loc, NULL, NULL,
-                                bitpos, piece_bitpos, bitsize, loc_note);
-             return NULL;
-           }
-         /* If the last note doesn't cover any instructions, remove it.  */
          if (temp->last != last)
            {
              temp->last->next = NULL;
@@ -8007,28 +7801,17 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
            {
              gcc_assert (temp->first == temp->last);
              memset (temp->last, '\0', sizeof (*temp->last));
-             temp->last->loc = construct_piece_list (loc_note, bitpos, bitsize);
              return temp->last;
            }
        }
-      if (bitsize == -1 && NOTE_P (last->loc))
-       last_loc_note = last->loc;
-      else if (piece_loc != NULL
-              && *piece_loc != NULL_RTX
-              && piece_bitpos == bitpos
-              && decl_piece_bitsize (*piece_loc) == bitsize)
-       last_loc_note = *decl_piece_varloc_ptr (*piece_loc);
-      else
-       last_loc_note = NULL_RTX;
       /* If the current location is the same as the end of the list,
         and either both or neither of the locations is uninitialized,
         we have nothing to do.  */
-      if (last_loc_note == NULL_RTX
-         || (!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last_loc_note),
-                           NOTE_VAR_LOCATION_LOC (loc_note)))
-         || ((NOTE_VAR_LOCATION_STATUS (last_loc_note)
+      if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last->var_loc_note),
+                        NOTE_VAR_LOCATION_LOC (loc_note)))
+         || ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note)
               != NOTE_VAR_LOCATION_STATUS (loc_note))
-             && ((NOTE_VAR_LOCATION_STATUS (last_loc_note)
+             && ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note)
                   == VAR_INIT_STATUS_UNINITIALIZED)
                  || (NOTE_VAR_LOCATION_STATUS (loc_note)
                      == VAR_INIT_STATUS_UNINITIALIZED))))
@@ -8043,11 +7826,6 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
            }
          else
            loc = GGC_CNEW (struct var_loc_node);
-         if (bitsize == -1 || piece_loc == NULL)
-           loc->loc = construct_piece_list (loc_note, bitpos, bitsize);
-         else
-           adjust_piece_list (&loc->loc, &last->loc, piece_loc,
-                              bitpos, piece_bitpos, bitsize, loc_note);
          last->next = loc;
          /* Ensure TEMP->LAST will point either to the new last but one
             element of the chain, or to the last element in it.  */
@@ -8062,7 +7840,6 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
       loc = GGC_CNEW (struct var_loc_node);
       temp->first = loc;
       temp->last = loc;
-      loc->loc = construct_piece_list (loc_note, bitpos, bitsize);
     }
   return loc;
 }
@@ -12295,6 +12072,10 @@ base_type_die (tree type)
 
   base_type_result = new_die (DW_TAG_base_type, comp_unit_die, type);
 
+  /* This probably indicates a bug.  */
+  if (! TYPE_NAME (type))
+    add_name_attribute (base_type_result, "__unknown__");
+
   add_AT_unsigned (base_type_result, DW_AT_byte_size,
                   int_size_in_bytes (type));
   add_AT_unsigned (base_type_result, DW_AT_encoding, encoding);
@@ -12412,21 +12193,6 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
                          ((is_const_type ? TYPE_QUAL_CONST : 0)
                           | (is_volatile_type ? TYPE_QUAL_VOLATILE : 0)));
 
-  if (qualified_type == sizetype
-      && TYPE_NAME (qualified_type)
-      && TREE_CODE (TYPE_NAME (qualified_type)) == TYPE_DECL)
-    {
-#ifdef ENABLE_CHECKING
-      gcc_assert (TREE_CODE (TREE_TYPE (TYPE_NAME (qualified_type)))
-                 == INTEGER_TYPE
-                 && TYPE_PRECISION (TREE_TYPE (TYPE_NAME (qualified_type)))
-                    == TYPE_PRECISION (qualified_type)
-                 && TYPE_UNSIGNED (TREE_TYPE (TYPE_NAME (qualified_type)))
-                    == TYPE_UNSIGNED (qualified_type));
-#endif
-      qualified_type = TREE_TYPE (TYPE_NAME (qualified_type));
-    }
-
   /* If we do, then we can just use its DIE, if it exists.  */
   if (qualified_type)
     {
@@ -12543,9 +12309,6 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
        name = DECL_NAME (name);
       add_name_attribute (mod_type_die, IDENTIFIER_POINTER (name));
     }
-  /* This probably indicates a bug.  */
-  else if (mod_type_die && mod_type_die->die_tag == DW_TAG_base_type)
-    add_name_attribute (mod_type_die, "__unknown__");
 
   if (qualified_type)
     equate_type_number_to_die (qualified_type, mod_type_die);
@@ -14124,8 +13887,10 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
          else
            {
              loc_result->dw_loc_oprnd2.val_class = dw_val_class_const_double;
-             loc_result->dw_loc_oprnd2.v.val_double
-               = rtx_to_double_int (rtl);
+             loc_result->dw_loc_oprnd2.v.val_double.high
+               = CONST_DOUBLE_HIGH (rtl);
+             loc_result->dw_loc_oprnd2.v.val_double.low
+               = CONST_DOUBLE_LOW (rtl);
            }
        }
       break;
@@ -14149,14 +13914,39 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
              for (i = 0, p = array; i < length; i++, p += elt_size)
                {
                  rtx elt = CONST_VECTOR_ELT (rtl, i);
-                 double_int val = rtx_to_double_int (elt);
+                 HOST_WIDE_INT lo, hi;
+
+                 switch (GET_CODE (elt))
+                   {
+                   case CONST_INT:
+                     lo = INTVAL (elt);
+                     hi = -(lo < 0);
+                     break;
+
+                   case CONST_DOUBLE:
+                     lo = CONST_DOUBLE_LOW (elt);
+                     hi = CONST_DOUBLE_HIGH (elt);
+                     break;
+
+                   default:
+                     gcc_unreachable ();
+                   }
 
                  if (elt_size <= sizeof (HOST_WIDE_INT))
-                   insert_int (double_int_to_shwi (val), elt_size, p);
+                   insert_int (lo, elt_size, p);
                  else
                    {
+                     unsigned char *p0 = p;
+                     unsigned char *p1 = p + sizeof (HOST_WIDE_INT);
+
                      gcc_assert (elt_size == 2 * sizeof (HOST_WIDE_INT));
-                     insert_double (val, p);
+                     if (WORDS_BIG_ENDIAN)
+                       {
+                         p0 = p1;
+                         p1 = p;
+                       }
+                     insert_int (lo, sizeof (HOST_WIDE_INT), p0);
+                     insert_int (hi, sizeof (HOST_WIDE_INT), p1);
                    }
                }
              break;
@@ -14306,11 +14096,7 @@ dw_loc_list_1 (tree loc, rtx varloc, int want_address,
     }
   else
     {
-      if (GET_CODE (varloc) == VAR_LOCATION)
-       mode = DECL_MODE (PAT_VAR_LOCATION_DECL (varloc));
-      else
-       mode = DECL_MODE (loc);
-      descr = loc_descriptor (varloc, mode, initialized);
+      descr = loc_descriptor (varloc, DECL_MODE (loc), initialized);
       have_address = 1;
     }
 
@@ -14360,125 +14146,6 @@ dw_loc_list_1 (tree loc, rtx varloc, int want_address,
   return descr;
 }
 
-/* Create a DW_OP_piece or DW_OP_bit_piece for bitsize, or return NULL
-   if it is not possible.  */
-
-static dw_loc_descr_ref
-new_loc_descr_op_bit_piece (HOST_WIDE_INT bitsize)
-{
-  if ((bitsize % BITS_PER_UNIT) == 0)
-    return new_loc_descr (DW_OP_piece, bitsize / BITS_PER_UNIT, 0);
-  else if (dwarf_version >= 3 || !dwarf_strict)
-    return new_loc_descr (DW_OP_bit_piece, bitsize, 0);
-  else
-    return NULL;
-}
-
-/* Helper function for dw_loc_list.  Compute proper Dwarf location descriptor
-   for VAR_LOC_NOTE for variable DECL that has been optimized by SRA.  */
-
-static dw_loc_descr_ref
-dw_sra_loc_expr (tree decl, rtx loc)
-{
-  rtx p;
-  unsigned int padsize = 0;
-  dw_loc_descr_ref descr, *descr_tail;
-  unsigned HOST_WIDE_INT decl_size;
-  rtx varloc;
-  enum var_init_status initialized;
-
-  if (DECL_SIZE (decl) == NULL
-      || !host_integerp (DECL_SIZE (decl), 1))
-    return NULL;
-
-  decl_size = tree_low_cst (DECL_SIZE (decl), 1);
-  descr = NULL;
-  descr_tail = &descr;
-
-  for (p = loc; p; p = XEXP (p, 1))
-    {
-      unsigned int bitsize = decl_piece_bitsize (p);
-      rtx loc_note = *decl_piece_varloc_ptr (p);
-      dw_loc_descr_ref cur_descr;
-      dw_loc_descr_ref *tail, last = NULL;
-      unsigned int opsize = 0;
-
-      if (loc_note == NULL_RTX
-         || NOTE_VAR_LOCATION_LOC (loc_note) == NULL_RTX)
-       {
-         padsize += bitsize;
-         continue;
-       }
-      initialized = NOTE_VAR_LOCATION_STATUS (loc_note);
-      varloc = NOTE_VAR_LOCATION (loc_note);
-      cur_descr = dw_loc_list_1 (decl, varloc, 2, initialized);
-      if (cur_descr == NULL)
-       {
-         padsize += bitsize;
-         continue;
-       }
-
-      /* Check that cur_descr either doesn't use
-        DW_OP_*piece operations, or their sum is equal
-        to bitsize.  Otherwise we can't embed it.  */
-      for (tail = &cur_descr; *tail != NULL;
-          tail = &(*tail)->dw_loc_next)
-       if ((*tail)->dw_loc_opc == DW_OP_piece)
-         {
-           opsize += (*tail)->dw_loc_oprnd1.v.val_unsigned
-                     * BITS_PER_UNIT;
-           last = *tail;
-         }
-       else if ((*tail)->dw_loc_opc == DW_OP_bit_piece)
-         {
-           opsize += (*tail)->dw_loc_oprnd1.v.val_unsigned;
-           last = *tail;
-         }
-
-      if (last != NULL && opsize != bitsize)
-       {
-         padsize += bitsize;
-         continue;
-       }
-
-      /* If there is a hole, add DW_OP_*piece after empty DWARF
-        expression, which means that those bits are optimized out.  */
-      if (padsize)
-       {
-         if (padsize > decl_size)
-           return NULL;
-         decl_size -= padsize;
-         *descr_tail = new_loc_descr_op_bit_piece (padsize);
-         if (*descr_tail == NULL)
-           return NULL;
-         descr_tail = &(*descr_tail)->dw_loc_next;
-         padsize = 0;
-       }
-      *descr_tail = cur_descr;
-      descr_tail = tail;
-      if (bitsize > decl_size)
-       return NULL;
-      decl_size -= bitsize;
-      if (last == NULL)
-       {
-         *descr_tail = new_loc_descr_op_bit_piece (bitsize);
-         if (*descr_tail == NULL)
-           return NULL;
-         descr_tail = &(*descr_tail)->dw_loc_next;
-       }
-    }
-
-  /* If there were any non-empty expressions, add padding till the end of
-     the decl.  */
-  if (descr != NULL && decl_size != 0)
-    {
-      *descr_tail = new_loc_descr_op_bit_piece (decl_size);
-      if (*descr_tail == NULL)
-       return NULL;
-    }
-  return descr;
-}
-
 /* Return the dwarf representation of the location list LOC_LIST of
    DECL.  WANT_ADDRESS has the same meaning as in loc_list_from_tree
    function.  */
@@ -14508,48 +14175,45 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 
   secname = secname_for_decl (decl);
 
-  for (node = loc_list->first; node; node = node->next)
-    if (GET_CODE (node->loc) == EXPR_LIST
-       || NOTE_VAR_LOCATION_LOC (node->loc) != NULL_RTX)
+  for (node = loc_list->first; node->next; node = node->next)
+    if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
       {
-       if (GET_CODE (node->loc) == EXPR_LIST)
-         {
-           /* This requires DW_OP_{,bit_}piece, which is not usable
-              inside DWARF expressions.  */
-           if (want_address != 2)
-             continue;
-           descr = dw_sra_loc_expr (decl, node->loc);
-           if (descr == NULL)
-             continue;
-         }
-       else
-         {
-           initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
-           varloc = NOTE_VAR_LOCATION (node->loc);
-           descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
-         }
+       /* The variable has a location between NODE->LABEL and
+          NODE->NEXT->LABEL.  */
+       initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+       varloc = NOTE_VAR_LOCATION (node->var_loc_note);
+       descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
        if (descr)
          {
-           /* The variable has a location between NODE->LABEL and
-              NODE->NEXT->LABEL.  */
-           if (node->next)
-             endname = node->next->label;
-           /* If the variable has a location at the last label
-              it keeps its location until the end of function.  */
-           else if (!current_function_decl)
-             endname = text_end_label;
-           else
-             {
-               ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
-                                            current_function_funcdef_no);
-               endname = ggc_strdup (label_id);
-             }
-
-           *listp = new_loc_list (descr, node->label, endname, secname);
+           *listp = new_loc_list (descr, node->label, node->next->label,
+                                  secname);
            listp = &(*listp)->dw_loc_next;
          }
       }
 
+  /* If the variable has a location at the last label
+     it keeps its location until the end of function.  */
+  if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
+    {
+      initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+      varloc = NOTE_VAR_LOCATION (node->var_loc_note);
+      descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
+      if (descr)
+       {
+         if (!current_function_decl)
+           endname = text_end_label;
+         else
+           {
+             ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
+                                          current_function_funcdef_no);
+             endname = ggc_strdup (label_id);
+           }
+
+         *listp = new_loc_list (descr, node->label, endname, secname);
+         listp = &(*listp)->dw_loc_next;
+       }
+    }
+
   /* Try to avoid the overhead of a location list emitting a location
      expression instead, but only if we didn't have more than one
      location entry in the first place.  If some entries were not
@@ -15670,24 +15334,6 @@ extract_int (const unsigned char *src, unsigned int size)
   return val;
 }
 
-/* Writes double_int values to dw_vec_const array.  */
-
-static void
-insert_double (double_int val, unsigned char *dest)
-{
-  unsigned char *p0 = dest;
-  unsigned char *p1 = dest + sizeof (HOST_WIDE_INT);
-
-  if (WORDS_BIG_ENDIAN)
-    {
-      p0 = p1;
-      p1 = dest;
-    }
-
-  insert_int ((HOST_WIDE_INT) val.low, sizeof (HOST_WIDE_INT), p0);
-  insert_int ((HOST_WIDE_INT) val.high, sizeof (HOST_WIDE_INT), p1);
-}
-
 /* Writes floating point values to dw_vec_const array.  */
 
 static void
@@ -15767,14 +15413,39 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
            for (i = 0, p = array; i < length; i++, p += elt_size)
              {
                rtx elt = CONST_VECTOR_ELT (rtl, i);
-               double_int val = rtx_to_double_int (elt);
+               HOST_WIDE_INT lo, hi;
+
+               switch (GET_CODE (elt))
+                 {
+                 case CONST_INT:
+                   lo = INTVAL (elt);
+                   hi = -(lo < 0);
+                   break;
+
+                 case CONST_DOUBLE:
+                   lo = CONST_DOUBLE_LOW (elt);
+                   hi = CONST_DOUBLE_HIGH (elt);
+                   break;
+
+                 default:
+                   gcc_unreachable ();
+                 }
 
                if (elt_size <= sizeof (HOST_WIDE_INT))
-                 insert_int (double_int_to_shwi (val), elt_size, p);
+                 insert_int (lo, elt_size, p);
                else
                  {
+                   unsigned char *p0 = p;
+                   unsigned char *p1 = p + sizeof (HOST_WIDE_INT);
+
                    gcc_assert (elt_size == 2 * sizeof (HOST_WIDE_INT));
-                   insert_double (val, p);
+                   if (WORDS_BIG_ENDIAN)
+                     {
+                       p0 = p1;
+                       p1 = p;
+                     }
+                   insert_int (lo, sizeof (HOST_WIDE_INT), p0);
+                   insert_int (hi, sizeof (HOST_WIDE_INT), p1);
                  }
              }
            break;
@@ -16298,9 +15969,8 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
   if (loc_list
       && loc_list->first
       && loc_list->first->next == NULL
-      && NOTE_P (loc_list->first->loc)
-      && NOTE_VAR_LOCATION (loc_list->first->loc)
-      && NOTE_VAR_LOCATION_LOC (loc_list->first->loc))
+      && NOTE_VAR_LOCATION (loc_list->first->var_loc_note)
+      && NOTE_VAR_LOCATION_LOC (loc_list->first->var_loc_note))
     {
       struct var_loc_node *node;
 
@@ -17138,7 +16808,8 @@ add_name_and_src_coords_attributes (dw_die_ref die, tree decl)
       if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL)
          && TREE_PUBLIC (decl)
          && !DECL_ABSTRACT (decl)
-         && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)))
+         && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
+         && !is_fortran ())
        {
          /* Defer until we have an assembler name set.  */
          if (!DECL_ASSEMBLER_NAME_SET_P (decl))
@@ -19110,20 +18781,6 @@ gen_compile_unit_die (const char *filename)
     }
 
   add_AT_unsigned (die, DW_AT_language, language);
-
-  switch (language)
-    {
-    case DW_LANG_Fortran77:
-    case DW_LANG_Fortran90:
-    case DW_LANG_Fortran95:
-      /* Fortran has case insensitive identifiers and the front-end
-        lowercases everything.  */
-      add_AT_unsigned (die, DW_AT_identifier_case, DW_ID_down_case);
-      break;
-    default:
-      /* The default DW_ID_case_sensitive doesn't need to be specified.  */
-      break;
-    }
   return die;
 }
 
@@ -19544,19 +19201,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
       break;
 
     case LANG_TYPE:
-      /* Just use DW_TAG_unspecified_type.  */
-      {
-        dw_die_ref type_die = lookup_type_die (type);
-        if (type_die == NULL)
-          {
-           tree name = TYPE_NAME (type);
-           if (TREE_CODE (name) == TYPE_DECL)
-             name = DECL_NAME (name);
-            type_die = new_die (DW_TAG_unspecified_type, comp_unit_die, type);
-            add_name_attribute (type_die, IDENTIFIER_POINTER (name));
-            equate_type_number_to_die (type, type_die);
-          }
-      }
+      /* No Dwarf representation currently defined.  */
       break;
 
     default:
@@ -20178,7 +19823,10 @@ dwarf2out_imported_module_or_decl_1 (tree decl,
 
   if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL)
     {
-      at_import_die = force_type_die (TREE_TYPE (decl));
+      if (is_base_type (TREE_TYPE (decl)))
+       at_import_die = base_type_die (TREE_TYPE (decl));
+      else
+       at_import_die = force_type_die (TREE_TYPE (decl));
       /* For namespace N { typedef void T; } using N::T; base_type_die
         returns NULL, but DW_TAG_imported_declaration requires
         the DW_AT_import tag.  Force creation of DW_TAG_typedef.  */
@@ -20807,6 +20455,8 @@ dwarf2out_var_location (rtx loc_note)
       loclabel_num++;
       last_label = ggc_strdup (loclabel);
     }
+  newloc->var_loc_note = loc_note;
+  newloc->next = NULL;
 
   if (!NOTE_DURING_CALL_P (loc_note))
     newloc->label = last_label;
@@ -21611,6 +21261,7 @@ resolve_one_addr (rtx *addr, void *data ATTRIBUTE_UNUSED)
 
   if (GET_CODE (rtl) == SYMBOL_REF
       && SYMBOL_REF_DECL (rtl)
+      && TREE_CODE (SYMBOL_REF_DECL (rtl)) == VAR_DECL
       && !TREE_ASM_WRITTEN (SYMBOL_REF_DECL (rtl)))
     return 1;