diff gcc/ddg.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
line wrap: on
line diff
--- a/gcc/ddg.c	Sun Aug 21 07:07:55 2011 +0900
+++ b/gcc/ddg.c	Fri Oct 27 22:46:09 2017 +0900
@@ -1,6 +1,5 @@
 /* DDG - Data Dependence Graph implementation.
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2004-2017 Free Software Foundation, Inc.
    Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.com>
 
 This file is part of GCC.
@@ -23,26 +22,13 @@
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "diagnostic-core.h"
+#include "backend.h"
 #include "rtl.h"
-#include "tm_p.h"
-#include "hard-reg-set.h"
-#include "regs.h"
-#include "function.h"
-#include "flags.h"
-#include "insn-config.h"
+#include "df.h"
 #include "insn-attr.h"
-#include "except.h"
-#include "recog.h"
 #include "sched-int.h"
-#include "target.h"
-#include "cfglayout.h"
-#include "cfgloop.h"
-#include "sbitmap.h"
-#include "expr.h"
-#include "bitmap.h"
 #include "ddg.h"
+#include "rtl-iter.h"
 
 #ifdef INSN_SCHEDULING
 
@@ -65,27 +51,24 @@
 static bool mem_ref_p;
 
 /* Auxiliary function for mem_read_insn_p.  */
-static int
-mark_mem_use (rtx *x, void *data ATTRIBUTE_UNUSED)
+static void
+mark_mem_use (rtx *x, void *)
 {
-  if (MEM_P (*x))
-    mem_ref_p = true;
-  return 0;
-}
-
-/* Auxiliary function for mem_read_insn_p.  */
-static void
-mark_mem_use_1 (rtx *x, void *data)
-{
-  for_each_rtx (x, mark_mem_use, data);
+  subrtx_iterator::array_type array;
+  FOR_EACH_SUBRTX (iter, array, *x, NONCONST)
+    if (MEM_P (*iter))
+      {
+	mem_ref_p = true;
+	break;
+      }
 }
 
 /* Returns nonzero if INSN reads from memory.  */
 static bool
-mem_read_insn_p (rtx insn)
+mem_read_insn_p (rtx_insn *insn)
 {
   mem_ref_p = false;
-  note_uses (&PATTERN (insn), mark_mem_use_1, NULL);
+  note_uses (&PATTERN (insn), mark_mem_use, NULL);
   return mem_ref_p;
 }
 
@@ -98,7 +81,7 @@
 
 /* Returns nonzero if INSN writes to memory.  */
 static bool
-mem_write_insn_p (rtx insn)
+mem_write_insn_p (rtx_insn *insn)
 {
   mem_ref_p = false;
   note_stores (PATTERN (insn), mark_mem_store, NULL);
@@ -140,11 +123,50 @@
 
 /* Returns nonzero if INSN reads to or writes from memory.  */
 static bool
-mem_access_insn_p (rtx insn)
+mem_access_insn_p (rtx_insn *insn)
 {
   return rtx_mem_access_p (PATTERN (insn));
 }
 
+/* Return true if DEF_INSN contains address being auto-inc or auto-dec
+   which is used in USE_INSN.  Otherwise return false.  The result is
+   being used to decide whether to remove the edge between def_insn and
+   use_insn when -fmodulo-sched-allow-regmoves is set.  This function
+   doesn't need to consider the specific address register; no reg_moves
+   will be allowed for any life range defined by def_insn and used
+   by use_insn, if use_insn uses an address register auto-inc'ed by
+   def_insn.  */
+bool
+autoinc_var_is_used_p (rtx_insn *def_insn, rtx_insn *use_insn)
+{
+  rtx note;
+
+  for (note = REG_NOTES (def_insn); note; note = XEXP (note, 1))
+    if (REG_NOTE_KIND (note) == REG_INC
+	&& reg_referenced_p (XEXP (note, 0), PATTERN (use_insn)))
+      return true;
+
+  return false;
+}
+
+/* Return true if one of the definitions in INSN has MODE_CC.  Otherwise
+   return false.  */
+static bool
+def_has_ccmode_p (rtx_insn *insn)
+{
+  df_ref def;
+
+  FOR_EACH_INSN_DEF (def, insn)
+    {
+      machine_mode mode = GET_MODE (DF_REF_REG (def));
+
+      if (GET_MODE_CLASS (mode) == MODE_CC)
+	return true;
+    }
+
+  return false;
+}
+
 /* Computes the dependence parameters (latency, distance etc.), creates
    a ddg_edge and adds it to the given DDG.  */
 static void
@@ -173,10 +195,16 @@
      compensate for that by generating reg-moves based on the life-range
      analysis.  The anti-deps that will be deleted are the ones which
      have true-deps edges in the opposite direction (in other words
-     the kernel has only one def of the relevant register).  TODO:
-     support the removal of all anti-deps edges, i.e. including those
+     the kernel has only one def of the relevant register).
+     If the address that is being auto-inc or auto-dec in DEST_NODE
+     is used in SRC_NODE then do not remove the edge to make sure
+     reg-moves will not be created for this address.  
+     TODO: support the removal of all anti-deps edges, i.e. including those
      whose register has multiple defs in the loop.  */
-  if (flag_modulo_sched_allow_regmoves && (t == ANTI_DEP && dt == REG_DEP))
+  if (flag_modulo_sched_allow_regmoves 
+      && (t == ANTI_DEP && dt == REG_DEP)
+      && !def_has_ccmode_p (dest_node->insn)
+      && !autoinc_var_is_used_p (dest_node->insn, src_node->insn))
     {
       rtx set;
 
@@ -250,27 +278,24 @@
   int regno = DF_REF_REGNO (last_def);
   struct df_link *r_use;
   int has_use_in_bb_p = false;
-  rtx def_insn = DF_REF_INSN (last_def);
+  rtx_insn *def_insn = DF_REF_INSN (last_def);
   ddg_node_ptr last_def_node = get_node_of_insn (g, def_insn);
   ddg_node_ptr use_node;
-#ifdef ENABLE_CHECKING
-  struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb);
-#endif
   df_ref first_def = df_bb_regno_first_def_find (g->bb, regno);
 
   gcc_assert (last_def_node);
   gcc_assert (first_def);
 
-#ifdef ENABLE_CHECKING
-  if (DF_REF_ID (last_def) != DF_REF_ID (first_def))
-    gcc_assert (!bitmap_bit_p (&bb_info->gen,
-			       DF_REF_ID (first_def)));
-#endif
+  if (flag_checking && DF_REF_ID (last_def) != DF_REF_ID (first_def))
+    {
+      struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb);
+      gcc_assert (!bitmap_bit_p (&bb_info->gen, DF_REF_ID (first_def)));
+    }
 
   /* Create inter-loop true dependences and anti dependences.  */
   for (r_use = DF_REF_CHAIN (last_def); r_use != NULL; r_use = r_use->next)
     {
-      rtx use_insn = DF_REF_INSN (r_use->ref);
+      rtx_insn *use_insn = DF_REF_INSN (r_use->ref);
 
       if (BLOCK_FOR_INSN (use_insn) != g->bb)
 	continue;
@@ -301,8 +326,16 @@
 
 	  gcc_assert (first_def_node);
 
+         /* Always create the edge if the use node is a branch in
+            order to prevent the creation of reg-moves.  
+            If the address that is being auto-inc or auto-dec in LAST_DEF
+            is used in USE_INSN then do not remove the edge to make sure
+            reg-moves will not be created for that address.  */
           if (DF_REF_ID (last_def) != DF_REF_ID (first_def)
-              || !flag_modulo_sched_allow_regmoves)
+              || !flag_modulo_sched_allow_regmoves
+	      || JUMP_P (use_node->insn)
+              || autoinc_var_is_used_p (DF_REF_INSN (last_def), use_insn)
+	      || def_has_ccmode_p (DF_REF_INSN (last_def)))
             create_ddg_dep_no_link (g, use_node, first_def_node, ANTI_DEP,
                                     REG_DEP, 1);
 
@@ -348,41 +381,52 @@
 }
 
 
-static int
-walk_mems_2 (rtx *x, rtx mem)
+/* Return true if two specified instructions have mem expr with conflict
+   alias sets.  */
+static bool
+insns_may_alias_p (rtx_insn *insn1, rtx_insn *insn2)
 {
-  if (MEM_P (*x))
+  subrtx_iterator::array_type array1;
+  subrtx_iterator::array_type array2;
+  FOR_EACH_SUBRTX (iter1, array1, PATTERN (insn1), NONCONST)
     {
-      if (may_alias_p (*x, mem))
-        return 1;
-
-      return -1;
+      const_rtx x1 = *iter1;
+      if (MEM_P (x1))
+	FOR_EACH_SUBRTX (iter2, array2, PATTERN (insn2), NONCONST)
+	  {
+	    const_rtx x2 = *iter2;
+	    if (MEM_P (x2) && may_alias_p (x2, x1))
+	      return true;
+	  }
     }
-  return 0;
+  return false;
 }
 
-static int
-walk_mems_1 (rtx *x, rtx *pat)
+/* 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 (MEM_P (*x))
-    {
-      /* Visit all MEMs in *PAT and check indepedence.  */
-      if (for_each_rtx (pat, (rtx_function) walk_mems_2, *x))
-        /* Indicate that dependence was determined and stop traversal.  */
-        return 1;
+
+  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;
 
-      return -1;
+  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);
     }
-  return 0;
-}
-
-/* Return 1 if two specified instructions have mem expr with conflict alias sets*/
-static int
-insns_may_alias_p (rtx insn1, rtx insn2)
-{
-  /* For each pair of MEMs in INSN1 and INSN2 check their independence.  */
-  return  for_each_rtx (&PATTERN (insn1), (rtx_function) walk_mems_1,
-			 &PATTERN (insn2));
+  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
@@ -429,7 +473,7 @@
   int i;
   /* Hold the dependency analysis state during dependency calculations.  */
   struct deps_desc tmp_deps;
-  rtx head, tail;
+  rtx_insn *head, *tail;
 
   /* Build the dependence information, using the sched_analyze function.  */
   init_deps_global ();
@@ -452,7 +496,15 @@
 
       FOR_EACH_DEP (dest_node->insn, SD_LIST_BACK, sd_it, dep)
 	{
-	  ddg_node_ptr src_node = get_node_of_insn (g, DEP_PRO (dep));
+	  rtx_insn *src_insn = DEP_PRO (dep);
+	  ddg_node_ptr src_node;
+
+	  /* Don't add dependencies on debug insns to non-debug insns
+	     to avoid codegen differences between -g and -g0.  */
+	  if (DEBUG_INSN_P (src_insn) && !DEBUG_INSN_P (dest_node->insn))
+	    continue;
+
+	  src_node = get_node_of_insn (g, src_insn);
 
 	  if (!src_node)
 	    continue;
@@ -472,10 +524,22 @@
 	      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.  */
-	      	  if (! TEST_BIT (dest_node->successors, j))
+		{
+		  /* Don't bother calculating inter-loop dep if an intra-loop dep
+		     already exists.  */
+	      	  if (! bitmap_bit_p (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
+		      && !bitmap_bit_p (dest_node->predecessors, j))
+		    add_intra_loop_mem_dep (g, j_node, dest_node);
+		}
             }
         }
     }
@@ -496,7 +560,7 @@
 create_ddg (basic_block bb, int closing_branch_deps)
 {
   ddg_ptr g;
-  rtx insn, first_note;
+  rtx_insn *insn, *first_note;
   int i;
   int num_nodes = 0;
 
@@ -536,7 +600,7 @@
   g->nodes = (ddg_node_ptr) xcalloc (num_nodes, sizeof (struct ddg_node));
   g->closing_branch = NULL;
   i = 0;
-  first_note = NULL_RTX;
+  first_note = NULL;
   for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
        insn = NEXT_INSN (insn))
     {
@@ -561,12 +625,12 @@
 
       g->nodes[i].cuid = i;
       g->nodes[i].successors = sbitmap_alloc (num_nodes);
-      sbitmap_zero (g->nodes[i].successors);
+      bitmap_clear (g->nodes[i].successors);
       g->nodes[i].predecessors = sbitmap_alloc (num_nodes);
-      sbitmap_zero (g->nodes[i].predecessors);
+      bitmap_clear (g->nodes[i].predecessors);
       g->nodes[i].first_note = (first_note ? first_note : insn);
       g->nodes[i++].insn = insn;
-      first_note = NULL_RTX;
+      first_note = NULL;
     }
 
   /* We must have found a branch in DDG.  */
@@ -654,7 +718,7 @@
 }
 
 /* Print the given DDG in VCG format.  */
-void
+DEBUG_FUNCTION void
 vcg_print_ddg (FILE *file, ddg_ptr g)
 {
   int src_cuid;
@@ -702,7 +766,7 @@
   for (i = 0; i < sccs->num_sccs; i++)
     {
       fprintf (file, "SCC number: %d\n", i);
-      EXECUTE_IF_SET_IN_SBITMAP (sccs->sccs[i]->nodes, 0, u, sbi)
+      EXECUTE_IF_SET_IN_BITMAP (sccs->sccs[i]->nodes, 0, u, sbi)
       {
         fprintf (file, "insn num %d\n", u);
         print_rtl_single (file, g->nodes[u].insn);
@@ -739,8 +803,8 @@
   /* Should have allocated the sbitmaps.  */
   gcc_assert (src->successors && dest->predecessors);
 
-  SET_BIT (src->successors, dest->cuid);
-  SET_BIT (dest->predecessors, src->cuid);
+  bitmap_set_bit (src->successors, dest->cuid);
+  bitmap_set_bit (dest->predecessors, src->cuid);
   e->next_in = dest->in;
   dest->in = e;
   e->next_out = src->out;
@@ -791,16 +855,16 @@
   scc->backarcs = NULL;
   scc->num_backarcs = 0;
   scc->nodes = sbitmap_alloc (g->num_nodes);
-  sbitmap_copy (scc->nodes, nodes);
+  bitmap_copy (scc->nodes, nodes);
 
   /* Mark the backarcs that belong to this SCC.  */
-  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
+  EXECUTE_IF_SET_IN_BITMAP (nodes, 0, u, sbi)
     {
       ddg_edge_ptr e;
       ddg_node_ptr n = &g->nodes[u];
 
       for (e = n->out; e; e = e->next_out)
-	if (TEST_BIT (nodes, e->dest->cuid))
+	if (bitmap_bit_p (nodes, e->dest->cuid))
 	  {
 	    e->aux.count = IN_SCC;
 	    if (e->distance > 0)
@@ -859,7 +923,7 @@
 
 /* Given the instruction INSN return the node that represents it.  */
 ddg_node_ptr
-get_node_of_insn (ddg_ptr g, rtx insn)
+get_node_of_insn (ddg_ptr g, rtx_insn *insn)
 {
   int i;
 
@@ -878,14 +942,14 @@
   unsigned int i = 0;
   sbitmap_iterator sbi;
 
-  EXECUTE_IF_SET_IN_SBITMAP (ops, 0, i, sbi)
+  EXECUTE_IF_SET_IN_BITMAP (ops, 0, i, sbi)
     {
       const sbitmap node_succ = NODE_SUCCESSORS (&g->nodes[i]);
-      sbitmap_a_or_b (succ, succ, node_succ);
+      bitmap_ior (succ, succ, node_succ);
     };
 
   /* We want those that are not in ops.  */
-  sbitmap_difference (succ, succ, ops);
+  bitmap_and_compl (succ, succ, ops);
 }
 
 /* Given a set OPS of nodes in the DDG, find the set of their predecessors
@@ -897,14 +961,14 @@
   unsigned int i = 0;
   sbitmap_iterator sbi;
 
-  EXECUTE_IF_SET_IN_SBITMAP (ops, 0, i, sbi)
+  EXECUTE_IF_SET_IN_BITMAP (ops, 0, i, sbi)
     {
       const sbitmap node_preds = NODE_PREDECESSORS (&g->nodes[i]);
-      sbitmap_a_or_b (preds, preds, node_preds);
+      bitmap_ior (preds, preds, node_preds);
     };
 
   /* We want those that are not in ops.  */
-  sbitmap_difference (preds, preds, ops);
+  bitmap_and_compl (preds, preds, ops);
 }
 
 
@@ -927,27 +991,24 @@
 	 (int (*) (const void *, const void *)) compare_sccs);
 }
 
-#ifdef ENABLE_CHECKING
 /* Check that every node in SCCS belongs to exactly one strongly connected
    component and that no element of SCCS is empty.  */
 static void
 check_sccs (ddg_all_sccs_ptr sccs, int num_nodes)
 {
   int i = 0;
-  sbitmap tmp = sbitmap_alloc (num_nodes);
+  auto_sbitmap tmp (num_nodes);
 
-  sbitmap_zero (tmp);
+  bitmap_clear (tmp);
   for (i = 0; i < sccs->num_sccs; i++)
     {
-      gcc_assert (!sbitmap_empty_p (sccs->sccs[i]->nodes));
+      gcc_assert (!bitmap_empty_p (sccs->sccs[i]->nodes));
       /* Verify that every node in sccs is in exactly one strongly
          connected component.  */
-      gcc_assert (!sbitmap_any_common_bits (tmp, sccs->sccs[i]->nodes));
-      sbitmap_a_or_b (tmp, tmp, sccs->sccs[i]->nodes);
+      gcc_assert (!bitmap_intersect_p (tmp, sccs->sccs[i]->nodes));
+      bitmap_ior (tmp, tmp, sccs->sccs[i]->nodes);
     }
-  sbitmap_free (tmp);
 }
-#endif
 
 /* Perform the Strongly Connected Components decomposing algorithm on the
    DDG and return DDG_ALL_SCCS structure that contains them.  */
@@ -956,9 +1017,9 @@
 {
   int i;
   int num_nodes = g->num_nodes;
-  sbitmap from = sbitmap_alloc (num_nodes);
-  sbitmap to = sbitmap_alloc (num_nodes);
-  sbitmap scc_nodes = sbitmap_alloc (num_nodes);
+  auto_sbitmap from (num_nodes);
+  auto_sbitmap to (num_nodes);
+  auto_sbitmap scc_nodes (num_nodes);
   ddg_all_sccs_ptr sccs = (ddg_all_sccs_ptr)
 			  xmalloc (sizeof (struct ddg_all_sccs));
 
@@ -977,11 +1038,11 @@
       if (backarc->aux.count == IN_SCC)
 	continue;
 
-      sbitmap_zero (scc_nodes);
-      sbitmap_zero (from);
-      sbitmap_zero (to);
-      SET_BIT (from, dest->cuid);
-      SET_BIT (to, src->cuid);
+      bitmap_clear (scc_nodes);
+      bitmap_clear (from);
+      bitmap_clear (to);
+      bitmap_set_bit (from, dest->cuid);
+      bitmap_set_bit (to, src->cuid);
 
       if (find_nodes_on_paths (scc_nodes, g, from, to))
 	{
@@ -990,12 +1051,10 @@
 	}
     }
   order_sccs (sccs);
-  sbitmap_free (from);
-  sbitmap_free (to);
-  sbitmap_free (scc_nodes);
-#ifdef ENABLE_CHECKING
-  check_sccs (sccs, num_nodes);
-#endif
+
+  if (flag_checking)
+    check_sccs (sccs, num_nodes);
+
   return sccs;
 }
 
@@ -1011,6 +1070,7 @@
   for (i = 0; i < all_sccs->num_sccs; i++)
     free_scc (all_sccs->sccs[i]);
 
+  free (all_sccs->sccs);
   free (all_sccs);
 }
 
@@ -1021,27 +1081,26 @@
 int
 find_nodes_on_paths (sbitmap result, ddg_ptr g, sbitmap from, sbitmap to)
 {
-  int answer;
   int change;
   unsigned int u = 0;
   int num_nodes = g->num_nodes;
   sbitmap_iterator sbi;
 
-  sbitmap workset = sbitmap_alloc (num_nodes);
-  sbitmap reachable_from = sbitmap_alloc (num_nodes);
-  sbitmap reach_to = sbitmap_alloc (num_nodes);
-  sbitmap tmp = sbitmap_alloc (num_nodes);
+  auto_sbitmap workset (num_nodes);
+  auto_sbitmap reachable_from (num_nodes);
+  auto_sbitmap reach_to (num_nodes);
+  auto_sbitmap tmp (num_nodes);
 
-  sbitmap_copy (reachable_from, from);
-  sbitmap_copy (tmp, from);
+  bitmap_copy (reachable_from, from);
+  bitmap_copy (tmp, from);
 
   change = 1;
   while (change)
     {
       change = 0;
-      sbitmap_copy (workset, tmp);
-      sbitmap_zero (tmp);
-      EXECUTE_IF_SET_IN_SBITMAP (workset, 0, u, sbi)
+      bitmap_copy (workset, tmp);
+      bitmap_clear (tmp);
+      EXECUTE_IF_SET_IN_BITMAP (workset, 0, u, sbi)
 	{
 	  ddg_edge_ptr e;
 	  ddg_node_ptr u_node = &g->nodes[u];
@@ -1051,26 +1110,26 @@
 	      ddg_node_ptr v_node = e->dest;
 	      int v = v_node->cuid;
 
-	      if (!TEST_BIT (reachable_from, v))
+	      if (!bitmap_bit_p (reachable_from, v))
 		{
-		  SET_BIT (reachable_from, v);
-		  SET_BIT (tmp, v);
+		  bitmap_set_bit (reachable_from, v);
+		  bitmap_set_bit (tmp, v);
 		  change = 1;
 		}
 	    }
 	}
     }
 
-  sbitmap_copy (reach_to, to);
-  sbitmap_copy (tmp, to);
+  bitmap_copy (reach_to, to);
+  bitmap_copy (tmp, to);
 
   change = 1;
   while (change)
     {
       change = 0;
-      sbitmap_copy (workset, tmp);
-      sbitmap_zero (tmp);
-      EXECUTE_IF_SET_IN_SBITMAP (workset, 0, u, sbi)
+      bitmap_copy (workset, tmp);
+      bitmap_clear (tmp);
+      EXECUTE_IF_SET_IN_BITMAP (workset, 0, u, sbi)
 	{
 	  ddg_edge_ptr e;
 	  ddg_node_ptr u_node = &g->nodes[u];
@@ -1080,22 +1139,17 @@
 	      ddg_node_ptr v_node = e->src;
 	      int v = v_node->cuid;
 
-	      if (!TEST_BIT (reach_to, v))
+	      if (!bitmap_bit_p (reach_to, v))
 		{
-		  SET_BIT (reach_to, v);
-		  SET_BIT (tmp, v);
+		  bitmap_set_bit (reach_to, v);
+		  bitmap_set_bit (tmp, v);
 		  change = 1;
 		}
 	    }
 	}
     }
 
-  answer = sbitmap_a_and_b_cg (result, reachable_from, reach_to);
-  sbitmap_free (workset);
-  sbitmap_free (reachable_from);
-  sbitmap_free (reach_to);
-  sbitmap_free (tmp);
-  return answer;
+  return bitmap_and (result, reachable_from, reach_to);
 }
 
 
@@ -1114,12 +1168,12 @@
       ddg_node_ptr v_node = e->dest;
       int v = v_node->cuid;
 
-      if (TEST_BIT (nodes, v)
+      if (bitmap_bit_p (nodes, v)
 	  && (e->distance == 0)
 	  && (v_node->aux.count < u_node->aux.count + e->latency))
 	{
 	  v_node->aux.count = u_node->aux.count + e->latency;
-	  SET_BIT (tmp, v);
+	  bitmap_set_bit (tmp, v);
 	  result = 1;
 	}
     }
@@ -1135,10 +1189,9 @@
   int i;
   unsigned int u = 0;
   int change = 1;
-  int result;
   int num_nodes = g->num_nodes;
-  sbitmap workset = sbitmap_alloc (num_nodes);
-  sbitmap tmp = sbitmap_alloc (num_nodes);
+  auto_sbitmap workset (num_nodes);
+  auto_sbitmap tmp (num_nodes);
 
 
   /* Data will hold the distance of the longest path found so far from
@@ -1147,27 +1200,24 @@
     g->nodes[i].aux.count = -1;
   g->nodes[src].aux.count = 0;
 
-  sbitmap_zero (tmp);
-  SET_BIT (tmp, src);
+  bitmap_clear (tmp);
+  bitmap_set_bit (tmp, src);
 
   while (change)
     {
       sbitmap_iterator sbi;
 
       change = 0;
-      sbitmap_copy (workset, tmp);
-      sbitmap_zero (tmp);
-      EXECUTE_IF_SET_IN_SBITMAP (workset, 0, u, sbi)
+      bitmap_copy (workset, tmp);
+      bitmap_clear (tmp);
+      EXECUTE_IF_SET_IN_BITMAP (workset, 0, u, sbi)
 	{
 	  ddg_node_ptr u_node = &g->nodes[u];
 
 	  change |= update_dist_to_successors (u_node, nodes, tmp);
 	}
     }
-  result = g->nodes[dest].aux.count;
-  sbitmap_free (workset);
-  sbitmap_free (tmp);
-  return result;
+  return g->nodes[dest].aux.count;
 }
 
 #endif /* INSN_SCHEDULING */