OSDN Git Service

PR rtl-optimization/23898
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Sep 2005 21:48:36 +0000 (21:48 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Sep 2005 21:48:36 +0000 (21:48 +0000)
* output.h (get_attr_min_length): Declare.
* final.c (get_attr_length_1): New function, broken out of:
(get_attr_length).
(get_attr_min_length): New function.
* bb-reorder.c (copy_bb_p, get_uncond_jump_length): Use it.
(duplicate_computed_gotos): Likewise.
* genattr.c (insn_min_length): Generate declaration.
* genattrtab.c (min_fn, min_attr_value): New functions.
(make_length_attrs): Generate insn_min_length.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104468 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/bb-reorder.c
gcc/final.c
gcc/genattr.c
gcc/genattrtab.c
gcc/output.h

index 15f7f29..a4e0484 100644 (file)
@@ -1,3 +1,16 @@
+2005-09-20  J"orn Rennecke <joern.rennecke@st.com>
+
+       PR rtl-optimization/23898
+       * output.h (get_attr_min_length): Declare.
+       * final.c (get_attr_length_1): New function, broken out of:
+       (get_attr_length).
+       (get_attr_min_length): New function.
+       * bb-reorder.c (copy_bb_p, get_uncond_jump_length): Use it.
+       (duplicate_computed_gotos): Likewise.
+       * genattr.c (insn_min_length): Generate declaration.
+       * genattrtab.c (min_fn, min_attr_value): New functions.
+       (make_length_attrs): Generate insn_min_length.
+
 2005-09-20  Steve Ellcey  <sje@cup.hp.com>
 
        * config/pa/pa.c (output_cbranch): Check for zero in operands[2].
index c5de235..68d2cd8 100644 (file)
@@ -1178,7 +1178,7 @@ copy_bb_p (basic_block bb, int code_may_grow)
   FOR_BB_INSNS (bb, insn)
     {
       if (INSN_P (insn))
-       size += get_attr_length (insn);
+       size += get_attr_min_length (insn);
     }
 
   if (size <= max_size)
@@ -1205,7 +1205,7 @@ get_uncond_jump_length (void)
   label = emit_label_before (gen_label_rtx (), get_insns ());
   jump = emit_jump_insn (gen_jump (label));
 
-  length = get_attr_length (jump);
+  length = get_attr_min_length (jump);
 
   delete_insn (jump);
   delete_insn (label);
@@ -2030,7 +2030,7 @@ duplicate_computed_gotos (void)
       FOR_BB_INSNS (bb, insn)
        if (INSN_P (insn))
          {
-           size += get_attr_length (insn);
+           size += get_attr_min_length (insn);
            if (size > max_size)
               break;
          }
index e1a4c18..f827069 100644 (file)
@@ -383,10 +383,11 @@ init_insn_lengths (void)
 }
 
 /* Obtain the current length of an insn.  If branch shortening has been done,
-   get its actual length.  Otherwise, get its maximum length.  */
-
-int
-get_attr_length (rtx insn ATTRIBUTE_UNUSED)
+   get its actual length.  Otherwise, use FALLBACK_FN to calcualte the
+   length.  */
+static inline int
+get_attr_length_1 (rtx insn ATTRIBUTE_UNUSED,
+                  int (*fallback_fn) (rtx) ATTRIBUTE_UNUSED)
 {
 #ifdef HAVE_ATTR_length
   rtx body;
@@ -404,7 +405,7 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
        return 0;
 
       case CALL_INSN:
-       length = insn_default_length (insn);
+       length = fallback_fn (insn);
        break;
 
       case JUMP_INSN:
@@ -415,7 +416,7 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
               ADDR_VEC_ALIGN.  */
          }
        else
-         length = insn_default_length (insn);
+         length = fallback_fn (insn);
        break;
 
       case INSN:
@@ -424,12 +425,12 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
          return 0;
 
        else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
-         length = asm_insn_count (body) * insn_default_length (insn);
+         length = asm_insn_count (body) * fallback_fn (insn);
        else if (GET_CODE (body) == SEQUENCE)
          for (i = 0; i < XVECLEN (body, 0); i++)
            length += get_attr_length (XVECEXP (body, 0, i));
        else
-         length = insn_default_length (insn);
+         length = fallback_fn (insn);
        break;
 
       default:
@@ -444,6 +445,22 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
   return 0;
 #endif /* not HAVE_ATTR_length */
 }
+
+/* Obtain the current length of an insn.  If branch shortening has been done,
+   get its actual length.  Otherwise, get its maximum length.  */
+int
+get_attr_length (rtx insn)
+{
+  return get_attr_length_1 (insn, insn_default_length);
+}
+
+/* Obtain the current length of an insn.  If branch shortening has been done,
+   get its actual length.  Otherwise, get its minimum length.  */
+int
+get_attr_min_length (rtx insn)
+{
+  return get_attr_length_1 (insn, insn_min_length);
+}
 \f
 /* Code to handle alignment inside shorten_branches.  */
 
index a103795..0e039e7 100644 (file)
@@ -79,6 +79,7 @@ gen_attr (rtx attr)
       puts ("\
 extern void shorten_branches (rtx);\n\
 extern int insn_default_length (rtx);\n\
+extern int insn_min_length (rtx);\n\
 extern int insn_variable_length_p (rtx);\n\
 extern int insn_current_length (rtx);\n\n\
 #include \"insn-addr.h\"\n");
index 78a61e8..359dddd 100644 (file)
@@ -285,6 +285,7 @@ static rtx identity_fn              (rtx);
 static rtx zero_fn             (rtx);
 static rtx one_fn              (rtx);
 static rtx max_fn              (rtx);
+static rtx min_fn              (rtx);
 static void write_length_unit_log (void);
 static rtx simplify_cond       (rtx, int, int);
 static void clear_struct_flag (rtx);
@@ -307,6 +308,7 @@ static void gen_insn                (rtx, int);
 static void gen_delay          (rtx, int);
 static void write_test_expr    (rtx, int);
 static int max_attr_value      (rtx, int*);
+static int min_attr_value      (rtx, int*);
 static int or_attr_value       (rtx, int*);
 static void walk_attr_value    (rtx);
 static void write_attr_get     (struct attr_desc *);
@@ -1583,11 +1585,14 @@ make_length_attrs (void)
   static const char *new_names[] =
     {
       "*insn_default_length",
+      "*insn_min_length",
       "*insn_variable_length_p",
       "*insn_current_length"
     };
-  static rtx (*const no_address_fn[]) (rtx) = {identity_fn, zero_fn, zero_fn};
-  static rtx (*const address_fn[]) (rtx) = {max_fn, one_fn, identity_fn};
+  static rtx (*const no_address_fn[]) (rtx)
+    = {identity_fn,identity_fn, zero_fn, zero_fn};
+  static rtx (*const address_fn[]) (rtx)
+    = {max_fn, min_fn, one_fn, identity_fn};
   size_t i;
   struct attr_desc *length_attr, *new_attr;
   struct attr_value *av, *new_av;
@@ -1654,6 +1659,13 @@ max_fn (rtx exp)
   return make_numeric_value (max_attr_value (exp, &unknown));
 }
 
+static rtx
+min_fn (rtx exp)
+{
+  int unknown;
+  return make_numeric_value (min_attr_value (exp, &unknown));
+}
+
 static void
 write_length_unit_log (void)
 {
@@ -3531,6 +3543,47 @@ max_attr_value (rtx exp, int *unknownp)
   return current_max;
 }
 
+/* Given an attribute value, return the minimum CONST_STRING argument
+   encountered.  Set *UNKNOWNP and return 0 if the value is unknown.  */
+
+static int
+min_attr_value (rtx exp, int *unknownp)
+{
+  int current_min;
+  int i, n;
+
+  switch (GET_CODE (exp))
+    {
+    case CONST_STRING:
+      current_min = atoi (XSTR (exp, 0));
+      break;
+
+    case COND:
+      current_min = min_attr_value (XEXP (exp, 1), unknownp);
+      for (i = 0; i < XVECLEN (exp, 0); i += 2)
+       {
+         n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
+         if (n < current_min)
+           current_min = n;
+       }
+      break;
+
+    case IF_THEN_ELSE:
+      current_min = min_attr_value (XEXP (exp, 1), unknownp);
+      n = min_attr_value (XEXP (exp, 2), unknownp);
+      if (n < current_min)
+       current_min = n;
+      break;
+
+    default:
+      *unknownp = 1;
+      current_min = INT_MAX;
+      break;
+    }
+
+  return current_min;
+}
+
 /* Given an attribute value, return the result of ORing together all
    CONST_STRING arguments encountered.  Set *UNKNOWNP and return -1
    if the numeric value is not known.  */
index c0dfb5f..cb8d8c0 100644 (file)
@@ -49,6 +49,10 @@ extern void init_insn_lengths (void);
    get its actual length.  Otherwise, get its maximum length.  */
 extern int get_attr_length (rtx);
 
+/* Obtain the current length of an insn.  If branch shortening has been done,
+   get its actual length.  Otherwise, get its minimum length.  */
+extern int get_attr_min_length (rtx);
+
 /* Make a pass over all insns and compute their actual lengths by shortening
    any branches of variable length if possible.  */
 extern void shorten_branches (rtx);