Author: laijx Date: 2011-03-05 01:19:38 -0500 (Sat, 05 Mar 2011) New Revision: 3506
Modified: trunk/osprey/be/com/cfg_base.h trunk/osprey/be/com/wn_cfg_template.h trunk/osprey/be/com/wssa_update.cxx trunk/osprey/be/com/wssa_update.h Log: Fixed bugs in WHIRL cfg and ssa: 1. in WSSA_UPDATER::ssa_rename_tree(), BLOCK is not handled in previous code. 2. in WN_CFG_VERIFY_ACTION::Finalize(), dfs_iterator is used instead of BB_iterator because some of BB is deleted and BB_iterator will also returns those deleted bb. Rename the dfs_itrator to dfs_iterator. 3. in wn_cfg_template.h, the kid count of SWITCH/COMPGOTO can be 2 or 3. The default target is valid only if the kid count is 3. 4. in wn_cfg_template.h, in processing OPR_IF, OPR_DO_WHIRL, OPR_WHILE_DO, the _current_bb is not set correctly. and an enhancement: 1. in wssa_update.h/cxx, Delete_BB is added to WSSA_UPDATER to support delete a BB from CFG, as well as its statements from WHIRL tree. CR by Mei Ye. Modified: trunk/osprey/be/com/cfg_base.h =================================================================== --- trunk/osprey/be/com/cfg_base.h 2011-03-04 17:27:33 UTC (rev 3505) +++ trunk/osprey/be/com/cfg_base.h 2011-03-05 06:19:38 UTC (rev 3506) @@ -796,8 +796,8 @@ typedef BB_NODE_BASE<_Tstmtcontainer> BB_NODE; typedef typename BB_NODE::BB_LIST BB_LIST; - typedef DFS_ITERATOR<BB_NODE, TRUE> dfs_fwd_itrator; - typedef DFS_ITERATOR<BB_NODE, FALSE> dfs_bwd_itrator; + typedef DFS_ITERATOR<BB_NODE, TRUE> dfs_fwd_iterator; + typedef DFS_ITERATOR<BB_NODE, FALSE> dfs_bwd_iterator; typedef typename _Tnodecontainer::iterator bb_iterator; typedef typename _Tnodecontainer::const_iterator const_bb_iterator; @@ -892,10 +892,10 @@ } // DFS iterators - dfs_fwd_itrator Dfs_fwd_begin() { dfs_fwd_itrator it(Get_dummy_entry(), Get_max_id()); return it; } - dfs_fwd_itrator Dfs_fwd_end() { dfs_fwd_itrator it(NULL, 0); return it; } - dfs_bwd_itrator Dfs_bwd_begin() { dfs_bwd_itrator it(Get_dummy_exit(), Get_max_id()); return it; } - dfs_bwd_itrator Dfs_bwd_end() { dfs_bwd_itrator it(NULL, 0); return it; } + dfs_fwd_iterator Dfs_fwd_begin() { dfs_fwd_iterator it(Get_dummy_entry(), Get_max_id()); return it; } + dfs_fwd_iterator Dfs_fwd_end() { dfs_fwd_iterator it(NULL, 0); return it; } + dfs_bwd_iterator Dfs_bwd_begin() { dfs_bwd_iterator it(Get_dummy_exit(), Get_max_id()); return it; } + dfs_bwd_iterator Dfs_bwd_end() { dfs_bwd_iterator it(NULL, 0); return it; } // BB iterators bb_iterator BB_begin() { return _node_container.begin(); } Modified: trunk/osprey/be/com/wn_cfg_template.h =================================================================== --- trunk/osprey/be/com/wn_cfg_template.h 2011-03-04 17:27:33 UTC (rev 3505) +++ trunk/osprey/be/com/wn_cfg_template.h 2011-03-05 06:19:38 UTC (rev 3506) @@ -374,8 +374,8 @@ if (WN_label_number(goto_wn) == WN_label_number(label)) return TRUE; } - if (WN_label_number(WN_switch_default(stmt)) == - WN_label_number(label)) + if (WN_kid_count(stmt) > 2 && + WN_label_number(WN_switch_default(stmt)) == WN_label_number(label)) return TRUE; else return FALSE; @@ -401,7 +401,8 @@ if (goto_wn == kid) return TRUE; } - if (WN_switch_default(stmt) == kid) + if (WN_kid_count(stmt) > 2 && + WN_switch_default(stmt) == kid) return TRUE; else return FALSE; @@ -445,18 +446,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_iterator 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")); } } @@ -777,18 +778,20 @@ Is_True(then_block != NULL && WN_operator(then_block) == OPR_BLOCK, ("invalid BLOCK of IF then")); - BB_NODE* then_bb = _action.Create_node(if_bb, WN_first(then_block)); - _action.Process_predsucc(if_bb, then_bb); + _current_bb = _action.Create_node(if_bb, WN_first(then_block)); + _action.Process_predsucc(if_bb, _current_bb); Process_block(then_block); + BB_NODE* then_bb = _current_bb; // put ELSE block into BB2 WN* else_block = WN_else(wn); Is_True(else_block != NULL && WN_operator(else_block) == OPR_BLOCK, ("invalid BLOCK of IF else")); - BB_NODE* else_bb = _action.Create_node(if_bb, WN_first(else_block)); - _action.Process_predsucc(if_bb, else_bb); + _current_bb = _action.Create_node(if_bb, WN_first(else_block)); + _action.Process_predsucc(if_bb, _current_bb); Process_block(else_block); + BB_NODE* else_bb = _current_bb; // connect THEN/ELSE block with BB3 _current_bb = _action.Create_node(then_bb != NULL ? then_bb : else_bb, @@ -821,18 +824,18 @@ Process_stmt(init_bb, wn); // put COMP into BB1 - BB_NODE* cmp_bb = _action.Create_node(init_bb, WN_end(wn)); - _action.Process_predsucc(init_bb, cmp_bb); - Process_stmt(cmp_bb, WN_end(wn)); + _current_bb = _action.Create_node(init_bb, WN_end(wn)); + _action.Process_predsucc(init_bb, _current_bb); + Process_stmt(_current_bb, WN_end(wn)); + BB_NODE* cmp_bb = _current_bb; // put BODY/INCR into BB2 WN* body_block = WN_do_body(wn); Is_True(body_block != NULL && WN_operator(body_block) == OPR_BLOCK, ("invalid BLOCK for DO_LOOP body")); - BB_NODE* body_bb = _action.Create_node(cmp_bb, WN_first(body_block)); - _action.Process_predsucc(cmp_bb, body_bb); - _current_bb = body_bb; + _current_bb = _action.Create_node(cmp_bb, WN_first(body_block)); + _action.Process_predsucc(cmp_bb, _current_bb); Process_block(body_block); Process_stmt(_current_bb, WN_step(wn)); _action.Process_predsucc(_current_bb, cmp_bb); @@ -956,7 +959,7 @@ } goto_wn = WN_next(goto_wn); } - goto_wn = WN_switch_default(wn); + goto_wn = WN_kid_count(wn) > 2 ? WN_switch_default(wn) : NULL; if (goto_wn != NULL && label_set.find(WN_label_number(goto_wn)) == label_set.end()) _action.Process_goto(_current_bb, goto_wn); @@ -993,7 +996,7 @@ } casegoto_wn = WN_next(casegoto_wn); } - casegoto_wn = WN_switch_default(wn); + casegoto_wn = WN_kid_count(wn) > 2 ? WN_switch_default(wn) : NULL; if (casegoto_wn != NULL && label_set.find(WN_label_number(casegoto_wn)) == label_set.end()) _action.Process_goto(_current_bb, casegoto_wn); Modified: trunk/osprey/be/com/wssa_update.cxx =================================================================== --- trunk/osprey/be/com/wssa_update.cxx 2011-03-04 17:27:33 UTC (rev 3505) +++ trunk/osprey/be/com/wssa_update.cxx 2011-03-05 06:19:38 UTC (rev 3506) @@ -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 */ Modified: trunk/osprey/be/com/wssa_update.h =================================================================== --- trunk/osprey/be/com/wssa_update.h 2011-03-04 17:27:33 UTC (rev 3505) +++ trunk/osprey/be/com/wssa_update.h 2011-03-05 06:19:38 UTC (rev 3506) @@ -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 */ ------------------------------------------------------------------------------ What You Don't Know About Data Connectivity CAN Hurt You This paper provides an overview of data connectivity, details its effect on application quality, and explores various alternative solutions. http://p.sf.net/sfu/progress-d2d _______________________________________________ Open64-devel mailing list Open64-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/open64-devel