Cont_cpr_match_result cpr_match_hb_maxreduce (Compound_region* blk) { // pattern match applies to superblock or hyperblock // predicates use must be static single assignment // scan the hyper block and build up a hb-descr HB_cont_cpr_descr hb_descr(blk); Hash_set<Operand> dn_defs(hash_operand, 223); if(dbg(cpr,5)) { cout << "Matching control block: " << blk->id() << endl; cout << *blk << endl; } int num_branches=0; // count the branches as we go for (Region_ops_C0_order opc(blk); opc != 0; ++opc) { // perform the match analysis Op* op = (*opc); if(is_cmpp(op)) {// for a compare if(dbg(cpr,4)) {cout << "op" << op->id() << " is a compare"<< endl;} hb_descr.insert_compare(op); } else if(is_conditional_branch(op) || is_brl(op) || is_bru(op) ) { // if(dbg(cpr,4)){cout << "op" << op->id() << " is a branch"<< endl;} hb_descr.insert_branch(op); num_branches++; } } //num_branches counts the number of branches in the cont_cpr_descr Cont_cpr_match_result result; //construct and initialize cpr_blk_list & cpr_blk_type Dlist< Pair<Op*, Op*> > cpr_blk; // declare current cpr block Pair<Op* , Op*> curr_tuple; // tuple for potential inclusion into result int curr_br=0; //indicates last branch already in cpr block int cand_br; //indicates candidate for potentially joining block int prev_blk_last_br=0; //last branch in previous block El_Cpr_Match_Info blk_info; while(true){ // build new CPR block cpr_blk.clear(); curr_br=prev_blk_last_br+1; if(curr_br>num_branches) break; curr_tuple=hb_descr.get_tuple(curr_br); cpr_blk.push_tail(curr_tuple); //always add first branch to cpr block if(dbg(cpr,4)) { cout << "pushing tuple into new cpr block: " ; print_tuple(cout, curr_tuple); cout << endl; } hb_descr.suitability_init(curr_br); //initialize compare suitability test hb_descr.blocking_init(curr_br); bool type=false; // initialize to fall_through list blk_info = EL_CPR_MATCH_UNKNOWN; while(true){ //may append additonal branches to CPR block cand_br=curr_br+1; if(cand_br > num_branches) { blk_info = EL_CPR_MATCH_END; break; } if (dbg(cpr,4)) cout << "+Considering candidate to be appended: " << cand_br << endl; if(!hb_descr.suitability_test(cand_br)) { if (dbg(cpr,4)) cout << "\tSuitability test failed on candidiate - not appended" << endl; blk_info = EL_CPR_MATCH_SUITABILITY; break; } if (!hb_descr.max_block_length_test(cand_br)) { if (dbg(cpr,4)) cout << "\tMax block length exceeded - cand not appended" << endl; blk_info = EL_CPR_MATCH_MAX_BR; break; } //passed all tests curr_br=cand_br; curr_tuple = hb_descr.get_tuple(curr_br); cpr_blk.push_tail(curr_tuple); //append candidate branch to cpr block if(dbg(cpr,4)) { cout << "pushing tuple into previous cpr block: " ; print_tuple(cout, curr_tuple); cout << endl; } } result.cpr_blk_list.push_tail(cpr_blk); type = hb_descr.predict_taken(curr_br); result.cpr_blk_type.push_tail(type); result.cpr_blk_info.push_tail(blk_info); prev_blk_last_br=curr_br; } return result; }
Cont_cpr_match_result cpr_match_hb_original (Compound_region* blk){ // pattern match applies to superblock or hyperblock // predicates use must be static single assignment // scan the hyper block and build up a hb-descr HB_cont_cpr_descr hb_descr(blk); Hash_set<Operand> dn_defs(hash_operand, 223); if(dbg(cpr,5)) { cout << "Matching control block: " << blk->id() << endl; cout << *blk << endl; } int num_branches=0; // count the branches as we go for (Region_ops_C0_order opc(blk); opc != 0; ++opc) { // perform the match analysis Op* op = (*opc); if(is_cmpp(op)) {// for a compare if(dbg(cpr,4)) {cout << "op" << op->id() << " is a compare"<< endl;} hb_descr.insert_compare(op); } else if(is_conditional_branch(op) || is_brl(op) || is_bru(op) ) { // if(dbg(cpr,4)){cout << "op" << op->id() << " is a branch"<< endl;} hb_descr.insert_branch(op); num_branches++; } } //num_branches counts the number of branches in the cont_cpr_descr Cont_cpr_match_result result; //construct and initialize cpr_blk_list & cpr_blk_type Dlist< Pair<Op*, Op*> > cpr_blk; // declare current cpr block Pair<Op* , Op*> curr_tuple; // tuple for potential inclusion into result int curr_br=0; //indicates last branch already in cpr block int cand_br; //indicates candidate for potentially joining block int prev_blk_last_br=0; //last branch in previous block bool blk_type=false; El_Cpr_Match_Info blk_info; while(true){ cpr_blk.clear(); //begin building new CPR block curr_br=prev_blk_last_br+1; if(curr_br>num_branches) break; curr_tuple=hb_descr.get_tuple(curr_br); cpr_blk.push_tail(curr_tuple); //always add first branch to cpr block if(dbg(cpr,4)) { cout << endl << "pushing tuple into new cpr block: " ; print_tuple(cout, curr_tuple); cout << endl; } hb_descr.suitability_init(curr_br); //initialize compare suitability test hb_descr.separability_init(curr_br); hb_descr.blocking_init(curr_br); bool predict_taken=false; bool predict_pausea=false; bool predict_break=false; blk_info = EL_CPR_MATCH_UNKNOWN; while(true){ //may append additonal branches to CPR block if(hb_descr.predict_taken(curr_br)) //complete tests which break after inclusion { if (dbg(cpr,4)) { cout << "predict taken current\n";} blk_type=true; //block of type taken block blk_info = EL_CPR_MATCH_PRED_TAKEN; break; } if( hb_descr.predict_break(curr_br) ) { if (dbg(cpr,4)) {cout<<"predicted break current"<<endl;} blk_info = EL_CPR_MATCH_BREAK; break; } if(hb_descr.predict_pausea(curr_br)) { if (dbg(cpr,4)) { cout << "predict pausea current\n";} blk_type=false; blk_info = EL_CPR_MATCH_PAUSEA; break; } cand_br=curr_br+1; if(cand_br > num_branches) { blk_info = EL_CPR_MATCH_END; break; } if (dbg(cpr,4)) {cout<< "Considering candidate to be appended:" << cand_br << endl;} if(!hb_descr.suitability_test(cand_br)) { if (dbg(cpr,4)) {cout << "Suitability test failed -- candidiate not appended" << endl;} blk_info = EL_CPR_MATCH_SUITABILITY; break; // preform suitability test and cut block if fails } if(!hb_descr.separability_test(cand_br)) { if (dbg(cpr,4)) cout << "Separability test failed -- candidiate not appended" << endl; blk_info = EL_CPR_MATCH_SEPARABILITY; break; } if(hb_descr.predict_taken(cand_br)&&hb_descr.can_move_back(prev_blk_last_br+1,cand_br)) { // CPR to taken branch case if (dbg(cpr,4)) {cout << "Predict taken(cand_br)\n";} predict_taken=true; } if(!predict_taken && hb_descr.predict_break(cand_br)) { if (dbg(cpr,4)) {cout << "Predict break\n";} predict_break=true; //preclude growth of next block blk_info = EL_CPR_MATCH_BREAK; break; } //blocking test not applied in taken branch case if (!predict_taken && !predict_break && !hb_descr.sum_exit_freq_test(cand_br)) { if (dbg(cpr,4)) {cout << "Exit frequency exceeded" << endl;} blk_info = EL_CPR_MATCH_EXIT_RATIO; break; } if(!predict_taken && hb_descr.predict_pauseb(cand_br)) { if (dbg(cpr,4)) {cout << "Predict pauseb\n";} blk_info = EL_CPR_MATCH_PAUSEB; break; } if(!predict_taken && hb_descr.predict_pausea(cand_br)) { if (dbg(cpr,4)) {cout << "Predict pausea\n";} predict_pausea=true; } if (!hb_descr.max_block_length_test(cand_br)) { if (dbg(cpr,4)) {cout << "Max block length\n";} blk_info = EL_CPR_MATCH_MAX_BR; break; } //passed all tests which break before inclusion curr_br=cand_br; curr_tuple = hb_descr.get_tuple(curr_br); cpr_blk.push_tail(curr_tuple); //append candidate branch to cpr block if(dbg(cpr,4)) { cout << "Pushing tuple into previous cpr block. " ; print_tuple(cout, curr_tuple); cout << endl; } } // add new cpr block to list if of appropriate size if((int) cpr_blk.size() >= El_cpr_min_block_length) { if(dbg(cpr,4)) { cout << "Adequate sized block pushed, type: " << blk_type << endl; } result.cpr_blk_list.push_tail(cpr_blk); result.cpr_blk_type.push_tail(blk_type); result.cpr_blk_info.push_tail(blk_info); } else { curr_br=prev_blk_last_br+1; // roll back to block of length one curr_tuple=cpr_blk.head(); //keep only the first tuple from the current block cpr_blk.clear(); cpr_blk.push_tail(curr_tuple); result.cpr_blk_list.push_tail(cpr_blk); result.cpr_blk_type.push_tail(false); result.cpr_blk_info.push_tail(blk_info); if (dbg(cpr,4)) { cout << "Block too short, fabricating singleton cpr block. " ; print_tuple(cout, curr_tuple); cout << endl; } } prev_blk_last_br=curr_br; if (dbg(cpr,4)) { cout << "prev_blk_last_br=" << prev_blk_last_br << endl; } } return result; }