//'usevec': for local used. bool IR_CP::doProp(IN IRBB * bb, Vector<IR*> & usevec) { bool change = false; C<IR*> * cur_iter, * next_iter; for (BB_irlist(bb).get_head(&cur_iter), next_iter = cur_iter; cur_iter != NULL; cur_iter = next_iter) { IR * def_stmt = cur_iter->val(); BB_irlist(bb).get_next(&next_iter); if (!is_copy(def_stmt)) { continue; } DUSet const* useset = NULL; UINT num_of_use = 0; SSAInfo * ssainfo = NULL; bool ssadu = false; if ((ssainfo = def_stmt->get_ssainfo()) != NULL && SSA_uses(ssainfo).get_elem_count() != 0) { //Record use_stmt in another vector to facilitate this function //if it is not in use-list any more after copy-propagation. SEGIter * sc; for (INT u = SSA_uses(ssainfo).get_first(&sc); u >= 0; u = SSA_uses(ssainfo).get_next(u, &sc)) { IR * use = m_ru->get_ir(u); ASSERT0(use); usevec.set(num_of_use, use); num_of_use++; } ssadu = true; } else if (def_stmt->get_exact_ref() == NULL && !def_stmt->is_void()) { //Allowing copy propagate exact or VOID value. continue; } else if ((useset = def_stmt->readDUSet()) != NULL && useset->get_elem_count() != 0) { //Record use_stmt in another vector to facilitate this function //if it is not in use-list any more after copy-propagation. DUIter di = NULL; for (INT u = useset->get_first(&di); u >= 0; u = useset->get_next(u, &di)) { IR * use = m_ru->get_ir(u); usevec.set(num_of_use, use); num_of_use++; } } else { continue; } IR const* prop_value = get_propagated_value(def_stmt); for (UINT i = 0; i < num_of_use; i++) { IR * use = usevec.get(i); ASSERT0(use->is_exp()); IR * use_stmt = use->get_stmt(); ASSERT0(use_stmt->is_stmt()); ASSERT0(use_stmt->get_bb() != NULL); IRBB * use_bb = use_stmt->get_bb(); if (!ssadu && !(bb == use_bb && bb->is_dom(def_stmt, use_stmt, true)) && !m_cfg->is_dom(BB_id(bb), BB_id(use_bb))) { //'def_stmt' must dominate 'use_stmt'. //e.g: // if (...) { // g = 10; //S1 // } // ... = g; //S2 //g can not be propagted since S1 is not dominate S2. continue; } if (!is_available(def_stmt, prop_value, use_stmt)) { //The value that will be propagated can //not be killed during 'ir' and 'use_stmt'. //e.g: // g = a; //S1 // if (...) { // a = ...; //S3 // } // ... = g; //S2 //g can not be propagted since a is killed by S3. continue; } if (!ssadu && !m_du->isExactAndUniqueDef(def_stmt, use)) { //Only single definition is allowed. //e.g: // g = 20; //S3 // if (...) { // g = 10; //S1 // } // ... = g; //S2 //g can not be propagted since there are //more than one definitions are able to get to S2. continue; } if (!canBeCandidate(prop_value)) { continue; } CPCtx lchange; IR * old_use_stmt = use_stmt; replaceExp(use, prop_value, lchange, ssadu); ASSERT(use_stmt && use_stmt->is_stmt(), ("ensure use_stmt still legal")); change |= CPC_change(lchange); if (!CPC_change(lchange)) { continue; } //Indicate whether use_stmt is the next stmt of def_stmt. bool is_next = false; if (next_iter != NULL && use_stmt == next_iter->val()) { is_next = true; } RefineCtx rf; use_stmt = m_ru->refineIR(use_stmt, change, rf); if (use_stmt == NULL && is_next) { //use_stmt has been optimized and removed by refineIR(). next_iter = cur_iter; BB_irlist(bb).get_next(&next_iter); } if (use_stmt != NULL && use_stmt != old_use_stmt) { //use_stmt has been removed and new stmt generated. ASSERT(old_use_stmt->is_undef(), ("the old one should be freed")); C<IR*> * irct = NULL; BB_irlist(use_bb).find(old_use_stmt, &irct); ASSERT0(irct); BB_irlist(use_bb).insert_before(use_stmt, irct); BB_irlist(use_bb).remove(irct); } } //end for each USE } //end for IR return change; }