OSDN Git Service

ch:
[pf3gnuchains/gcc-fork.git] / gcc / except.c
index 405a53f..efa61e5 100644 (file)
@@ -463,13 +463,13 @@ static void start_dynamic_cleanup PARAMS ((tree, tree));
 static void start_dynamic_handler      PARAMS ((void));
 static void expand_rethrow     PARAMS ((rtx));
 static void output_exception_table_entry       PARAMS ((FILE *, int));
-static int can_throw           PARAMS ((rtx));
 static rtx scan_region         PARAMS ((rtx, int, int *));
 static void eh_regs            PARAMS ((rtx *, rtx *, rtx *, int));
 static void set_insn_eh_region PARAMS ((rtx *, int));
 #ifdef DONT_USE_BUILTIN_SETJMP
 static void jumpif_rtx         PARAMS ((rtx, rtx));
 #endif
+static void find_exception_handler_labels_1 PARAMS ((rtx));
 static void mark_eh_node        PARAMS ((struct eh_node *));
 static void mark_eh_stack       PARAMS ((struct eh_stack *));
 static void mark_eh_queue       PARAMS ((struct eh_queue *));
@@ -483,7 +483,6 @@ static int find_func_region PARAMS ((int));
 static int find_func_region_from_symbol PARAMS ((rtx));
 static void clear_function_eh_region PARAMS ((void));
 static void process_nestinfo   PARAMS ((int, eh_nesting_info *, int *));
-
 rtx expand_builtin_return_addr PARAMS ((enum built_in_function, int, rtx));
 static void emit_cleanup_handler PARAMS ((struct eh_entry *));
 static int eh_region_from_symbol PARAMS ((rtx));
@@ -495,6 +494,7 @@ static int eh_region_from_symbol PARAMS ((rtx));
 extern struct obstack permanent_obstack;
 
 /* Generate a SYMBOL_REF for rethrow to use */
+
 static rtx
 create_rethrow_ref (region_num)
      int region_num;
@@ -566,7 +566,7 @@ top_label_entry (stack)
   return (*stack)->u.tlabel;
 }
 
-/* get an exception label. These must be on the permanent obstack */
+/* Get an exception label.  */
 
 rtx
 gen_exception_label ()
@@ -602,7 +602,8 @@ push_eh_entry (stack)
   stack->top = node;
 }
 
-/* push an existing entry onto a stack. */
+/* Push an existing entry onto a stack.  */
+
 static void
 push_entry (stack, entry)
      struct eh_stack *stack;
@@ -695,7 +696,8 @@ struct func_eh_entry
 {
   int range_number;   /* EH region number from EH NOTE insn's.  */
   rtx rethrow_label;  /* Label for rethrow.  */
-  int rethrow_ref;    /* Is rethrow referenced?  */
+  int rethrow_ref;    /* Is rethrow_label referenced?  */
+  int emitted;        /* 1 if this entry has been emitted in assembly file.  */
   struct handler_info *handlers;
 };
 
@@ -737,7 +739,8 @@ new_eh_region_entry (note_eh_region, rethrow)
   else
     function_eh_regions[current_func_eh_entry].rethrow_label = rethrow;
   function_eh_regions[current_func_eh_entry].handlers = NULL;
-
+  function_eh_regions[current_func_eh_entry].emitted = 0;
   return current_func_eh_entry++;
 }
 
@@ -928,7 +931,8 @@ clear_function_eh_region ()
         next = ptr->next;
         free (ptr);
       }
-  free (function_eh_regions);
+  if (function_eh_regions)
+    free (function_eh_regions);
   num_func_eh_entries  = 0;
   current_func_eh_entry = 0;
 }
@@ -969,6 +973,7 @@ duplicate_eh_handlers (old_note_eh_region, new_note_eh_region, map)
 
 
 /* Given a rethrow symbol, find the EH region number this is for. */
+
 static int 
 eh_region_from_symbol (sym)
      rtx sym;
@@ -984,6 +989,7 @@ eh_region_from_symbol (sym)
 
 /* Like find_func_region, but using the rethrow symbol for the region
    rather than the region number itself.  */
+
 static int
 find_func_region_from_symbol (sym)
      rtx sym;
@@ -995,12 +1001,17 @@ find_func_region_from_symbol (sym)
    __rethrow as well. This performs the remap. If a symbol isn't foiund,
    the original one is returned. This is not an efficient routine,
    so don't call it on everything!! */
+
 rtx 
 rethrow_symbol_map (sym, map)
      rtx sym;
      rtx (*map) PARAMS ((rtx));
 {
   int x, y;
+
+  if (! flag_new_exceptions)
+    return sym;
+
   for (x = 0; x < current_func_eh_entry; x++)
     if (function_eh_regions[x].rethrow_label == sym)
       {
@@ -1021,6 +1032,10 @@ rethrow_symbol_map (sym, map)
   return sym;
 }
 
+/* Returns nonzero if the rethrow label for REGION is referenced
+   somewhere (i.e. we rethrow out of REGION or some other region
+   masquerading as REGION).  */
+
 int 
 rethrow_used (region)
      int region;
@@ -1348,7 +1363,7 @@ start_dynamic_handler ()
   buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2);
 
 #ifdef DONT_USE_BUILTIN_SETJMP
-  x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1,
+  x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_CONST,
                               TYPE_MODE (integer_type_node), 1,
                               buf, Pmode);
   /* If we come back here for a catch, transfer control to the handler.  */
@@ -1633,16 +1648,7 @@ expand_fixup_region_end (cleanup)
 }
 
 /* If we are using the setjmp/longjmp EH codegen method, we emit a
-   call to __sjthrow.
-
-   Otherwise, we emit a call to __throw and note that we threw
-   something, so we know we need to generate the necessary code for
-   __throw.
-
-   Before invoking throw, the __eh_pc variable must have been set up
-   to contain the PC being thrown from. This address is used by
-   __throw to determine which exception region (if any) is
-   responsible for handling the exception.  */
+   call to __sjthrow.  Otherwise, we emit a call to __throw.  */
 
 void
 emit_throw ()
@@ -1755,7 +1761,8 @@ start_catch_handler (rtime)
 
       /* Now issue the call, and branch around handler if needed */
       call_rtx = emit_library_call_value (eh_rtime_match_libfunc, NULL_RTX, 
-                                          0, TYPE_MODE (integer_type_node),
+                                          LCT_NORMAL,
+                                         TYPE_MODE (integer_type_node),
                                          1, rtime_address, Pmode);
 
       /* Did the function return true? */
@@ -1861,10 +1868,9 @@ emit_cleanup_handler (entry)
   end_sequence ();
 
   /* And add it to the CATCH_CLAUSES.  */
-  push_to_sequence (catch_clauses);
+  push_to_full_sequence (catch_clauses, catch_clauses_last);
   emit_insns (handler_insns);
-  catch_clauses = get_insns ();
-  end_sequence ();
+  end_full_sequence (&catch_clauses, &catch_clauses_last);
 
   /* Now we've left the handler.  */
   pop_ehqueue ();
@@ -1986,10 +1992,9 @@ expand_end_all_catch ()
   pop_label_entry (&outer_context_label_stack);
 
   /* Add the new sequence of catches to the main one for this function.  */
-  push_to_sequence (catch_clauses);
+  push_to_full_sequence (catch_clauses, catch_clauses_last);
   emit_insns (new_catch_clause);
-  catch_clauses = get_insns ();
-  end_sequence ();
+  end_full_sequence (&catch_clauses, &catch_clauses_last);
   
   /* Here we fall through into the continuation code.  */
 }
@@ -2011,7 +2016,7 @@ expand_rethrow (label)
          label = last_rethrow_symbol;
        emit_library_call (rethrow_libfunc, 0, VOIDmode, 1, label, Pmode);
        region = find_func_region (eh_region_from_symbol (label));
-       /* If the region is -1, it doesn't exist yet.  We should be
+       /* If the region is -1, it doesn't exist yet.  We shouldn't be
           trying to rethrow there yet.  */
        if (region == -1)
          abort ();
@@ -2160,6 +2165,24 @@ add_eh_table_entry (n)
        }
     }
   eh_table[eh_table_size++] = n;
+  
+  if (flag_new_exceptions)
+    {
+      /* We will output the exception table late in the compilation. That
+         references type_info objects which should have already been output
+         by that time. We explicitly mark those objects as being
+         referenced now so we know to emit them.  */
+      struct handler_info *handler = get_first_handler (n);
+      
+      for (; handler; handler = handler->next)
+        if (handler->type_info && handler->type_info != CATCH_ALL_TYPE)
+          {
+            tree tinfo = (tree)handler->type_info;
+
+            tinfo = TREE_OPERAND (tinfo, 0);
+            TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
+          }
+    }
 #endif
 }
 
@@ -2194,14 +2217,16 @@ output_exception_table_entry (file, n)
   int index = find_func_region (n);
   rtx rethrow;
   
- /* form and emit the rethrow label, if needed  */
-  rethrow = function_eh_regions[index].rethrow_label;
-  if (rethrow != NULL_RTX && !flag_new_exceptions)
-      rethrow = NULL_RTX;
-  if (rethrow != NULL_RTX && handler == NULL)
-    if (! function_eh_regions[index].rethrow_ref)
-      rethrow = NULL_RTX;
+  /* Form and emit the rethrow label, if needed  */
+  if (flag_new_exceptions
+      && (handler || function_eh_regions[index].rethrow_ref))
+    rethrow = function_eh_regions[index].rethrow_label;
+  else
+    rethrow = NULL_RTX;
 
+  if (function_eh_regions[index].emitted)
+    return;
+  function_eh_regions[index].emitted  = 1;
 
   for ( ; handler != NULL || rethrow != NULL_RTX; handler = handler->next)
     {
@@ -2209,34 +2234,34 @@ output_exception_table_entry (file, n)
       if (rethrow != NULL_RTX && (handler == NULL || handler->next == NULL))
         {
           ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", n);
-          assemble_label(buf);
+          assemble_eh_label(buf);
           rethrow = NULL_RTX;
         }
 
       ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n);
       sym = gen_rtx_SYMBOL_REF (Pmode, buf);
-      assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
+      assemble_eh_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
 
       ASM_GENERATE_INTERNAL_LABEL (buf, "LEHE", n);
       sym = gen_rtx_SYMBOL_REF (Pmode, buf);
-      assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
+      assemble_eh_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
       
       if (handler == NULL)
-        assemble_integer (GEN_INT (0), POINTER_SIZE / BITS_PER_UNIT, 1);
+        assemble_eh_integer (GEN_INT (0), POINTER_SIZE / BITS_PER_UNIT, 1);
       else
         {
           ASM_GENERATE_INTERNAL_LABEL (buf, "L", handler->handler_number);
           sym = gen_rtx_SYMBOL_REF (Pmode, buf);
-          assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
+          assemble_eh_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
         }
 
       if (flag_new_exceptions)
         {
           if (handler == NULL || handler->type_info == NULL)
-            assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
+            assemble_eh_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
           else
             if (handler->type_info == CATCH_ALL_TYPE)
-              assemble_integer (GEN_INT (CATCH_ALL_TYPE), 
+              assemble_eh_integer (GEN_INT (CATCH_ALL_TYPE), 
                                              POINTER_SIZE / BITS_PER_UNIT, 1);
             else
               output_constant ((tree)(handler->type_info), 
@@ -2270,61 +2295,101 @@ set_exception_version_code (code)
   version_code = code;
 }
 
-
+/* Free the EH table structures.  */
 void
-output_exception_table ()
+free_exception_table ()
+{
+  if (eh_table)
+    free (eh_table);
+  clear_function_eh_region ();
+}
+  
+/* Output the common content of an exception table.  */
+void
+output_exception_table_data ()
 {
   int i;
   char buf[256];
   extern FILE *asm_out_file;
 
-  if (! doing_eh (0) || ! eh_table)
-    return;
-
-  exception_section ();
-
-  /* Beginning marker for table.  */
-  assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
-  assemble_label ("__EXCEPTION_TABLE__");
-
   if (flag_new_exceptions)
     {
-      assemble_integer (GEN_INT (NEW_EH_RUNTIME), 
+      assemble_eh_integer (GEN_INT (NEW_EH_RUNTIME), 
                                         POINTER_SIZE / BITS_PER_UNIT, 1);
-      assemble_integer (GEN_INT (language_code), 2 , 1); 
-      assemble_integer (GEN_INT (version_code), 2 , 1);
+      assemble_eh_integer (GEN_INT (language_code), 2 , 1); 
+      assemble_eh_integer (GEN_INT (version_code), 2 , 1);
 
       /* Add enough padding to make sure table aligns on a pointer boundry. */
       i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4;
       for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT)
         ;
       if (i != 0)
-        assemble_integer (const0_rtx, i , 1);
+        assemble_eh_integer (const0_rtx, i , 1);
 
-      /* Generate the label for offset calculations on rethrows */
+      /* Generate the label for offset calculations on rethrows */
       ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", 0);
-      assemble_label(buf);
+      assemble_eh_label(buf);
     }
 
   for (i = 0; i < eh_table_size; ++i)
     output_exception_table_entry (asm_out_file, eh_table[i]);
 
-  free (eh_table);
-  clear_function_eh_region ();
+}
+
+/* Output an exception table for the entire compilation unit.  */
+void
+output_exception_table ()
+{
+  char buf[256];
+  extern FILE *asm_out_file;
+
+  if (! doing_eh (0) || ! eh_table)
+    return;
+
+  exception_section ();
+
+  /* Beginning marker for table.  */
+  assemble_eh_align (GET_MODE_ALIGNMENT (ptr_mode));
+  assemble_eh_label ("__EXCEPTION_TABLE__");
+
+  output_exception_table_data ();
 
   /* Ending marker for table.  */
   /* Generate the label for end of table. */
   ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", CODE_LABEL_NUMBER (final_rethrow));
-  assemble_label(buf);
-  assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
+  assemble_eh_label(buf);
+  assemble_eh_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
 
-  /* for binary compatability, the old __throw checked the second
+  /* For binary compatibility, the old __throw checked the second
      position for a -1, so we should output at least 2 -1's */
   if (! flag_new_exceptions)
-    assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
+    assemble_eh_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
 
   putc ('\n', asm_out_file);           /* blank line */
 }
+
+/* Used by the ia64 unwind format to output data for an individual 
+   function.  */
+void
+output_function_exception_table ()
+{
+  extern FILE *asm_out_file;
+
+  if (! doing_eh (0) || ! eh_table)
+    return;
+
+#ifdef HANDLER_SECTION
+  HANDLER_SECTION;
+#endif
+
+  output_exception_table_data ();
+
+  /* Ending marker for table.  */
+  assemble_eh_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
+
+  putc ('\n', asm_out_file);           /* blank line */
+}
+
 \f
 /* Emit code to get EH context.
    
@@ -2370,27 +2435,18 @@ emit_eh_context ()
       }
 }
 
-/* Scan the current insns and build a list of handler labels. The
-   resulting list is placed in the global variable exception_handler_labels.
+/* Scan the insn chain F and build a list of handler labels. The
+   resulting list is placed in the global variable exception_handler_labels.  */
 
-   It is called after the last exception handling region is added to
-   the current function (when the rtl is almost all built for the
-   current function) and before the jump optimization pass.  */
-
-void
-find_exception_handler_labels ()
+static void
+find_exception_handler_labels_1 (f)
+     rtx f;
 {
   rtx insn;
 
-  exception_handler_labels = NULL_RTX;
-
-  /* If we aren't doing exception handling, there isn't much to check.  */
-  if (! doing_eh (0))
-    return;
-
   /* For each start of a region, add its label to the list.  */
 
-  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+  for (insn = f; insn; insn = NEXT_INSN (insn))
     {
       struct handler_info* ptr;
       if (GET_CODE (insn) == NOTE
@@ -2409,9 +2465,34 @@ find_exception_handler_labels ()
                                ptr->handler_label, exception_handler_labels);
             }
        }
+      else if (GET_CODE (insn) == CALL_INSN
+              && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
+       {
+         find_exception_handler_labels_1 (XEXP (PATTERN (insn), 0));
+         find_exception_handler_labels_1 (XEXP (PATTERN (insn), 1));
+         find_exception_handler_labels_1 (XEXP (PATTERN (insn), 2));
+       }
     }
 }
 
+/* Scan the current insns and build a list of handler labels. The
+   resulting list is placed in the global variable exception_handler_labels.
+
+   It is called after the last exception handling region is added to
+   the current function (when the rtl is almost all built for the
+   current function) and before the jump optimization pass.  */
+void
+find_exception_handler_labels ()
+{
+  exception_handler_labels = NULL_RTX;
+
+  /* If we aren't doing exception handling, there isn't much to check.  */
+  if (! doing_eh (0))
+    return;
+
+  find_exception_handler_labels_1 (get_insns ());
+}     
+
 /* Return a value of 1 if the parameter label number is an exception handler
    label. Return 0 otherwise. */
 
@@ -2526,7 +2607,8 @@ mark_eh_status (eh)
   mark_eh_queue (eh->x_ehqueue);
   ggc_mark_rtx (eh->x_catch_clauses);
 
-  lang_mark_false_label_stack (eh->x_false_label_stack);
+  if (lang_mark_false_label_stack)
+    (*lang_mark_false_label_stack) (eh->x_false_label_stack);
   mark_tree_label_node (eh->x_caught_return_label_stack);
 
   ggc_mark_tree (eh->x_protect_list);
@@ -2609,21 +2691,24 @@ free_eh_status (f)
 }
 \f
 /* This section is for the exception handling specific optimization
-   pass.  First are the internal routines, and then the main
-   optimization pass.  */
+   pass.  */
 
 /* Determine if the given INSN can throw an exception.  */
 
-static int
+int
 can_throw (insn)
      rtx insn;
 {
+  if (GET_CODE (insn) == INSN
+      && GET_CODE (PATTERN (insn)) == SEQUENCE)
+    insn = XVECEXP (PATTERN (insn), 0, 0);
+
   /* Calls can always potentially throw exceptions, unless they have
      a REG_EH_REGION note with a value of 0 or less.  */
   if (GET_CODE (insn) == CALL_INSN)
     {
       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-      if (!note || XINT (XEXP (note, 0), 0) > 0)
+      if (!note || INTVAL (XEXP (note, 0)) > 0)
        return 1;
     }
 
@@ -2638,6 +2723,27 @@ can_throw (insn)
   return 0;
 }
 
+/* Return nonzero if nothing in this function can throw.  */
+
+int
+nothrow_function_p ()
+{
+  rtx insn;
+
+  if (! flag_exceptions)
+    return 1;
+
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    if (can_throw (insn))
+      return 0;
+  for (insn = current_function_epilogue_delay_list; insn;
+       insn = XEXP (insn, 1))
+    if (can_throw (insn))
+      return 0;
+
+  return 1;
+}
+
 /* Scan a exception region looking for the matching end and then
    remove it if possible. INSN is the start of the region, N is the
    region number, and DELETE_OUTER is to note if anything in this
@@ -2666,7 +2772,7 @@ scan_region (insn, n, delete_outer)
   /* Assume we can delete the region.  */
   int delete = 1;
 
-  /* Can't delete something which is rethrown to. */
+  /* Can't delete something which is rethrown from. */
   if (rethrow_used (n))
     delete = 0;
 
@@ -2783,9 +2889,10 @@ exception_optimize ()
     }
 }
 
-/* This function determines whether any of the exception regions in the
-   current function are targets of a rethrow or not, and set the 
-   reference flag according.  */
+/* This function determines whether the rethrow labels for any of the
+   exception regions in the current function are used or not, and set
+   the reference flag according.  */
+
 void
 update_rethrow_references ()
 {
@@ -2800,7 +2907,7 @@ update_rethrow_references ()
   saw_rethrow = (int *) xcalloc (current_func_eh_entry, sizeof (int));
 
   /* Determine what regions exist, and whether there are any rethrows
-     to those regions or not.  */
+     from those regions or not.  */
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     if (GET_CODE (insn) == CALL_INSN)
       {
@@ -2884,9 +2991,10 @@ expand_builtin_frob_return_addr (addr_tree)
    The first passes the exception context to the handler.  For this
    we use the return value register for a void*.
 
-   The second holds the stack pointer value to be restored.  For
-   this we use the static chain register if it exists and is different
-   from the previous, otherwise some arbitrary call-clobbered register.
+   The second holds the stack pointer value to be restored.  For this
+   we use the static chain register if it exists, is different from
+   the previous, and is call-clobbered; otherwise some arbitrary
+   call-clobbered register.
 
    The third holds the address of the handler itself.  Here we use
    some arbitrary call-clobbered register.  */
@@ -2897,7 +3005,7 @@ eh_regs (pcontext, psp, pra, outgoing)
      int outgoing ATTRIBUTE_UNUSED;
 {
   rtx rcontext, rsp, rra;
-  int i;
+  unsigned int i;
 
 #ifdef FUNCTION_OUTGOING_VALUE
   if (outgoing)
@@ -2913,7 +3021,8 @@ eh_regs (pcontext, psp, pra, outgoing)
     rsp = static_chain_incoming_rtx;
   else
     rsp = static_chain_rtx;
-  if (REGNO (rsp) == REGNO (rcontext))
+  if (REGNO (rsp) == REGNO (rcontext)
+      || ! call_used_regs [REGNO (rsp)])
 #endif /* STATIC_CHAIN_REGNUM */
     rsp = NULL_RTX;
 
@@ -3160,6 +3269,7 @@ in_same_eh_region (insn1, insn2)
    yet.  At some point in the future we can trim out handlers which we
    know cannot be called. (ie, if a block has an INT type handler,
    control will never be passed to an outer INT type handler).  */
+
 static void 
 process_nestinfo (block, info, nested_eh_region)
      int block;
@@ -3238,6 +3348,7 @@ process_nestinfo (block, info, nested_eh_region)
 /* This function will allocate and initialize an eh_nesting_info structure. 
    It returns a pointer to the completed data structure.  If there are
    no exception regions, a NULL value is returned.  */
+
 eh_nesting_info *
 init_eh_nesting_info ()
 {
@@ -3248,6 +3359,9 @@ init_eh_nesting_info ()
   rtx insn;
   int x;
 
+  if (! flag_exceptions)
+    return 0;
+
   info = (eh_nesting_info *) xmalloc (sizeof (eh_nesting_info));
   info->region_index = (int *) xcalloc ((max_label_num () + 1), sizeof (int));
   nested_eh_region = (int *) xcalloc (max_label_num () + 1, sizeof (int));
@@ -3318,6 +3432,7 @@ init_eh_nesting_info ()
    HANDLERS is the address of a pointer to a vector of handler_info pointers.
    Upon return, this will have the handlers which can be reached by block.
    This function returns the number of elements in the handlers vector.  */
+
 int 
 reachable_handlers (block, info, insn, handlers)
      int block;
@@ -3336,7 +3451,7 @@ reachable_handlers (block, info, insn, handlers)
   if (insn && GET_CODE (insn) == CALL_INSN)
     {
       /* RETHROWs specify a region number from which we are going to rethrow.
-        This means we wont pass control to handlers in the specified
+        This means we won't pass control to handlers in the specified
         region, but rather any region OUTSIDE the specified region.
         We accomplish this by setting block to the outer_index of the
         specified region.  */
@@ -3356,7 +3471,7 @@ reachable_handlers (block, info, insn, handlers)
          note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
          if (note)
            {
-             int b = XINT (XEXP (note, 0), 0);
+             int b = INTVAL (XEXP (note, 0));
              if (b <= 0)
                index = 0;
              else