OSDN Git Service

* config/i386/sse.md ("*divv4sf3"): Rename to "sse_divv4sf3".
[pf3gnuchains/gcc-fork.git] / gcc / cfgexpand.c
index c8d446f..0a4e2ca 100644 (file)
@@ -5,7 +5,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -14,9 +14,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -513,7 +512,7 @@ dump_stack_var_partition (void)
          fputc ('\t', dump_file);
          print_generic_expr (dump_file, stack_vars[j].decl, dump_flags);
          fprintf (dump_file, ", offset " HOST_WIDE_INT_PRINT_DEC "\n",
-                  stack_vars[i].offset);
+                  stack_vars[j].offset);
        }
     }
 }
@@ -580,8 +579,11 @@ expand_stack_vars (bool (*pred) (tree))
       /* Create rtl for each variable based on their location within the
         partition.  */
       for (j = i; j != EOC; j = stack_vars[j].next)
-       expand_one_stack_var_at (stack_vars[j].decl,
-                                stack_vars[j].offset + offset);
+       {
+         gcc_assert (stack_vars[j].offset <= stack_vars[i].size);
+         expand_one_stack_var_at (stack_vars[j].decl,
+                                  stack_vars[j].offset + offset);
+       }
     }
 }
 
@@ -674,18 +676,10 @@ expand_one_register_var (tree var)
 
   /* Note if the object is a user variable.  */
   if (!DECL_ARTIFICIAL (var))
-    {
       mark_user_reg (x);
 
-      /* Trust user variables which have a pointer type to really
-        be pointers.  Do not trust compiler generated temporaries
-        as our type system is totally busted as it relates to
-        pointer arithmetic which translates into lots of compiler
-        generated objects with pointer types, but which are not really
-        pointers.  */
-      if (POINTER_TYPE_P (type))
-       mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (var))));
-    }
+  if (POINTER_TYPE_P (type))
+    mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (var))));
 }
 
 /* A subroutine of expand_one_var.  Called to assign rtl to a VAR_DECL that
@@ -1244,6 +1238,10 @@ maybe_dump_rtl_for_tree_stmt (tree stmt, rtx since)
     }
 }
 
+/* Maps the blocks that do not contain tree labels to rtx labels.  */
+
+static struct pointer_map_t *lab_rtx_for_bb;
+
 /* Returns the label_rtx expression for a label starting basic block BB.  */
 
 static rtx
@@ -1251,12 +1249,17 @@ label_rtx_for_bb (basic_block bb)
 {
   tree_stmt_iterator tsi;
   tree lab, lab_stmt;
+  void **elt;
 
   if (bb->flags & BB_RTL)
     return block_label (bb);
 
-  /* We cannot use tree_block_label, as we no longer have stmt annotations.
-     TODO -- avoid creating the new tree labels.  */
+  elt = pointer_map_contains (lab_rtx_for_bb, bb);
+  if (elt)
+    return (rtx) *elt;
+
+  /* Find the tree label if it is present.  */
+     
   for (tsi = tsi_start (bb_stmt_list (bb)); !tsi_end_p (tsi); tsi_next (&tsi))
     {
       lab_stmt = tsi_stmt (tsi);
@@ -1270,10 +1273,9 @@ label_rtx_for_bb (basic_block bb)
       return label_rtx (lab);
     }
 
-  lab = create_artificial_label ();
-  lab_stmt = build1 (LABEL_EXPR, void_type_node, lab);
-  tsi_link_before (&tsi, lab_stmt, TSI_NEW_STMT);
-  return label_rtx (lab);
+  elt = pointer_map_insert (lab_rtx_for_bb, bb);
+  *elt = gen_label_rtx ();
+  return (rtx) *elt;
 }
 
 /* A subroutine of expand_gimple_basic_block.  Expand one COND_EXPR.
@@ -1313,7 +1315,7 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
       add_reg_br_prob_note (last, true_edge->probability);
       maybe_dump_rtl_for_tree_stmt (stmt, last);
       if (true_edge->goto_locus)
-       set_curr_insn_source_location (*true_edge->goto_locus);
+       set_curr_insn_source_location (location_from_locus (true_edge->goto_locus));
       false_edge->flags |= EDGE_FALLTHRU;
       return NULL;
     }
@@ -1323,7 +1325,7 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
       add_reg_br_prob_note (last, false_edge->probability);
       maybe_dump_rtl_for_tree_stmt (stmt, last);
       if (false_edge->goto_locus)
-       set_curr_insn_source_location (*false_edge->goto_locus);
+       set_curr_insn_source_location (location_from_locus (false_edge->goto_locus));
       true_edge->flags |= EDGE_FALLTHRU;
       return NULL;
     }
@@ -1354,7 +1356,7 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
   maybe_dump_rtl_for_tree_stmt (stmt, last2);
 
   if (false_edge->goto_locus)
-    set_curr_insn_source_location (*false_edge->goto_locus);
+    set_curr_insn_source_location (location_from_locus (false_edge->goto_locus));
 
   return new_bb;
 }
@@ -1477,6 +1479,7 @@ expand_gimple_basic_block (basic_block bb)
   rtx note, last;
   edge e;
   edge_iterator ei;
+  void **elt;
 
   if (dump_file)
     {
@@ -1510,20 +1513,32 @@ expand_gimple_basic_block (basic_block bb)
 
   tsi = tsi_start (stmts);
   if (!tsi_end_p (tsi))
-    stmt = tsi_stmt (tsi);
+    {
+      stmt = tsi_stmt (tsi);
+      if (TREE_CODE (stmt) != LABEL_EXPR)
+       stmt = NULL_TREE;
+    }
+
+  elt = pointer_map_contains (lab_rtx_for_bb, bb);
 
-  if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
+  if (stmt || elt)
     {
       last = get_last_insn ();
 
-      expand_expr_stmt (stmt);
+      if (stmt)
+       {
+         expand_expr_stmt (stmt);
+         tsi_next (&tsi);
+       }
+
+      if (elt)
+       emit_label ((rtx) *elt);
 
       /* Java emits line number notes in the top of labels.
         ??? Make this go away once line number notes are obsoleted.  */
       BB_HEAD (bb) = NEXT_INSN (last);
       if (NOTE_P (BB_HEAD (bb)))
        BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb));
-      tsi_next (&tsi);
       note = emit_note_after (NOTE_INSN_BASIC_BLOCK, BB_HEAD (bb));
 
       maybe_dump_rtl_for_tree_stmt (stmt, last);
@@ -1608,7 +1623,7 @@ expand_gimple_basic_block (basic_block bb)
     {
       emit_jump (label_rtx_for_bb (e->dest));
       if (e->goto_locus)
-        set_curr_insn_source_location (*e->goto_locus);
+        set_curr_insn_source_location (location_from_locus (e->goto_locus));
       e->flags &= ~EDGE_FALLTHRU;
     }
 
@@ -1865,9 +1880,11 @@ tree_expand_cfg (void)
   if (warn_stack_protect)
     {
       if (current_function_calls_alloca)
-       warning (0, "not protecting local variables: variable length buffer");
+       warning (OPT_Wstack_protector, 
+                "not protecting local variables: variable length buffer");
       if (has_short_buffer && !cfun->stack_protect_guard)
-       warning (0, "not protecting function: no buffer at least %d bytes long",
+       warning (OPT_Wstack_protector, 
+                "not protecting function: no buffer at least %d bytes long",
                 (int) PARAM_VALUE (PARAM_SSP_BUFFER_SIZE));
     }
 
@@ -1896,8 +1913,10 @@ tree_expand_cfg (void)
   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
     e->flags &= ~EDGE_EXECUTABLE;
 
+  lab_rtx_for_bb = pointer_map_create ();
   FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
     bb = expand_gimple_basic_block (bb);
+  pointer_map_destroy (lab_rtx_for_bb);
 
   construct_exit_block ();
   set_curr_insn_block (DECL_INITIAL (current_function_decl));