OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / ddg.c
index d7b093b..d06bdbb 100644 (file)
--- a/gcc/ddg.c
+++ b/gcc/ddg.c
@@ -1,5 +1,5 @@
 /* DDG - Data Dependence Graph implementation.
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.com>
 
@@ -25,7 +25,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "diagnostic-core.h"
-#include "toplev.h"
 #include "rtl.h"
 #include "tm_p.h"
 #include "hard-reg-set.h"
@@ -198,6 +197,11 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node,
         }
     }
 
+  /* If a true dep edge enters the branch create an anti edge in the
+     opposite direction to prevent the creation of reg-moves.  */
+  if ((DEP_TYPE (link) == REG_DEP_TRUE) && JUMP_P (dest_node->insn))
+    create_ddg_dep_no_link (g, dest_node, src_node, ANTI_DEP, REG_DEP, 1);
+
    latency = dep_cost (link);
    e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance);
    add_edge_to_ddg (g, e);
@@ -262,9 +266,11 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
   gcc_assert (last_def_node);
   gcc_assert (first_def);
 
+#ifdef ENABLE_CHECKING
   if (DF_REF_ID (last_def) != DF_REF_ID (first_def))
-    gcc_checking_assert (!bitmap_bit_p (&bb_info->gen,
-                                       DF_REF_ID (first_def)));
+    gcc_assert (!bitmap_bit_p (&bb_info->gen,
+                              DF_REF_ID (first_def)));
+#endif
 
   /* Create inter-loop true dependences and anti dependences.  */
   for (r_use = DF_REF_CHAIN (last_def); r_use != NULL; r_use = r_use->next)
@@ -384,6 +390,33 @@ insns_may_alias_p (rtx insn1, rtx insn2)
                         &PATTERN (insn2));
 }
 
+/* Given two nodes, analyze their RTL insns and add intra-loop mem deps
+   to ddg G.  */
+static void
+add_intra_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
+{
+
+  if ((from->cuid == to->cuid)
+      || !insns_may_alias_p (from->insn, to->insn))
+    /* Do not create edge if memory references have disjoint alias sets
+       or 'to' and 'from' are the same instruction.  */
+    return;
+
+  if (mem_write_insn_p (from->insn))
+    {
+      if (mem_read_insn_p (to->insn))
+       create_ddg_dep_no_link (g, from, to,
+                               DEBUG_INSN_P (to->insn)
+                               ? ANTI_DEP : TRUE_DEP, MEM_DEP, 0);
+      else
+       create_ddg_dep_no_link (g, from, to,
+                               DEBUG_INSN_P (to->insn)
+                               ? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 0);
+    }
+  else if (!mem_read_insn_p (to->insn))
+    create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 0);
+}
+
 /* Given two nodes, analyze their RTL insns and add inter-loop mem deps
    to ddg G.  */
 static void
@@ -471,10 +504,22 @@ build_intra_loop_deps (ddg_ptr g)
              if (DEBUG_INSN_P (j_node->insn))
                continue;
              if (mem_access_insn_p (j_node->insn))
-               /* Don't bother calculating inter-loop dep if an intra-loop dep
-                  already exists.  */
+               {
+                 /* Don't bother calculating inter-loop dep if an intra-loop dep
+                    already exists.  */
                  if (! TEST_BIT (dest_node->successors, j))
                    add_inter_loop_mem_dep (g, dest_node, j_node);
+                 /* If -fmodulo-sched-allow-regmoves
+                    is set certain anti-dep edges are not created.
+                    It might be that these anti-dep edges are on the
+                    path from one memory instruction to another such that
+                    removing these edges could cause a violation of the
+                    memory dependencies.  Thus we add intra edges between
+                    every two memory instructions in this case.  */
+                 if (flag_modulo_sched_allow_regmoves
+                     && !TEST_BIT (dest_node->predecessors, j))
+                   add_intra_loop_mem_dep (g, j_node, dest_node);
+               }
             }
         }
     }
@@ -1010,6 +1055,7 @@ free_ddg_all_sccs (ddg_all_sccs_ptr all_sccs)
   for (i = 0; i < all_sccs->num_sccs; i++)
     free_scc (all_sccs->sccs[i]);
 
+  free (all_sccs->sccs);
   free (all_sccs);
 }