OSDN Git Service

* stor-layout.c (layout_decl): Unshare size expressions copied
[pf3gnuchains/gcc-fork.git] / gcc / final.c
index abc07c5..bf5771a 100644 (file)
@@ -677,6 +677,7 @@ compute_alignments (void)
       rtx label = BB_HEAD (bb);
       int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0;
       edge e;
+      edge_iterator ei;
 
       if (!LABEL_P (label)
          || probably_never_executed_bb_p (bb))
@@ -684,7 +685,7 @@ compute_alignments (void)
       max_log = LABEL_ALIGN (label);
       max_skip = LABEL_ALIGN_MAX_SKIP;
 
-      for (e = bb->pred; e; e = e->pred_next)
+      FOR_EACH_EDGE (e, ei, bb->preds)
        {
          if (e->flags & EDGE_FALLTHRU)
            has_fallthru = 1, fallthru_frequency += EDGE_FREQUENCY (e);
@@ -767,7 +768,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
   /* Compute maximum UID and allocate label_align / uid_shuid.  */
   max_uid = get_max_uid ();
 
-  /* Free uid_shuid before reallocating it.   */
+  /* Free uid_shuid before reallocating it.  */
   free (uid_shuid);
   
   uid_shuid = xmalloc (max_uid * sizeof *uid_shuid);
@@ -788,8 +789,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
 
       /* Range of labels grows monotonically in the function.  Abort here
          means that the initialization of array got lost.  */
-      if (n_old_labels > n_labels)
-       abort ();
+      gcc_assert (n_old_labels <= n_labels);
 
       memset (label_align + n_old_labels, 0,
              (n_labels - n_old_labels) * sizeof (struct label_alignment));
@@ -933,8 +933,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
            continue;
          pat = PATTERN (insn);
          len = XVECLEN (pat, 1);
-         if (len <= 0)
-           abort ();
+         gcc_assert (len > 0);
          min_align = MAX_CODE_ALIGN;
          for (min = max_shuid, max = min_shuid, i = len - 1; i >= 0; i--)
            {
@@ -957,6 +956,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
          XEXP (pat, 3) = gen_rtx_LABEL_REF (VOIDmode, max_lab);
          insn_shuid = INSN_SHUID (insn);
          rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0));
+         memset (&flags, 0, sizeof (flags));
          flags.min_align = min_align;
          flags.base_after_vec = rel > insn_shuid;
          flags.min_after_vec  = min > insn_shuid;
@@ -1366,7 +1366,7 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
 
 #if defined (DWARF2_UNWIND_INFO) && defined (HAVE_prologue)
   if (dwarf2out_do_frame ())
-    dwarf2out_frame_debug (NULL_RTX);
+    dwarf2out_frame_debug (NULL_RTX, false);
 #endif
 
   /* If debugging, assign block numbers to all of the blocks in this
@@ -1566,10 +1566,8 @@ final (rtx first, FILE *file, int optimize, int prescan)
        {
          /* This can be triggered by bugs elsewhere in the compiler if
             new insns are created after init_insn_lengths is called.  */
-         if (NOTE_P (insn))
-           insn_current_address = -1;
-         else
-           abort ();
+         gcc_assert (NOTE_P (insn));
+         insn_current_address = -1;
        }
       else
        insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
@@ -1589,12 +1587,11 @@ get_insn_template (int code, rtx insn)
     case INSN_OUTPUT_FORMAT_MULTI:
       return insn_data[code].output.multi[which_alternative];
     case INSN_OUTPUT_FORMAT_FUNCTION:
-      if (insn == NULL)
-       abort ();
+      gcc_assert (insn);
       return (*insn_data[code].output.function) (recog_data.operand, insn);
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -1625,7 +1622,7 @@ output_alternate_entry_point (FILE *file, rtx insn)
 
     case LABEL_NORMAL:
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -1699,9 +1696,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
        case NOTE_INSN_DELETED:
        case NOTE_INSN_LOOP_BEG:
        case NOTE_INSN_LOOP_END:
-       case NOTE_INSN_LOOP_END_TOP_COND:
-       case NOTE_INSN_LOOP_CONT:
-       case NOTE_INSN_LOOP_VTOP:
        case NOTE_INSN_FUNCTION_END:
        case NOTE_INSN_REPEATED_LINE_NUMBER:
        case NOTE_INSN_EXPECTED_VALUE:
@@ -1728,9 +1722,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
             are writing to appropriately.  */
          
          if (flag_reorder_blocks_and_partition
-             && in_unlikely_text_section()
              && !scan_ahead_for_unlikely_executed_note (insn))
-           text_section ();
+           function_section (current_function_decl);
 
 #ifdef TARGET_UNWIND_INFO
          targetm.asm_out.unwind_emit (asm_out_file, insn);
@@ -1795,7 +1788,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
        case NOTE_INSN_BLOCK_BEG:
          if (debug_info_level == DINFO_LEVEL_NORMAL
              || debug_info_level == DINFO_LEVEL_VERBOSE
-             || write_symbols == DWARF_DEBUG
              || write_symbols == DWARF2_DEBUG
              || write_symbols == VMS_AND_DWARF2_DEBUG
              || write_symbols == VMS_DEBUG)
@@ -1817,7 +1809,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
        case NOTE_INSN_BLOCK_END:
          if (debug_info_level == DINFO_LEVEL_NORMAL
              || debug_info_level == DINFO_LEVEL_VERBOSE
-             || write_symbols == DWARF_DEBUG
              || write_symbols == DWARF2_DEBUG
              || write_symbols == VMS_AND_DWARF2_DEBUG
              || write_symbols == VMS_DEBUG)
@@ -1828,8 +1819,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 
              /* End of a symbol-block.  */
              --block_depth;
-             if (block_depth < 0)
-               abort ();
+             gcc_assert (block_depth >= 0);
 
              (*debug_hooks->end_block) (high_block_linenum, n);
            }
@@ -1850,8 +1840,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          break;
 
        default:
-         if (NOTE_LINE_NUMBER (insn) <= 0)
-           abort ();
+         gcc_assert (NOTE_LINE_NUMBER (insn) > 0);
          break;
        }
       break;
@@ -1859,7 +1848,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
     case BARRIER:
 #if defined (DWARF2_UNWIND_INFO)
       if (dwarf2out_do_frame ())
-       dwarf2out_frame_debug (insn);
+       dwarf2out_frame_debug (insn, false);
 #endif
       break;
 
@@ -1923,7 +1912,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
         basic blocks into separate sections of the .o file, we need
         to ensure the jump table ends up in the correct section...  */
       
-      if (flag_reorder_blocks_and_partition)
+      if (flag_reorder_blocks_and_partition
+         && targetm.have_named_sections)
        {
          rtx tmp_table, tmp_label;
          if (LABEL_P (insn)
@@ -1933,11 +1923,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
            }
          else if (scan_ahead_for_unlikely_executed_note (insn)) 
            unlikely_text_section ();
-         else 
-           {
-             if (in_unlikely_text_section ())
-               text_section ();
-           }
+         else if (in_unlikely_text_section ())
+           function_section (current_function_decl);
        }
 
       if (app_on)
@@ -1966,7 +1953,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
                {
                  int log_align;
 
-                 readonly_data_section ();
+                 targetm.asm_out.function_rodata_section (current_function_decl);
 
 #ifdef ADDR_VEC_ALIGN
                  log_align = ADDR_VEC_ALIGN (NEXT_INSN (insn));
@@ -2047,7 +2034,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 #ifdef ASM_OUTPUT_ADDR_VEC
                ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body);
 #else
-               abort ();
+               gcc_unreachable ();
 #endif
              }
            else
@@ -2055,7 +2042,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 #ifdef ASM_OUTPUT_ADDR_DIFF_VEC
                ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body);
 #else
-               abort ();
+               gcc_unreachable ();
 #endif
              }
 #else
@@ -2068,7 +2055,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
                    ASM_OUTPUT_ADDR_VEC_ELT
                      (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
 #else
-                   abort ();
+                   gcc_unreachable ();
 #endif
                  }
                else
@@ -2080,7 +2067,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
                       CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
                       CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
 #else
-                   abort ();
+                   gcc_unreachable ();
 #endif
                  }
              }
@@ -2181,7 +2168,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 #if defined (DWARF2_UNWIND_INFO)
            if (dwarf2out_do_frame ())
              for (i = 1; i < XVECLEN (body, 0); i++)
-               dwarf2out_frame_debug (XVECEXP (body, 0, i));
+               dwarf2out_frame_debug (XVECEXP (body, 0, i), false);
 #endif
 
            /* The first insn in this SEQUENCE might be a JUMP_INSN that will
@@ -2473,7 +2460,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 
 #if defined (DWARF2_UNWIND_INFO)
        if (CALL_P (insn) && dwarf2out_do_frame ())
-         dwarf2out_frame_debug (insn);
+         dwarf2out_frame_debug (insn, false);
 #endif
 
        /* Find the proper template for this insn.  */
@@ -2486,8 +2473,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          {
            rtx prev;
 
-           if (prev_nonnote_insn (insn) != last_ignored_compare)
-             abort ();
+           gcc_assert (prev_nonnote_insn (insn) == last_ignored_compare);
 
            /* We have already processed the notes between the setter and
               the user.  Make sure we don't process them again, this is
@@ -2518,7 +2504,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
            /* This instruction should have been split in shorten_branches,
               to ensure that we would have valid length info for the
               splitees.  */
-           abort ();
+           gcc_unreachable ();
 #endif
 
            return new;
@@ -2541,13 +2527,12 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
           the unwind info.   We've already done this for delay slots
           and call instructions.  */
 #if defined (DWARF2_UNWIND_INFO)
-       if (NONJUMP_INSN_P (insn)
+       if (final_sequence == 0
 #if !defined (HAVE_prologue)
            && !ACCUMULATE_OUTGOING_ARGS
 #endif
-           && final_sequence == 0
            && dwarf2out_do_frame ())
-         dwarf2out_frame_debug (insn);
+         dwarf2out_frame_debug (insn, true);
 #endif
 
        current_output_insn = debug_insn = 0;
@@ -2622,7 +2607,24 @@ alter_subreg (rtx *xp)
   /* simplify_subreg does not remove subreg from volatile references.
      We are required to.  */
   if (MEM_P (y))
-    *xp = adjust_address (y, GET_MODE (x), SUBREG_BYTE (x));
+    {
+      int offset = SUBREG_BYTE (x);
+
+      /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
+        contains 0 instead of the proper offset.  See simplify_subreg.  */
+      if (offset == 0
+         && GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x)))
+        {
+          int difference = GET_MODE_SIZE (GET_MODE (y))
+                          - GET_MODE_SIZE (GET_MODE (x));
+          if (WORDS_BIG_ENDIAN)
+            offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
+          if (BYTES_BIG_ENDIAN)
+            offset += difference % UNITS_PER_WORD;
+        }
+
+      *xp = adjust_address (y, GET_MODE (x), offset);
+    }
   else
     {
       rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
@@ -2630,14 +2632,13 @@ alter_subreg (rtx *xp)
 
       if (new != 0)
        *xp = new;
-      /* Simplify_subreg can't handle some REG cases, but we have to.  */
-      else if (REG_P (y))
+      else
        {
-         unsigned int regno = subreg_hard_regno (x, 1);
+         /* Simplify_subreg can't handle some REG cases, but we have to.  */
+         unsigned int regno = subreg_regno (x);
+         gcc_assert (REG_P (y));
          *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, SUBREG_BYTE (x));
        }
-      else
-       abort ();
     }
 
   return *xp;
@@ -2788,7 +2789,7 @@ alter_cond (rtx cond)
     switch (GET_CODE (cond))
       {
       default:
-       abort ();
+       gcc_unreachable ();
 
       case NE:
        PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT);
@@ -2847,7 +2848,7 @@ output_operand_lossage (const char *msgid, ...)
 
   va_start (ap, msgid);
 
-  pfx_str = this_is_asm_operands ? _("invalid `asm': ") : "output_operand: ";
+  pfx_str = this_is_asm_operands ? _("invalid 'asm': ") : "output_operand: ";
   asprintf (&fmt_string, "%s%s", pfx_str, _(msgid));
   vasprintf (&new_message, fmt_string, ap);
 
@@ -3100,61 +3101,66 @@ output_asm_insn (const char *template, rtx *operands)
        else if (ISALPHA (*p))
          {
            int letter = *p++;
-           c = atoi (p);
-
-           if (! ISDIGIT (*p))
-             output_operand_lossage ("operand number missing after %%-letter");
-           else if (this_is_asm_operands
-                    && (c < 0 || (unsigned int) c >= insn_noperands))
+           unsigned long opnum;
+           char *endptr;
+           
+           opnum = strtoul (p, &endptr, 10);
+
+           if (endptr == p)
+             output_operand_lossage ("operand number missing "
+                                     "after %%-letter");
+           else if (this_is_asm_operands && opnum >= insn_noperands)
              output_operand_lossage ("operand number out of range");
            else if (letter == 'l')
-             output_asm_label (operands[c]);
+             output_asm_label (operands[opnum]);
            else if (letter == 'a')
-             output_address (operands[c]);
+             output_address (operands[opnum]);
            else if (letter == 'c')
              {
-               if (CONSTANT_ADDRESS_P (operands[c]))
-                 output_addr_const (asm_out_file, operands[c]);
+               if (CONSTANT_ADDRESS_P (operands[opnum]))
+                 output_addr_const (asm_out_file, operands[opnum]);
                else
-                 output_operand (operands[c], 'c');
+                 output_operand (operands[opnum], 'c');
              }
            else if (letter == 'n')
              {
-               if (GET_CODE (operands[c]) == CONST_INT)
+               if (GET_CODE (operands[opnum]) == CONST_INT)
                  fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
-                          - INTVAL (operands[c]));
+                          - INTVAL (operands[opnum]));
                else
                  {
                    putc ('-', asm_out_file);
-                   output_addr_const (asm_out_file, operands[c]);
+                   output_addr_const (asm_out_file, operands[opnum]);
                  }
              }
            else
-             output_operand (operands[c], letter);
+             output_operand (operands[opnum], letter);
 
-           if (!opoutput[c])
-             oporder[ops++] = c;
-           opoutput[c] = 1;
+           if (!opoutput[opnum])
+             oporder[ops++] = opnum;
+           opoutput[opnum] = 1;
 
-           while (ISDIGIT (c = *p))
-             p++;
+           p = endptr;
+           c = *p;
          }
        /* % followed by a digit outputs an operand the default way.  */
        else if (ISDIGIT (*p))
          {
-           c = atoi (p);
-           if (this_is_asm_operands
-               && (c < 0 || (unsigned int) c >= insn_noperands))
+           unsigned long opnum;
+           char *endptr;
+           
+           opnum = strtoul (p, &endptr, 10);
+           if (this_is_asm_operands && opnum >= insn_noperands)
              output_operand_lossage ("operand number out of range");
            else
-             output_operand (operands[c], 0);
+             output_operand (operands[opnum], 0);
 
-           if (!opoutput[c])
-             oporder[ops++] = c;
-           opoutput[c] = 1;
+           if (!opoutput[opnum])
+             oporder[ops++] = opnum;
+           opoutput[opnum] = 1;
 
-           while (ISDIGIT (c = *p))
-             p++;
+           p = endptr;
+           c = *p;
          }
        /* % followed by punctuation: output something for that
           punctuation character alone, with no operand.
@@ -3194,7 +3200,7 @@ output_asm_label (rtx x)
          && NOTE_LINE_NUMBER (x) == NOTE_INSN_DELETED_LABEL))
     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   else
-    output_operand_lossage ("`%%l' operand isn't a label");
+    output_operand_lossage ("'%%l' operand isn't a label");
 
   assemble_name (asm_out_file, buf);
 }
@@ -3217,9 +3223,7 @@ output_operand (rtx x, int code ATTRIBUTE_UNUSED)
 
   /* If X is a pseudo-register, abort now rather than writing trash to the
      assembler file.  */
-
-  if (x && REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER)
-    abort ();
+  gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
 
   PRINT_OPERAND (asm_out_file, x, code);
 }
@@ -3518,7 +3522,7 @@ asm_fprintf (FILE *file, const char *p, ...)
          ASM_FPRINTF_EXTENSIONS (file, argptr, p)
 #endif
          default:
-           abort ();
+           gcc_unreachable ();
          }
        break;
 
@@ -3719,13 +3723,12 @@ int
 final_forward_branch_p (rtx insn)
 {
   int insn_id, label_id;
-  if (!uid_shuid)
-    abort ();
+  
+  gcc_assert (uid_shuid);
   insn_id = INSN_SHUID (insn);
   label_id = INSN_SHUID (JUMP_LABEL (insn));
   /* We've hit some insns that does not have id information available.  */
-  if (!insn_id || !label_id)
-    abort ();
+  gcc_assert (insn_id && label_id);
   return insn_id < label_id;
 }
 
@@ -3817,8 +3820,7 @@ leaf_renumber_regs_insn (rtx in_rtx)
          return;
        }
       newreg = LEAF_REG_REMAP (newreg);
-      if (newreg < 0)
-       abort ();
+      gcc_assert (newreg >= 0);
       regs_ever_live[REGNO (in_rtx)] = 0;
       regs_ever_live[newreg] = 1;
       REGNO (in_rtx) = newreg;
@@ -3861,7 +3863,7 @@ leaf_renumber_regs_insn (rtx in_rtx)
        break;
 
       default:
-       abort ();
+       gcc_unreachable ();
       }
 }
 #endif