diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/RD_subst.cpp b/sapfor/experts/Sapfor_2017/_src/CFGraph/RD_subst.cpp index a99bf77..387b142 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/RD_subst.cpp +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/RD_subst.cpp @@ -321,38 +321,6 @@ static bool getDependencies(SAPFOR::Argument* var, SAPFOR::Instruction* instr, c return true; } -static bool ifVariableValid(SAPFOR::Argument* var, const set>& defs, - SAPFOR::Argument* processed_var, const pair& def_of_processed_var) -{ - const auto& BB_of_def_of_processed_var = def_of_processed_var.second; - - if (defs.size() == 1) - { - const auto& def = *defs.begin(); - if (def.second == BB_of_def_of_processed_var && def.first->getNumber() < def_of_processed_var.first->getNumber()) - return true; - } - - const auto& RD_In_BB_of_def_of_processed_var = BB_of_def_of_processed_var->getRD_In(); - auto RD_of_var_from_BB_with_processed_var = RD_In_BB_of_def_of_processed_var.find(var); - - if (RD_of_var_from_BB_with_processed_var != RD_In_BB_of_def_of_processed_var.end() - && RD_of_var_from_BB_with_processed_var->second.size() == defs.size()) - { - for (const auto& def : defs) - { - int number_of_istruction_with_decl = def.first ? def.first->getNumber() : CFG_VAL::UNINIT; - - if (RD_of_var_from_BB_with_processed_var->second.count(number_of_istruction_with_decl) == 0) - return false; - } - - return true; - } - - return false; -} - static const set& func_affects(const FuncInfo* func, const vector& blocks) { static map> affects; @@ -1150,7 +1118,7 @@ vector sortCfgNodes(const vector& bloc if (!nodes_added && processing_stack.size() != 0) { //there is some blocks in the stack but no one can be processed //this code should be unreachable -#ifdef DEBUG_CHECKS +#if DEBUG_CHECKS printInternalError(convertFileName(__FILE__).c_str(), __LINE__); #endif // DEBUG_CHECKS auto block = processing_stack.back(); @@ -1167,7 +1135,7 @@ vector sortCfgNodes(const vector& bloc } } -#ifdef DEBUG_CHECKS +#if DEBUG_CHECKS set verify_unique; verify_unique.insert(result.begin(), result.end()); @@ -1176,7 +1144,7 @@ vector sortCfgNodes(const vector& bloc verify_unique.clear(); #endif // DEBUG_CHECKS -#ifdef DEBUG_CHECKS +#if DEBUG_CHECKS set all_blocks, res_blocks; all_blocks.insert(blocks.begin(), blocks.end()); @@ -1267,7 +1235,7 @@ bool isArgReaches(int decl_instr, SAPFOR::BasicBlock* decl_bb, if (RDs_for_arg.size() == 1) { const int rd = *RDs_for_arg.begin(); - if (rd >= decl_bb->getInstructions().front()->getNumber() && rd <= decl_instr) + if (rd >= decl_bb->getInstructions().front()->getNumber() && rd < decl_instr) return true; } @@ -1275,7 +1243,67 @@ bool isArgReaches(int decl_instr, SAPFOR::BasicBlock* decl_bb, if (arg_in_from_decl_it == decl_bb->getRD_In().end()) return false; - return arg_in_from_decl_it->second == RDs_for_arg; + if(arg_in_from_decl_it->second != RDs_for_arg) + return false; + + set reachable = { decl_bb }; + set banned_instructions; + for (int instr_def : arg_in_from_decl_it->second) + if (instr_def >= decl_instr || instr_def < decl_bb->getInstructions().front()->getNumber()) + //try to find way [decl_bb] -> [dest_bb] with redefining of var (that means that var value from decl_bb could be overwrited) + banned_instructions.insert(instr_def); + + set worklist = reachable, banned_blocks; + bool way_found = false; + while (worklist.size() != 0 && banned_instructions.size() != 0) + { + for (SAPFOR::BasicBlock* wl : worklist) + { + int start = wl->getInstructions().front()->getNumber(), end = wl->getInstructions().back()->getNumber(); + + for (auto banned_it = banned_instructions.begin(); banned_it != banned_instructions.end();) + { + if(start <= *banned_it && *banned_it <= end) + { + banned_it = banned_instructions.erase(banned_it); + banned_blocks.insert(wl); + } + else + { + banned_it++; + } + } + } + + set to_insert; + + for (auto b : worklist) + for (auto next : b->getNext()) + if (reachable.insert(next).second) + to_insert.insert(next); + + worklist = to_insert; + } + + reachable = banned_blocks; + worklist = reachable; + while (worklist.size() != 0 || banned_instructions.size() == 0) + { + if(worklist.find(dest_bb) != worklist.end()) + return false; + + set to_insert; + + for (auto b : worklist) + for (auto next : b->getNext()) + if(next != decl_bb) + if (reachable.insert(next).second) + to_insert.insert(next); + + worklist = to_insert; + } + + return true; } // return arg's definition if it really reaches dest_bb @@ -1597,28 +1625,7 @@ void buildSubstitutions(const map>& CFGra for (SAPFOR::Argument* dep : dependencies_of_var->second) { - if (dep->getType() != CFG_ARG_TYPE::VAR) - { - can_use = false; - break; - } - - const auto& RD_In_of_curr_BB = cur_BB->getRD_In(); - auto dep_from_curr_RD_In = RD_In_of_curr_BB.find(dep); - - if (dep_from_curr_RD_In == RD_In_of_curr_BB.end()) - { - can_use = false; - break; - } - - const auto& RDs_for_dep = dep_from_curr_RD_In->second; - - set> defs_of_dep; - for (int def_instruction_num : RDs_for_dep) - defs_of_dep.insert(getInstructionAndBlockByNumber(CFGraph_for_project, def_instruction_num)); - - if (!ifVariableValid(dep, defs_of_dep, in_val.first, instr_and_bb)) + if (!isArgReaches(instr_num, instr_and_bb.second, dep, cur_BB)) { can_use = false; break;