OSDN Git Service

PR tree-optimization/16688
[pf3gnuchains/gcc-fork.git] / gcc / cfgloopanal.c
index 9b3ffa0..074574f 100644 (file)
@@ -431,9 +431,9 @@ expected_loop_iterations (const struct loop *loop)
          count_in += e->count;
 
       if (count_in == 0)
-       return 0;
-
-      expected = (count_latch + count_in - 1) / count_in;
+        expected = count_latch * 2;
+      else
+        expected = (count_latch + count_in - 1) / count_in;
 
       /* Avoid overflows.  */
       return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);
@@ -452,8 +452,114 @@ expected_loop_iterations (const struct loop *loop)
          freq_in += EDGE_FREQUENCY (e);
 
       if (freq_in == 0)
-       return 0;
+       return freq_latch * 2;
 
       return (freq_latch + freq_in - 1) / freq_in;
     }
 }
+
+/* Returns the maximum level of nesting of subloops of LOOP.  */
+
+unsigned
+get_loop_level (const struct loop *loop)
+{
+  const struct loop *ploop;
+  unsigned mx = 0, l;
+
+  for (ploop = loop->inner; ploop; ploop = ploop->next)
+    {
+      l = get_loop_level (ploop);
+      if (l >= mx)
+       mx = l + 1;
+    }
+  return mx;
+}
+
+/* Returns estimate on cost of computing SEQ.  */
+
+static unsigned
+seq_cost (rtx seq)
+{
+  unsigned cost = 0;
+  rtx set;
+
+  for (; seq; seq = NEXT_INSN (seq))
+    {
+      set = single_set (seq);
+      if (set)
+       cost += rtx_cost (set, SET);
+      else
+       cost++;
+    }
+
+  return cost;
+}
+
+/* The properties of the target.  */
+
+static unsigned avail_regs;    /* Number of available registers.  */
+static unsigned res_regs;      /* Number of reserved registers.  */
+static unsigned small_cost;    /* The cost for register when there is a free one.  */
+static unsigned pres_cost;     /* The cost for register when there are not too many
+                                  free ones.  */
+static unsigned spill_cost;    /* The cost for register when we need to spill.  */
+
+/* Initialize the constants for computing set costs.  */
+
+void
+init_set_costs (void)
+{
+  rtx seq;
+  rtx reg1 = gen_raw_REG (SImode, FIRST_PSEUDO_REGISTER);
+  rtx reg2 = gen_raw_REG (SImode, FIRST_PSEUDO_REGISTER + 1);
+  rtx addr = gen_raw_REG (Pmode, FIRST_PSEUDO_REGISTER + 2);
+  rtx mem = validize_mem (gen_rtx_MEM (SImode, addr));
+  unsigned i;
+
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
+       && !fixed_regs[i])
+      avail_regs++;
+
+  res_regs = 3;
+
+  /* These are really just heuristic values.  */
+  
+  start_sequence ();
+  emit_move_insn (reg1, reg2);
+  seq = get_insns ();
+  end_sequence ();
+  small_cost = seq_cost (seq);
+  pres_cost = 2 * small_cost;
+
+  start_sequence ();
+  emit_move_insn (mem, reg1);
+  emit_move_insn (reg2, mem);
+  seq = get_insns ();
+  end_sequence ();
+  spill_cost = seq_cost (seq);
+}
+
+/* Calculates cost for having SIZE new loop global variables.  REGS_USED is the
+   number of global registers used in loop.  N_USES is the number of relevant
+   variable uses.  */
+
+unsigned
+global_cost_for_size (unsigned size, unsigned regs_used, unsigned n_uses)
+{
+  unsigned regs_needed = regs_used + size;
+  unsigned cost = 0;
+
+  if (regs_needed + res_regs <= avail_regs)
+    cost += small_cost * size;
+  else if (regs_needed <= avail_regs)
+    cost += pres_cost * size;
+  else
+    {
+      cost += pres_cost * size;
+      cost += spill_cost * n_uses * (regs_needed - avail_regs) / regs_needed;
+    }
+
+  return cost;
+}
+