OSDN Git Service

2009-07-20 Shujing Zhao <pearly.zhao@oracle.com>
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 35c26b6..2c5d056 100644 (file)
@@ -74,7 +74,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "expr.h"
 #include "libfuncs.h"
 #include "except.h"
-#include "elf/dwarf2.h"
+#include "dwarf2.h"
 #include "dwarf2out.h"
 #include "dwarf2asm.h"
 #include "toplev.h"
@@ -283,6 +283,11 @@ typedef struct GTY(()) dw_fde_struct {
   unsigned stack_realign : 1;
   /* Whether dynamic realign argument pointer register has been saved.  */
   unsigned drap_reg_saved: 1;
+  /* True iff dw_fde_begin label is in text_section or cold_text_section.  */
+  unsigned in_std_section : 1;
+  /* True iff dw_fde_unlikely_section_label is in text_section or
+     cold_text_section.  */
+  unsigned cold_in_std_section : 1;
 }
 dw_fde_node;
 
@@ -994,7 +999,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p)
         the CFA register did not change but the offset did.  The data 
         factoring for DW_CFA_def_cfa_offset_sf happens in output_cfi, or
         in the assembler via the .cfi_def_cfa_offset directive.  */
-      if (need_data_align_sf_opcode (loc.offset))
+      if (loc.offset < 0)
        cfi->dw_cfi_opc = DW_CFA_def_cfa_offset_sf;
       else
        cfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
@@ -1021,7 +1026,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p)
         the specified offset.  The data factoring for DW_CFA_def_cfa_sf
         happens in output_cfi, or in the assembler via the .cfi_def_cfa
         directive.  */
-      if (need_data_align_sf_opcode (loc.offset))
+      if (loc.offset < 0)
        cfi->dw_cfi_opc = DW_CFA_def_cfa_sf;
       else
        cfi->dw_cfi_opc = DW_CFA_def_cfa;
@@ -2759,6 +2764,22 @@ dwarf2out_begin_epilogue (rtx insn)
       if (CALL_P (i) && SIBLING_CALL_P (i))
        break;
 
+      if (GET_CODE (PATTERN (i)) == SEQUENCE)
+       {
+         int idx;
+         rtx seq = PATTERN (i);
+
+         if (returnjump_p (XVECEXP (seq, 0, 0)))
+           break;
+         if (CALL_P (XVECEXP (seq, 0, 0))
+             && SIBLING_CALL_P (XVECEXP (seq, 0, 0)))
+           break;
+
+         for (idx = 0; idx < XVECLEN (seq, 0); idx++)
+           if (RTX_FRAME_RELATED_P (XVECEXP (seq, 0, idx)))
+             saw_frp = true;
+       }
+
       if (RTX_FRAME_RELATED_P (i))
        saw_frp = true;
     }
@@ -3571,6 +3592,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
   char * dup_label;
   dw_fde_ref fde;
+  section *fnsec;
 
   current_function_func_begin_label = NULL;
 
@@ -3586,7 +3608,8 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
     return;
 #endif
 
-  switch_to_section (function_section (current_function_decl));
+  fnsec = function_section (current_function_decl);
+  switch_to_section (fnsec);
   ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL,
                               current_function_funcdef_no);
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, FUNC_BEGIN_LABEL,
@@ -3630,6 +3653,27 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
   fde->drap_reg = INVALID_REGNUM;
   fde->vdrap_reg = INVALID_REGNUM;
+  if (flag_reorder_blocks_and_partition)
+    {
+      section *unlikelysec;
+      if (first_function_block_is_cold)
+       fde->in_std_section = 1;
+      else
+       fde->in_std_section
+         = (fnsec == text_section
+            || (cold_text_section && fnsec == cold_text_section));
+      unlikelysec = unlikely_text_section ();
+      fde->cold_in_std_section
+       = (unlikelysec == text_section
+          || (cold_text_section && unlikelysec == cold_text_section));
+    }
+  else
+    {
+      fde->in_std_section
+       = (fnsec == text_section
+          || (cold_text_section && fnsec == cold_text_section));
+      fde->cold_in_std_section = 0;
+    }
 
   args_size = old_args_size = 0;
 
@@ -10240,11 +10284,10 @@ based_loc_descr (rtx reg, HOST_WIDE_INT offset,
             is aligned without drap, use stack pointer + offset to
             access stack variables.  */
          if (crtl->stack_realign_tried
-             && cfa.reg == HARD_FRAME_POINTER_REGNUM
              && reg == frame_pointer_rtx)
            {
              int base_reg
-               = DWARF_FRAME_REGNUM (cfa.indirect
+               = DWARF_FRAME_REGNUM ((fde && fde->drap_reg != INVALID_REGNUM)
                                      ? HARD_FRAME_POINTER_REGNUM
                                      : STACK_POINTER_REGNUM);
              return new_reg_loc_descr (base_reg, offset);
@@ -11460,22 +11503,31 @@ add_data_member_location_attribute (dw_die_ref die, tree decl)
 
   if (! loc_descr)
     {
-      enum dwarf_location_atom op;
-
-      /* The DWARF2 standard says that we should assume that the structure
-        address is already on the stack, so we can specify a structure field
-        address by using DW_OP_plus_uconst.  */
-
+      if (dwarf_version > 2)
+       {
+         /* Don't need to output a location expression, just the constant. */
+         add_AT_int (die, DW_AT_data_member_location, offset);
+         return;
+       }
+      else
+       {
+         enum dwarf_location_atom op;
+         
+         /* The DWARF2 standard says that we should assume that the structure
+            address is already on the stack, so we can specify a structure
+            field address by using DW_OP_plus_uconst.  */
+         
 #ifdef MIPS_DEBUGGING_INFO
-      /* ??? The SGI dwarf reader does not handle the DW_OP_plus_uconst
-        operator correctly.  It works only if we leave the offset on the
-        stack.  */
-      op = DW_OP_constu;
+         /* ??? The SGI dwarf reader does not handle the DW_OP_plus_uconst
+            operator correctly.  It works only if we leave the offset on the
+            stack.  */
+         op = DW_OP_constu;
 #else
-      op = DW_OP_plus_uconst;
+         op = DW_OP_plus_uconst;
 #endif
-
-      loc_descr = new_loc_descr (op, offset, 0);
+         
+         loc_descr = new_loc_descr (op, offset, 0);
+       }
     }
 
   add_AT_loc (die, DW_AT_data_member_location, loc_descr);
@@ -15083,6 +15135,8 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
   if (type == NULL_TREE || type == error_mark_node)
     return;
 
+  /* If TYPE is a typedef type variant, let's generate debug info
+     for the parent typedef which TYPE is a type of.  */
   if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
       && DECL_ORIGINAL_TYPE (TYPE_NAME (type)))
     {
@@ -17104,12 +17158,14 @@ dwarf2out_finish (const char *filename)
 
          if (fde->dw_fde_switched_sections)
            {
-             add_ranges_by_labels (fde->dw_fde_hot_section_label,
-                                   fde->dw_fde_hot_section_end_label);
-             add_ranges_by_labels (fde->dw_fde_unlikely_section_label,
-                                   fde->dw_fde_unlikely_section_end_label);
+             if (!fde->in_std_section)
+               add_ranges_by_labels (fde->dw_fde_hot_section_label,
+                                     fde->dw_fde_hot_section_end_label);
+             if (!fde->cold_in_std_section)
+               add_ranges_by_labels (fde->dw_fde_unlikely_section_label,
+                                     fde->dw_fde_unlikely_section_end_label);
            }
-         else
+         else if (!fde->in_std_section)
            add_ranges_by_labels (fde->dw_fde_begin,
                                  fde->dw_fde_end);
        }