OSDN Git Service

(ext_shift_insns, ext_shift_amounts): new arrays.
[pf3gnuchains/gcc-fork.git] / gcc / integrate.c
index 0d871bd..f1e778a 100644 (file)
@@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA.  */
 #include "output.h"
 #include "integrate.h"
 #include "real.h"
 #include "output.h"
 #include "integrate.h"
 #include "real.h"
+#include "except.h"
 #include "function.h"
 #include "bytecode.h"
 
 #include "function.h"
 #include "bytecode.h"
 
@@ -170,6 +171,19 @@ function_cannot_inline_p (fndecl)
   if (current_function_has_nonlocal_goto)
     return "function with nonlocal goto cannot be inline";
 
   if (current_function_has_nonlocal_goto)
     return "function with nonlocal goto cannot be inline";
 
+  /* This is a hack, until the inliner is taught about eh regions at
+     the start of the function.  */
+  for (insn = get_insns ();
+       insn &&
+         ! (GET_CODE (insn) == NOTE
+           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG);
+       insn = NEXT_INSN (insn))
+    {
+      if (insn && GET_CODE (insn) == NOTE
+         && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
+       return "function with complex parameters cannot be inline";
+    }
+
   return 0;
 }
 \f
   return 0;
 }
 \f
@@ -309,6 +323,7 @@ initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, copy)
      the size of the incoming stack area for parameters,
      the number of bytes popped on return,
      the stack slot list,
      the size of the incoming stack area for parameters,
      the number of bytes popped on return,
      the stack slot list,
+     the labels that are forced to exist,
      some flags that are used to restore compiler globals,
      the value of current_function_outgoing_args_size,
      the original argument vector,
      some flags that are used to restore compiler globals,
      the value of current_function_outgoing_args_size,
      the original argument vector,
@@ -335,7 +350,7 @@ finish_inline (fndecl, head)
      tree fndecl;
      rtx head;
 {
      tree fndecl;
      rtx head;
 {
-  NEXT_INSN (head) = get_first_nonparm_insn ();
+  FIRST_FUNCTION_INSN (head) = get_first_nonparm_insn ();
   FIRST_PARM_INSN (head) = get_insns ();
   DECL_SAVED_INSNS (fndecl) = head;
   DECL_FRAME_SIZE (fndecl) = get_frame_size ();
   FIRST_PARM_INSN (head) = get_insns ();
   DECL_SAVED_INSNS (fndecl) = head;
   DECL_FRAME_SIZE (fndecl) = get_frame_size ();
@@ -394,7 +409,7 @@ save_for_inline_copying (fndecl)
   char *new, *new1;
 
   /* Make and emit a return-label if we have not already done so. 
   char *new, *new1;
 
   /* Make and emit a return-label if we have not already done so. 
-     Do this before recording the bounds on label numbers. */
+     Do this before recording the bounds on label numbers.  */
 
   if (return_label == 0)
     {
 
   if (return_label == 0)
     {
@@ -565,6 +580,15 @@ save_for_inline_copying (fndecl)
              NOTE_SOURCE_FILE (insn) = (char *) copy;
              NOTE_SOURCE_FILE (copy) = 0;
            }
              NOTE_SOURCE_FILE (insn) = (char *) copy;
              NOTE_SOURCE_FILE (copy) = 0;
            }
+         if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG
+             || NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_END)
+           {
+             /* We have to forward these both to match the new exception
+                region.  */
+             NOTE_BLOCK_NUMBER (copy)
+               = CODE_LABEL_NUMBER (label_map[NOTE_BLOCK_NUMBER (copy)]);
+             
+           }
          RTX_INTEGRATED_P (copy) = RTX_INTEGRATED_P (insn);
          break;
 
          RTX_INTEGRATED_P (copy) = RTX_INTEGRATED_P (insn);
          break;
 
@@ -1227,7 +1251,9 @@ expand_inline_function (fndecl, parms, target, ignore, type,
          /* If they are block mode, the types should match exactly.
             They don't match exactly if TREE_TYPE (FORMAL) == ERROR_MARK_NODE,
             which could happen if the parameter has incomplete type.  */
          /* If they are block mode, the types should match exactly.
             They don't match exactly if TREE_TYPE (FORMAL) == ERROR_MARK_NODE,
             which could happen if the parameter has incomplete type.  */
-         || (mode == BLKmode && TREE_TYPE (arg) != TREE_TYPE (formal)))
+         || (mode == BLKmode
+             && (TYPE_MAIN_VARIANT (TREE_TYPE (arg))
+                 != TYPE_MAIN_VARIANT (TREE_TYPE (formal)))))
        return (rtx) (HOST_WIDE_INT) -1;
     }
 
        return (rtx) (HOST_WIDE_INT) -1;
     }
 
@@ -1464,7 +1490,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
             that flag set if it is a register.
 
             Also, don't allow hard registers here; they might not be valid
             that flag set if it is a register.
 
             Also, don't allow hard registers here; they might not be valid
-            when substituted into insns. */
+            when substituted into insns.  */
 
          if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
              || (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
 
          if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
              || (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
@@ -1495,7 +1521,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
             that flag set if it is a register.
 
             Also, don't allow hard registers here; they might not be valid
             that flag set if it is a register.
 
             Also, don't allow hard registers here; they might not be valid
-            when substituted into insns. */
+            when substituted into insns.  */
          rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc);
          rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc);
          rtx copyreal = gen_realpart (GET_MODE (locreal), copy);
          rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc);
          rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc);
          rtx copyreal = gen_realpart (GET_MODE (locreal), copy);
@@ -1597,7 +1623,8 @@ expand_inline_function (fndecl, parms, target, ignore, type,
 
       if (GET_CODE (XEXP (loc, 0)) == REG)
        {
 
       if (GET_CODE (XEXP (loc, 0)) == REG)
        {
-         temp = force_reg (Pmode, structure_value_addr);
+         temp = force_reg (Pmode,
+                           force_operand (structure_value_addr, NULL_RTX));
          map->reg_map[REGNO (XEXP (loc, 0))] = temp;
          if ((CONSTANT_P (structure_value_addr)
               || (GET_CODE (structure_value_addr) == PLUS
          map->reg_map[REGNO (XEXP (loc, 0))] = temp;
          if ((CONSTANT_P (structure_value_addr)
               || (GET_CODE (structure_value_addr) == PLUS
@@ -1869,7 +1896,18 @@ expand_inline_function (fndecl, parms, target, ignore, type,
          if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
              && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
              && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
          if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
              && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
              && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
-           copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
+           {
+             copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
+             if (copy && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG
+                          || NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_END))
+               {
+                 rtx label = map->label_map[NOTE_BLOCK_NUMBER (copy)];
+
+                 /* We have to forward these both to match the new exception
+                    region.  */
+                 NOTE_BLOCK_NUMBER (copy) = CODE_LABEL_NUMBER (label);
+               }
+           }
          else
            copy = 0;
          break;
          else
            copy = 0;
          break;
@@ -2149,7 +2187,7 @@ copy_rtx_and_substitute (orig, map)
          else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
            {
              /* Do the same for a block to contain any arguments referenced
          else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
            {
              /* Do the same for a block to contain any arguments referenced
-                in memory. */
+                in memory.  */
              rtx loc, seq;
              int size = FUNCTION_ARGS_SIZE (DECL_SAVED_INSNS (map->fndecl));
 
              rtx loc, seq;
              int size = FUNCTION_ARGS_SIZE (DECL_SAVED_INSNS (map->fndecl));
 
@@ -2158,7 +2196,7 @@ copy_rtx_and_substitute (orig, map)
              loc = XEXP (loc, 0);
              /* When arguments grow downward, the virtual incoming 
                 args pointer points to the top of the argument block,
              loc = XEXP (loc, 0);
              /* When arguments grow downward, the virtual incoming 
                 args pointer points to the top of the argument block,
-                so the remapped location better do the same. */
+                so the remapped location better do the same.  */
 #ifdef ARGS_GROW_DOWNWARD
              loc = plus_constant (loc, size);
 #endif
 #ifdef ARGS_GROW_DOWNWARD
              loc = plus_constant (loc, size);
 #endif
@@ -2342,7 +2380,7 @@ copy_rtx_and_substitute (orig, map)
         will not have valid reg_map entries.  This can cause try_constants()
         to fail because assumes that all registers in the rtx have valid
         reg_map entries, and it may end up replacing one of these new
         will not have valid reg_map entries.  This can cause try_constants()
         to fail because assumes that all registers in the rtx have valid
         reg_map entries, and it may end up replacing one of these new
-        registers with junk. */
+        registers with junk.  */
 
       if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
        temp = change_address (temp, GET_MODE (temp), XEXP (temp, 0));
 
       if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
        temp = change_address (temp, GET_MODE (temp), XEXP (temp, 0));