OSDN Git Service

* class.c (build_vcall_offset_vtbl_entries): Do not add vcall
[pf3gnuchains/gcc-fork.git] / gcc / cfgexpand.c
index 941cdad..d0a560e 100644 (file)
@@ -45,7 +45,7 @@ Boston, MA 02110-1301, USA.  */
    ??? We really ought to pass the probability down to RTL expanders and let it
    re-distribute it when the conditional expands into multiple conditionals.
    This is however difficult to do.  */
-static void
+void
 add_reg_br_prob_note (rtx last, int probability)
 {
   if (profile_status == PROFILE_ABSENT)
@@ -58,7 +58,9 @@ add_reg_br_prob_note (rtx last, int probability)
        if (!any_condjump_p (last)
            || !JUMP_P (NEXT_INSN (last))
            || !simplejump_p (NEXT_INSN (last))
+           || !NEXT_INSN (NEXT_INSN (last))
            || !BARRIER_P (NEXT_INSN (NEXT_INSN (last)))
+           || !NEXT_INSN (NEXT_INSN (NEXT_INSN (last)))
            || !LABEL_P (NEXT_INSN (NEXT_INSN (NEXT_INSN (last))))
            || NEXT_INSN (NEXT_INSN (NEXT_INSN (NEXT_INSN (last)))))
          goto failed;
@@ -348,11 +350,19 @@ stack_var_size_cmp (const void *a, const void *b)
 {
   HOST_WIDE_INT sa = stack_vars[*(const size_t *)a].size;
   HOST_WIDE_INT sb = stack_vars[*(const size_t *)b].size;
+  unsigned int uida = DECL_UID (stack_vars[*(const size_t *)a].decl);
+  unsigned int uidb = DECL_UID (stack_vars[*(const size_t *)b].decl);
 
   if (sa < sb)
     return -1;
   if (sa > sb)
     return 1;
+  /* For stack variables of the same size use the uid of the decl
+     to make the sort stable.  */
+  if (uida < uidb)
+    return -1;
+  if (uida > uidb)
+    return 1;
   return 0;
 }
 
@@ -754,7 +764,12 @@ expand_used_vars_for_block (tree block, bool toplevel)
 
   /* Expand all variables at this level.  */
   for (t = BLOCK_VARS (block); t ; t = TREE_CHAIN (t))
-    if (TREE_USED (t))
+    if (TREE_USED (t)
+       /* Force local static variables to be output when marked by
+          used attribute.  For unit-at-a-time, cgraph code already takes
+          care of this.  */
+       || (!flag_unit_at_a_time && TREE_STATIC (t)
+           && DECL_PRESERVE_P (t)))
       expand_one_var (t, toplevel);
 
   this_sv_num = stack_vars_num;
@@ -1450,6 +1465,7 @@ construct_exit_block (void)
   edge e, e2;
   unsigned ix;
   edge_iterator ei;
+  rtx orig_end = BB_END (EXIT_BLOCK_PTR->prev_bb);
 
   /* Make sure the locus is set to the end of the function, so that
      epilogue line numbers and warnings are set properly.  */
@@ -1469,6 +1485,9 @@ construct_exit_block (void)
   end = get_last_insn ();
   if (head == end)
     return;
+  /* While emitting the function end we could move end of the last basic block.
+   */
+  BB_END (EXIT_BLOCK_PTR->prev_bb) = orig_end;
   while (NEXT_INSN (head) && NOTE_P (NEXT_INSN (head)))
     head = NEXT_INSN (head);
   exit_block = create_basic_block (NEXT_INSN (head), end,
@@ -1580,6 +1599,8 @@ tree_expand_cfg (void)
 {
   basic_block bb, init_block;
   sbitmap blocks;
+  edge_iterator ei;
+  edge e;
 
   /* Some backends want to know that we are expanding to RTL.  */
   currently_expanding_to_rtl = 1;
@@ -1623,6 +1644,11 @@ tree_expand_cfg (void)
 
   init_block = construct_init_block ();
 
+  /* Clear EDGE_EXECUTABLE on the entry edge(s).  It is cleaned from the
+     remaining edges in expand_gimple_basic_block.  */
+  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
+    e->flags &= ~EDGE_EXECUTABLE;
+
   FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
     bb = expand_gimple_basic_block (bb);