OSDN Git Service

* doc/cppopts.texi: Remove documentation of -A-.
[pf3gnuchains/gcc-fork.git] / gcc / global.c
index dfbe038..b35777e 100644 (file)
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 
 #include "machmode.h"
 #include "hard-reg-set.h"
@@ -130,6 +132,11 @@ struct allocno
   /* Set of hard registers that some later allocno has a preference for.  */
 
   HARD_REG_SET regs_someone_prefers;
+
+#ifdef STACK_REGS
+  /* Set to true if allocno can't be allocated in the stack register.  */
+  bool no_stack_reg;
+#endif
 };
 
 static struct allocno *allocno;
@@ -688,7 +695,7 @@ global_conflicts ()
                2. Y is live at some instruction on the path that
                   evaluates X.
 
-               3. Either X or Y is not evaluted on the path to P
+               3. Either X or Y is not evaluated on the path to P
                   (ie it is used uninitialized) and thus the
                   conflict can be ignored.
 
@@ -706,8 +713,14 @@ global_conflicts ()
            if (e->flags & EDGE_ABNORMAL)
              break;
          if (e != NULL)
-           for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
-             record_one_conflict (ax);
+           {
+             EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax,
+               {
+                 allocno[ax].no_stack_reg = 1;
+               });
+             for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
+               record_one_conflict (ax);
+           }
        }
 #endif
       }
@@ -1192,6 +1205,11 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
              /* Don't use a reg no good for this pseudo.  */
              && ! TEST_HARD_REG_BIT (used2, regno)
              && HARD_REGNO_MODE_OK (regno, mode)
+             /* The code below assumes that we need only a single
+                register, but the check of allocno[num].size above
+                was not enough.  Sometimes we need more than one
+                register for a single-word value.  */
+             && HARD_REGNO_NREGS (regno, mode) == 1
              && (allocno[num].calls_crossed == 0
                  || accept_call_clobbered
                  || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
@@ -1199,6 +1217,10 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
              && ! invalid_mode_change_p (regno, REGNO_REG_CLASS (regno),
                                          mode)
 #endif
+#ifdef STACK_REGS
+            && (!allocno[num].no_stack_reg
+                || regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
+#endif
              )
            {
              /* We explicitly evaluate the divide results into temporary
@@ -1358,15 +1380,9 @@ record_conflicts (allocno_vec, len)
      int *allocno_vec;
      int len;
 {
-  int num;
-  int ialloc_prod;
-
   while (--len >= 0)
-    {
-      num = allocno_vec[len];
-      ialloc_prod = num * allocno_row_words;
-      IOR_HARD_REG_SET (allocno[num].hard_reg_conflicts, hard_regs_live);
-    }
+    IOR_HARD_REG_SET (allocno[allocno_vec[len]].hard_reg_conflicts,
+                      hard_regs_live);
 }
 
 /* If CONFLICTP (i, j) is true, make sure CONFLICTP (j, i) is also true.  */