Index: osprey/be/com/wssa_update.h
===================================================================
--- osprey/be/com/wssa_update.h	(revision 3501)
+++ osprey/be/com/wssa_update.h	(working copy)
@@ -151,6 +151,9 @@
   // rename inside bb and keep the versions of live out the same
   void Rename_BB(BB_NODE* bb);
   void Rename_BB_new_preg(BB_NODE* bb);
+
+  // delete all statements in bb and bb itself
+  void Delete_BB(BB_NODE* bb);
 };
 
 }; /* namespace WSSA */
Index: osprey/be/com/wssa_update.cxx
===================================================================
--- osprey/be/com/wssa_update.cxx	(revision 3501)
+++ osprey/be/com/wssa_update.cxx	(working copy)
@@ -1298,6 +1298,16 @@
   Is_True(old_ver == VER_INVALID ||
           wst_idx == _ssa->Get_ver_wst(old_ver), ("wst mismatch"));
 
+  if (WN_operator(wn) == OPR_BLOCK) {
+    for (WN* kid = WN_first(wn); kid != NULL; kid = WN_next(kid)) {
+      BOOL redef = ssa_rename_tree(kid, old_ver, new_ver);
+      if (redef) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
   // rename kids at first
   for (int i = 0; i < WN_kid_count(wn); i++) {
     BOOL redef = ssa_rename_tree(WN_kid(wn, i), old_ver, new_ver);
@@ -1913,6 +1923,54 @@
   rename.Finalize();
 }
 
+//===================================================================
+// Delete_BB
+//   delete all statements in bb
+//   delete BB itself
+//===================================================================
+void
+WSSA_UPDATER::Delete_BB(BB_NODE* bb) {
+  if (bb->Is_empty()) {
+    _cfg->Delete_node(bb);
+    return;
+  }
 
+  // keep the info of stmts
+  WN* first = bb->First_stmt();
+  WN* last = bb->Last_stmt();
+  Is_True(first != NULL && last != NULL,
+          ("TODO: extra stmt is not NULL"));
+  if (first != last) {
+    Is_True(WN_prev(last) == bb->Prev_stmt(last),
+            ("TODO: handle extra_stmt in bb"));
+  }
+
+  WN* block = _cfg->Get_parent_block(first);
+  Is_True(block != NULL && _cfg->Get_parent_block(last) == block,
+          ("unexpected parent block"));
+
+  // delete the node from CFG
+  _cfg->Delete_node(bb);
+
+  // remove the stmts from WHIRL tree
+  WN* prev = WN_prev(first);
+  WN* next = WN_next(last);
+  if (prev != NULL)
+    WN_next(prev) = next;
+  else
+    WN_first(block) = next;
+
+  if (next != NULL)
+    WN_prev(next) = prev;
+  else
+    WN_last(block) = prev;
+
+  for (WN* stmt = first; stmt != WN_next(last); ) {
+    WN* to_delete = stmt;
+    stmt = WN_next(stmt);
+    WN_DELETE_Tree(to_delete);
+  }
+}
+
 } /* namespace WSSA */
 
Index: osprey/be/com/wn_cfg_template.h
===================================================================
--- osprey/be/com/wn_cfg_template.h	(revision 3501)
+++ osprey/be/com/wn_cfg_template.h	(working copy)
@@ -445,18 +445,18 @@
 
   void Finalize() {
     BB_NODE* dummy_exit = ACTION_BASE::Get_dummy_exit();
-    for (typename _Tcfg::bb_iterator bit = ACTION_BASE::_cfg.BB_begin();
-         bit != ACTION_BASE::_cfg.BB_end();
+    for (typename _Tcfg::dfs_fwd_itrator bit = ACTION_BASE::_cfg.Dfs_fwd_begin();
+         bit != ACTION_BASE::_cfg.Dfs_fwd_end();
          ++bit) {
-      UINT32 bb_id = (*bit)->Get_id();
-      if ((*bit)->Get_preds_count() != _verify_preds[bb_id].size()) {
-        if (dummy_exit != (*bit)) { // we possibly add edges to dummy exit
+      UINT32 bb_id = bit->Get_id();
+      if (bit->Get_preds_count() != _verify_preds[bb_id].size()) {
+        if (dummy_exit != &(*bit)) { // we possibly add edges to dummy exit
           Is_True(FALSE, ("WCFG VERIFY: missing edge"));
         }
       }
-      if ((*bit)->Get_succs_count() != _verify_succs[bb_id].size()) {
-        if ((*bit)->Succ_pos(dummy_exit) == POS_INVALID ||
-            (*bit)->Get_succs_count() != _verify_succs[bb_id].size() + 1) {
+      if (bit->Get_succs_count() != _verify_succs[bb_id].size()) {
+        if (bit->Succ_pos(dummy_exit) == POS_INVALID ||
+            bit->Get_succs_count() != _verify_succs[bb_id].size() + 1) {
           Is_True(FALSE, ("WCFG VERIFY: missing edge"));
         }
       }
