OSDN Git Service

Fix sh-elf linker relaxation:
[pf3gnuchains/gcc-fork.git] / gcc / ssa.c
index a1dedfb..0a640ef 100644 (file)
--- a/gcc/ssa.c
+++ b/gcc/ssa.c
@@ -31,6 +31,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 
 #include "rtl.h"
 #include "expr.h"
@@ -78,7 +80,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    the same hard register in the same machine mode are in the same
    class.  */
 
-/* If conservative_reg_partition is non-zero, use a conservative
+/* If conservative_reg_partition is nonzero, use a conservative
    register partitioning algorithm (which leaves more regs after
    emerging from SSA) instead of the coalescing one.  This is being
    left in for a limited time only, as a debugging tool until the
@@ -124,6 +126,8 @@ struct ssa_rename_from_hash_table_data {
   partition reg_partition;
 };
 
+static rtx gen_sequence
+  PARAMS ((void));
 static void ssa_rename_from_initialize
   PARAMS ((void));
 static rtx ssa_rename_from_lookup
@@ -163,7 +167,7 @@ struct rename_context;
 static inline rtx * phi_alternative
   PARAMS ((rtx, int));
 static void compute_dominance_frontiers_1
-  PARAMS ((sbitmap *frontiers, int *idom, int bb, sbitmap done));
+  PARAMS ((sbitmap *frontiers, dominance_info idom, int bb, sbitmap done));
 static void find_evaluations_1
   PARAMS ((rtx dest, rtx set, void *data));
 static void find_evaluations
@@ -181,9 +185,9 @@ static void apply_delayed_renames
 static int rename_insn_1
   PARAMS ((rtx *ptr, void *data));
 static void rename_block
-  PARAMS ((int b, int *idom));
+  PARAMS ((int b, dominance_info dom));
 static void rename_registers
-  PARAMS ((int nregs, int *idom));
+  PARAMS ((int nregs, dominance_info idom));
 
 static inline int ephi_add_node
   PARAMS ((rtx reg, rtx *nodes, int *n_nodes));
@@ -418,7 +422,7 @@ phi_alternative (set, c)
 }
 
 /* Given the SET of a phi node, remove the alternative for predecessor
-   block C.  Return non-zero on success, or zero if no alternative is
+   block C.  Return nonzero on success, or zero if no alternative is
    found for C.  */
 
 int
@@ -430,7 +434,7 @@ remove_phi_alternative (set, block)
   int num_elem = GET_NUM_ELEM (phi_vec);
   int v, c;
 
-  c = block->sindex;
+  c = block->index;
   for (v = num_elem - 2; v >= 0; v -= 2)
     if (INTVAL (RTVEC_ELT (phi_vec, v + 1)) == c)
       {
@@ -475,11 +479,11 @@ find_evaluations (evals, nregs)
   sbitmap_vector_zero (evals, nregs);
   fe_evals = evals;
 
-  FOR_ALL_BB_REVERSE (bb)
+  FOR_EACH_BB_REVERSE (bb)
     {
       rtx p, last;
 
-      fe_current_bb = bb->sindex;
+      fe_current_bb = bb->index;
       p = bb->head;
       last = bb->end;
       while (1)
@@ -514,7 +518,7 @@ find_evaluations (evals, nregs)
 static void
 compute_dominance_frontiers_1 (frontiers, idom, bb, done)
      sbitmap *frontiers;
-     int *idom;
+     dominance_info idom;
      int bb;
      sbitmap done;
 {
@@ -528,27 +532,28 @@ compute_dominance_frontiers_1 (frontiers, idom, bb, done)
   /* Do the frontier of the children first.  Not all children in the
      dominator tree (blocks dominated by this one) are children in the
      CFG, so check all blocks.  */
-  FOR_ALL_BB (c)
-    if (idom[c->sindex] == bb && ! TEST_BIT (done, c->sindex))
-      compute_dominance_frontiers_1 (frontiers, idom, c->sindex, done);
+  FOR_EACH_BB (c)
+    if (get_immediate_dominator (idom, c)->index == bb
+       && ! TEST_BIT (done, c->index))
+      compute_dominance_frontiers_1 (frontiers, idom, c->index, done);
 
   /* Find blocks conforming to rule (1) above.  */
   for (e = b->succ; e; e = e->succ_next)
     {
       if (e->dest == EXIT_BLOCK_PTR)
        continue;
-      if (idom[e->dest->sindex] != bb)
-       SET_BIT (frontiers[bb], e->dest->sindex);
+      if (get_immediate_dominator (idom, e->dest)->index != bb)
+       SET_BIT (frontiers[bb], e->dest->index);
     }
 
   /* Find blocks conforming to rule (2).  */
-  FOR_ALL_BB (c)
-    if (idom[c->sindex] == bb)
+  FOR_EACH_BB (c)
+    if (get_immediate_dominator (idom, c)->index == bb)
       {
        int x;
-       EXECUTE_IF_SET_IN_SBITMAP (frontiers[c->sindex], 0, x,
+       EXECUTE_IF_SET_IN_SBITMAP (frontiers[c->index], 0, x,
          {
-           if (idom[x] != bb)
+           if (get_immediate_dominator (idom, BASIC_BLOCK (x))->index != bb)
              SET_BIT (frontiers[bb], x);
          });
       }
@@ -557,7 +562,7 @@ compute_dominance_frontiers_1 (frontiers, idom, bb, done)
 void
 compute_dominance_frontiers (frontiers, idom)
      sbitmap *frontiers;
-     int *idom;
+     dominance_info idom;
 {
   sbitmap done = sbitmap_alloc (last_basic_block);
   sbitmap_zero (done);
@@ -665,7 +670,7 @@ insert_phi_node (regno, bb)
     if (e->src != ENTRY_BLOCK_PTR)
       {
        RTVEC_ELT (vec, i + 0) = pc_rtx;
-       RTVEC_ELT (vec, i + 1) = GEN_INT (e->src->sindex);
+       RTVEC_ELT (vec, i + 1) = GEN_INT (e->src->index);
       }
 
   phi = gen_rtx_PHI (VOIDmode, vec);
@@ -701,7 +706,7 @@ insert_phi_nodes (idfs, evals, nregs)
 /* Rename the registers to conform to SSA.
 
    This is essentially the algorithm presented in Figure 7.8 of Morgan,
-   with a few changes to reduce pattern search time in favour of a bit
+   with a few changes to reduce pattern search time in favor of a bit
    more memory usage.  */
 
 /* One of these is created for each set.  It will live in a list local
@@ -916,18 +921,23 @@ rename_insn_1 (ptr, data)
       }
 
     case REG:
-      if (CONVERT_REGISTER_TO_SSA_P (REGNO (x)) &&
-         REGNO (x) < ssa_max_reg_num)
+      if (CONVERT_REGISTER_TO_SSA_P (REGNO (x))
+         && REGNO (x) < ssa_max_reg_num)
        {
          rtx new_reg = ssa_rename_to_lookup (x);
 
-         if (new_reg != NULL_RTX && new_reg != RENAME_NO_RTX)
+         if (new_reg != RENAME_NO_RTX && new_reg != NULL_RTX)
            {
              if (GET_MODE (x) != GET_MODE (new_reg))
                abort ();
              *ptr = new_reg;
            }
-         /* Else this is a use before a set.  Warn?  */
+         else
+           {
+             /* Undefined value used, rename it to a new pseudo register so
+                that it cannot conflict with an existing register.  */
+             *ptr = gen_reg_rtx (GET_MODE (x));
+           }
        }
       return -1;
 
@@ -966,10 +976,32 @@ rename_insn_1 (ptr, data)
     }
 }
 
+static rtx
+gen_sequence ()
+{
+  rtx first_insn = get_insns ();
+  rtx result;
+  rtx tem;
+  int i;
+  int len;
+
+  /* Count the insns in the chain.  */
+  len = 0;
+  for (tem = first_insn; tem; tem = NEXT_INSN (tem))
+    len++;
+
+  result = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (len));
+
+  for (i = 0, tem = first_insn; tem; tem = NEXT_INSN (tem), i++)
+    XVECEXP (result, 0, i) = tem;
+
+  return result;
+}
+
 static void
 rename_block (bb, idom)
      int bb;
-     int *idom;
+     dominance_info idom;
 {
   basic_block b = BASIC_BLOCK (bb);
   edge e;
@@ -1078,9 +1110,9 @@ rename_block (bb, idom)
   /* Step Three: Do the same to the children of this block in
      dominator order.  */
 
-  FOR_ALL_BB (c)
-    if (idom[c->sindex] == bb)
-      rename_block (c->sindex, idom);
+  FOR_EACH_BB (c)
+    if (get_immediate_dominator (idom, c)->index == bb)
+      rename_block (c->index, idom);
 
   /* Step Four: Update the sets to refer to their new register,
      and restore ssa_rename_to to its previous state.  */
@@ -1105,7 +1137,7 @@ rename_block (bb, idom)
 static void
 rename_registers (nregs, idom)
      int nregs;
-     int *idom;
+     dominance_info idom;
 {
   VARRAY_RTX_INIT (ssa_definition, nregs * 3, "ssa_definition");
   ssa_rename_from_initialize ();
@@ -1136,7 +1168,7 @@ convert_to_ssa ()
   sbitmap *idfs;
 
   /* Element I is the immediate dominator of block I.  */
-  int *idom;
+  dominance_info idom;
 
   int nregs;
 
@@ -1150,15 +1182,14 @@ convert_to_ssa ()
      dead code.  We'll let the SSA optimizers do that.  */
   life_analysis (get_insns (), NULL, 0);
 
-  idom = (int *) alloca (last_basic_block * sizeof (int));
-  memset ((void *) idom, -1, (size_t) last_basic_block * sizeof (int));
-  calculate_dominance_info (idom, NULL, CDI_DOMINATORS);
+  idom = calculate_dominance_info (CDI_DOMINATORS);
 
   if (rtl_dump_file)
     {
       fputs (";; Immediate Dominators:\n", rtl_dump_file);
-      FOR_ALL_BB (bb)
-       fprintf (rtl_dump_file, ";\t%3d = %3d\n", bb->sindex, idom[bb->sindex]);
+      FOR_EACH_BB (bb)
+       fprintf (rtl_dump_file, ";\t%3d = %3d\n", bb->index,
+                get_immediate_dominator (idom, bb)->index);
       fflush (rtl_dump_file);
     }
 
@@ -1209,6 +1240,7 @@ convert_to_ssa ()
   in_ssa_form = 1;
 
   reg_scan (get_insns (), max_reg_num (), 1);
+  free_dominance_info (idom);
 }
 
 /* REG is the representative temporary of its partition.  Add it to the
@@ -1384,7 +1416,7 @@ eliminate_phi (e, reg_partition)
   n_nodes = 0;
   for (; PHI_NODE_P (insn); insn = next_nonnote_insn (insn))
     {
-      rtx* preg = phi_alternative (PATTERN (insn), e->src->sindex);
+      rtx* preg = phi_alternative (PATTERN (insn), e->src->index);
       rtx tgt = SET_DEST (PATTERN (insn));
       rtx reg;
 
@@ -1441,12 +1473,12 @@ eliminate_phi (e, reg_partition)
        ephi_create (i, visited, pred, succ, nodes);
     }
 
-  insn = gen_sequence ();
+  insn = get_insns ();
   end_sequence ();
   insert_insn_on_edge (insn, e);
   if (rtl_dump_file)
     fprintf (rtl_dump_file, "Emitting copy on edge (%d,%d)\n",
-            e->src->sindex, e->dest->sindex);
+            e->src->index, e->dest->index);
 
   sbitmap_free (visited);
 out:
@@ -1466,7 +1498,7 @@ out:
      and C is the ith predecessor of B,
      then T0 and Ti must be equivalent.
 
-   Return non-zero iff any such cases were found for which the two
+   Return nonzero iff any such cases were found for which the two
    regs were not already in the same class.  */
 
 static int
@@ -1501,7 +1533,7 @@ make_regs_equivalent_over_bad_edges (bb, reg_partition)
       for (e = b->pred; e; e = e->pred_next)
        if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
          {
-           rtx *alt = phi_alternative (set, e->src->sindex);
+           rtx *alt = phi_alternative (set, e->src->index);
            int alt_regno;
 
            /* If there is no alternative corresponding to this edge,
@@ -1582,7 +1614,7 @@ make_equivalent_phi_alternatives_equivalent (bb, reg_partition)
              /* Scan over edges.  */
              for (e = b->pred; e; e = e->pred_next)
                {
-                 int pred_block = e->src->sindex;
+                 int pred_block = e->src->index;
                  /* Identify the phi alternatives from both phi
                     nodes corresponding to this edge.  */
                  rtx *alt = phi_alternative (set, pred_block);
@@ -1643,17 +1675,17 @@ compute_conservative_reg_partition ()
      be copied on abnormal critical edges are placed in the same
      partition.  This saves us from having to split abnormal critical
      edges.  */
-  FOR_ALL_BB_REVERSE (bb)
-    changed += make_regs_equivalent_over_bad_edges (bb->sindex, p);
-  
+  FOR_EACH_BB_REVERSE (bb)
+    changed += make_regs_equivalent_over_bad_edges (bb->index, p);
+
   /* Now we have to insure that corresponding arguments of phi nodes
      assigning to corresponding regs are equivalent.  Iterate until
      nothing changes.  */
   while (changed > 0)
     {
       changed = 0;
-      FOR_ALL_BB_REVERSE (bb)
-       changed += make_equivalent_phi_alternatives_equivalent (bb->sindex, p);
+      FOR_EACH_BB_REVERSE (bb)
+       changed += make_equivalent_phi_alternatives_equivalent (bb->index, p);
     }
 
   return p;
@@ -1796,7 +1828,7 @@ struct phi_coalesce_context
 
 /* Callback function for for_each_successor_phi.  If the set
    destination and the phi alternative regs do not conflict, place
-   them in the same paritition class.  DATA is a pointer to a
+   them in the same partition class.  DATA is a pointer to a
    phi_coalesce_context struct.  */
 
 static int
@@ -1861,8 +1893,8 @@ compute_coalesced_reg_partition ()
      be copied on abnormal critical edges are placed in the same
      partition.  This saves us from having to split abnormal critical
      edges (which can't be done).  */
-  FOR_ALL_BB_REVERSE (bb)
-    make_regs_equivalent_over_bad_edges (bb->sindex, p);
+  FOR_EACH_BB_REVERSE (bb)
+    make_regs_equivalent_over_bad_edges (bb->index, p);
 
   INIT_REG_SET (phi_set);
 
@@ -1884,10 +1916,10 @@ compute_coalesced_reg_partition ()
         blocks first, so that most frequently executed copies would
         be more likely to be removed by register coalescing.  But any
         order will generate correct, if non-optimal, results.  */
-      FOR_ALL_BB_REVERSE (bb)
+      FOR_EACH_BB_REVERSE (bb)
        {
          changed += coalesce_regs_in_copies (bb, p, conflicts);
-         changed += 
+         changed +=
            coalesce_regs_in_successor_phi_nodes (bb, p, conflicts);
        }
 
@@ -2096,7 +2128,7 @@ rename_equivalent_regs (reg_partition)
 {
   basic_block b;
 
-  FOR_ALL_BB_REVERSE (b)
+  FOR_EACH_BB_REVERSE (b)
     {
       rtx next = b->head;
       rtx last = b->end;
@@ -2166,7 +2198,7 @@ convert_from_ssa ()
   rename_equivalent_regs (reg_partition);
 
   /* Eliminate the PHI nodes.  */
-  FOR_ALL_BB_REVERSE (b)
+  FOR_EACH_BB_REVERSE (b)
     {
       edge e;
 
@@ -2178,7 +2210,7 @@ convert_from_ssa ()
   partition_delete (reg_partition);
 
   /* Actually delete the PHI nodes.  */
-  FOR_ALL_BB_REVERSE (bb)
+  FOR_EACH_BB_REVERSE (bb)
     {
       rtx insn = bb->head;
 
@@ -2212,7 +2244,7 @@ convert_from_ssa ()
   count_or_remove_death_notes (NULL, 1);
 
   /* Deallocate the data structures.  */
-  VARRAY_FREE (ssa_definition);
+  ssa_definition = 0;
   ssa_rename_from_free ();
 }
 
@@ -2222,7 +2254,7 @@ convert_from_ssa ()
    destination, the regno of the phi argument corresponding to BB,
    and DATA.
 
-   If FN ever returns non-zero, stops immediately and returns this
+   If FN ever returns nonzero, stops immediately and returns this
    value.  Otherwise, returns zero.  */
 
 int
@@ -2257,7 +2289,7 @@ for_each_successor_phi (bb, fn, data)
        {
          int result;
          rtx phi_set = PATTERN (insn);
-         rtx *alternative = phi_alternative (phi_set, bb->sindex);
+         rtx *alternative = phi_alternative (phi_set, bb->index);
          rtx phi_src;
 
          /* This phi function may not have an alternative