OSDN Git Service

Word wrap comment
[pf3gnuchains/gcc-fork.git] / gcc / emit-rtl.c
index e238cfa..e697d55 100644 (file)
@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA.  */
 #include "expr.h"
 #include "regs.h"
 #include "hard-reg-set.h"
+#include "hashtab.h"
 #include "insn-config.h"
 #include "recog.h"
 #include "real.h"
@@ -137,6 +138,11 @@ rtx return_address_pointer_rtx;    /* (REG:Pmode RETURN_ADDRESS_POINTER_REGNUM) */
 
 rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
 
+/* A hash table storing CONST_INTs whose absolute value is greater
+   than MAX_SAVED_CONST_INT.  */
+
+static htab_t const_int_htab;
+
 /* start_sequence and gen_sequence can make a lot of rtx expressions which are
    shortly thrown away.  We use two mechanisms to prevent this waste:
 
@@ -172,16 +178,67 @@ static rtx make_call_insn_raw             PARAMS ((rtx));
 static rtx find_line_note              PARAMS ((rtx));
 static void mark_sequence_stack         PARAMS ((struct sequence_stack *));
 static void unshare_all_rtl_1          PARAMS ((rtx));
+static hashval_t const_int_htab_hash    PARAMS ((const void *));
+static int const_int_htab_eq            PARAMS ((const void *,
+                                                const void *));
+static int rtx_htab_mark_1              PARAMS ((void **, void *));
+static void rtx_htab_mark               PARAMS ((void *));
+
 \f
+/* Returns a hash code for X (which is a really a CONST_INT).  */
+
+static hashval_t
+const_int_htab_hash (x)
+     const void *x;
+{
+  return (hashval_t) INTVAL ((const struct rtx_def *) x);
+}
+
+/* Returns non-zero if the value represented by X (which is really a
+   CONST_INT) is the same as that given by Y (which is really a
+   HOST_WIDE_INT *).  */
+
+static int
+const_int_htab_eq (x, y)
+     const void *x;
+     const void *y;
+{
+  return (INTVAL ((const struct rtx_def *) x) == *((const HOST_WIDE_INT *) y));
+}
+
+/* Mark the hash-table element X (which is really a pointer to an
+   rtx).  */
+
+static int
+rtx_htab_mark_1 (x, data)
+     void **x;
+     void *data ATTRIBUTE_UNUSED;
+{
+  ggc_mark_rtx (*x);
+  return 1;
+}
+
+/* Mark all the elements of HTAB (which is really an htab_t full of
+   rtxs).  */
+
+static void
+rtx_htab_mark (htab)
+     void *htab;
+{
+  htab_traverse (*((htab_t *) htab), rtx_htab_mark_1, NULL);
+}
+
 /* There are some RTL codes that require special attention; the generation
    functions do the raw handling.  If you add to this list, modify
    special_rtx in gengenrtl.c as well.  */
 
 rtx
 gen_rtx_CONST_INT (mode, arg)
-     enum machine_mode mode;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
      HOST_WIDE_INT arg;
 {
+  void **slot;
+
   if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
     return const_int_rtx[arg + MAX_SAVED_CONST_INT];
 
@@ -190,11 +247,27 @@ gen_rtx_CONST_INT (mode, arg)
     return const_true_rtx;
 #endif
 
-  return gen_rtx_raw_CONST_INT (mode, arg);
+  /* Look up the CONST_INT in the hash table.  */
+  slot = htab_find_slot_with_hash (const_int_htab, &arg, (hashval_t) arg, 1);
+  if (*slot == 0)
+    {
+      if (!ggc_p)
+       {
+         push_obstacks_nochange ();
+         end_temporary_allocation ();
+         *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg);
+         pop_obstacks ();
+       }
+      else
+       *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg);
+    }
+
+  return (rtx) *slot;
 }
 
-/* CONST_DOUBLEs needs special handling because its length is known
+/* CONST_DOUBLEs needs special handling because their length is known
    only at run-time.  */
+
 rtx
 gen_rtx_CONST_DOUBLE (mode, arg0, arg1, arg2)
      enum machine_mode mode;
@@ -924,7 +997,8 @@ subreg_realpart_p (x)
   if (GET_CODE (x) != SUBREG)
     abort ();
 
-  return SUBREG_WORD (x) * UNITS_PER_WORD < GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (x)));
+  return ((unsigned int) SUBREG_WORD (x) * UNITS_PER_WORD
+         < GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (x))));
 }
 \f
 /* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a value,
@@ -1104,7 +1178,7 @@ subreg_lowpart_p (x)
 rtx
 operand_subword (op, i, validate_address, mode)
      rtx op;
-     int i;
+     unsigned int i;
      int validate_address;
      enum machine_mode mode;
 {
@@ -1181,7 +1255,9 @@ operand_subword (op, i, validate_address, mode)
     return gen_rtx_SUBREG (word_mode, SUBREG_REG (op), i + SUBREG_WORD (op));
   else if (GET_CODE (op) == CONCAT)
     {
-      int partwords = GET_MODE_UNIT_SIZE (GET_MODE (op)) / UNITS_PER_WORD;
+      unsigned int partwords
+       = GET_MODE_UNIT_SIZE (GET_MODE (op)) / UNITS_PER_WORD;
+
       if (i < partwords)
        return operand_subword (XEXP (op, 0), i, validate_address, mode);
       return operand_subword (XEXP (op, 1), i - partwords,
@@ -1428,7 +1504,7 @@ operand_subword (op, i, validate_address, mode)
 rtx
 operand_subword_force (op, i, mode)
      rtx op;
-     int i;
+     unsigned int i;
      enum machine_mode mode;
 {
   rtx result = operand_subword (op, i, 1, mode);
@@ -1624,9 +1700,7 @@ unshare_all_rtl (fndecl, insn)
 
   /* Make sure that virtual parameters are not shared.  */
   for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
-    {
-      copy_rtx_if_shared (DECL_RTL (decl));
-    }
+    copy_rtx_if_shared (DECL_RTL (decl));
 
   /* Unshare just about everything else.  */
   unshare_all_rtl_1 (insn);
@@ -3836,21 +3910,16 @@ init_emit ()
   REGNO_POINTER_FLAG (VIRTUAL_CFA_REGNUM) = 1;
 
 #ifdef STACK_BOUNDARY
-  REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY / BITS_PER_UNIT;
-  REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY / BITS_PER_UNIT;
-  REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM)
-    = STACK_BOUNDARY / BITS_PER_UNIT;
-  REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY / BITS_PER_UNIT;
-
-  REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM)
-    = STACK_BOUNDARY / BITS_PER_UNIT;
-  REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM)
-    = STACK_BOUNDARY / BITS_PER_UNIT;
-  REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM)
-    = STACK_BOUNDARY / BITS_PER_UNIT;
-  REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM)
-    = STACK_BOUNDARY / BITS_PER_UNIT;
-  REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = UNITS_PER_WORD;
+  REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
+  REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
+  REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
+  REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY;
+
+  REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM) = STACK_BOUNDARY;
+  REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM) = STACK_BOUNDARY;
+  REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) = STACK_BOUNDARY;
+  REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
+  REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = BITS_PER_WORD;
 #endif
 
 #ifdef INIT_EXPANDERS
@@ -4085,6 +4154,12 @@ init_emit_once (line_numbers)
   ggc_add_rtx_root (&static_chain_rtx, 1);
   ggc_add_rtx_root (&static_chain_incoming_rtx, 1);
   ggc_add_rtx_root (&return_address_pointer_rtx, 1);
+
+  /* Initialize the CONST_INT hash table.  */
+  const_int_htab = htab_create (37, const_int_htab_hash, 
+                               const_int_htab_eq, NULL);
+  ggc_add_root (&const_int_htab, 1, sizeof (const_int_htab), 
+               rtx_htab_mark);
 }
 \f
 /* Query and clear/ restore no_line_numbers.  This is used by the