https://gcc.gnu.org/g:8dd2f1ee16fb9ec05ef5c5370e33b0acb946e94d
commit 8dd2f1ee16fb9ec05ef5c5370e33b0acb946e94d Author: Ondřej Machota <ondrejmach...@gmail.com> Date: Fri Mar 14 14:04:39 2025 +0100 rtl-ssa-dce: phis are marked correctly Diff: --- gcc/dce.cc | 112 ++++++++++++++----------------------------------------------- 1 file changed, 25 insertions(+), 87 deletions(-) diff --git a/gcc/dce.cc b/gcc/dce.cc index cfa58f21dc03..58d763314778 100644 --- a/gcc/dce.cc +++ b/gcc/dce.cc @@ -1473,7 +1473,7 @@ bool is_rtx_insn_prelive(rtx_insn *insn) { return true; rtx body = PATTERN(insn); - if (GET_CODE(body) == CLOBBER) // ~/Documents/gcc/gcc/testsuite/gcc.c-torture/compile/20000605-1.c + if (GET_CODE(body) == CLOBBER) // gcc/gcc/testsuite/gcc.c-torture/compile/20000605-1.c return true; if (side_effects_with_mem(body) || can_throw_internal(body)) @@ -1588,12 +1588,18 @@ rtl_ssa_dce_prelive(std::unordered_set<insn_info *> &marked) static std::unordered_set<insn_info *> rtl_ssa_dce_mark() { + std::unordered_set<set_info *> marked_sets{}; + + std::unordered_set<insn_info *> marked{}; + // phi insn might have more that one phi node: gcc/gcc/testsuite/gcc.c-torture/execute/20000224-1.c + std::unordered_set<phi_info *> marked_phi_nodes{}; + // Phi will not be prelive auto worklist = rtl_ssa_dce_prelive(marked); auto_vec<set_info *> worklist_new{}; for (auto && item : worklist) { insn_info * insn = item; - std::cerr << "cp Current: " << insn->uid() << '\n'; + // std::cerr << "cp Current: " << insn->uid() << '\n'; for (auto&& use : insn->uses()) { set_info* set = use->def(); if (set) { @@ -1613,20 +1619,26 @@ rtl_ssa_dce_mark() * TODO : a phi insn might be visited more times due to having more phi nodes * Either we have to mark phi nodes or do not mark phi insn */ - std::cerr << "Current: " << insn->uid() << '\n'; + // std::cerr << "Current: " << insn->uid() << '\n'; // if (insn->uid() == -21) { // std::cerr << "Insn -21 phi? " << insn->is_phi() << '\n'; // } - if ((marked.count(insn) > 0)) { + if ((marked.count(insn) > 0) && !insn->is_phi()) { continue; } + // std::cout << insn->uid() << " not skipped\n"; + marked.emplace(insn); use_array uses = insn->uses(); if (insn->is_phi()) { phi_info* pi = as_a<phi_info *> (set); + if (marked_phi_nodes.count(pi) > 0) { + continue; + } + marked_phi_nodes.emplace(pi); uses = pi->inputs(); } @@ -1644,80 +1656,6 @@ rtl_ssa_dce_mark() } } - // if (dump_file) - // fprintf(dump_file, "Finished inherently live, marking parents\n"); - // while (!worklist.is_empty()) - // { - // insn_info *insn = worklist.pop(); - // use_array uses = insn->uses(); - // if (insn->is_phi()) { - // std::cerr << "Phi : "<< insn->uid() << " - uses: " << insn->num_uses() << ", defs:" << insn->num_defs() << '\n'; - // for (auto&& use : uses) { - // debug(use); - // std::cerr << '\n'; - // } - // } else if (insn->is_artificial()) { - // std::cerr << "Artificial " << insn->uid() << " - uses: " << insn->num_uses() << ", defs:" << insn->num_defs() << '\n'; - // for (auto&& use : uses) { - // debug(use); - // std::cerr << '\n'; - // } - // } - - // if (dump_file) - // fprintf(dump_file, "Looking at: %d, uses: %d\n", insn->uid(), uses.size()); - - // //std::cerr << "Insn: " << insn->uid() << ", uses: " << uses.size() << '\n'; - // std::cerr << "Current: " << insn->uid() << '\n'; - // for (size_t i = 0; i < uses.size(); i++) - // { - // // debug(uses[i]); - // use_info* use = uses[i]; - // // debug(use->def()); - // // if (use->def() != nullptr) { - // // std::cerr << use->def()->insn()->uid() << '\n'; - // // } - // // std::cerr << '\n'; - // // debug(use); - // // std::cerr << '\n'; - - // set_info* set = use->def(); - // if (!set) { - // continue; - // } - // insn_info *parent_insn = set->insn(); - // if (!parent_insn) { - // continue; - // } - // // if (parent_insn->is_phi()) { // this is weird... - // // // debug(use->def()); - // // phi_info * pi = as_a<phi_info *> (use->def()); - // // // std::cerr << "phi inputs: " << pi->num_inputs() << '\n'; - // // for (auto&& input: pi->inputs()) { - // // use_info* phi_use = input; - // // std::cerr << "Via phi insn: " << phi_use->def()->insn()->uid() << '\n'; - // // } - // // } - // int parent_insn_uid = parent_insn->uid(); - // // propage that some instruction in chain is live from bottom to top - // if (dump_file) - // fprintf(dump_file, "Trying to add: %d\n", parent_insn_uid); - // // not yet marked - // if (!(marked.count(parent_insn) > 0)) - // { - // //std::cerr << "Adding: " << parent_insn_uid << " to worklist"; - // if (dump_file) - // fprintf(dump_file, " Adding insn %d to worklist - mark\n", parent_insn_uid); - - - // worklist.safe_push(parent_insn); - // marked.emplace(parent_insn); - // } - // } - - // auto bb = insn->bb(); - // } - // for (auto&& insn : marked) { // if (dump_file) // fprintf(dump_file, " Marked insn: %d\n", insn->uid()); @@ -1736,7 +1674,7 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> marked) // we can get the number of items in the set and create an array of changes // which will hopefully have constructor for array_slice<insn_info *> auto attempt = crtl->ssa->new_change_attempt (); - std::cerr << "Change attempt created successfully" << std::endl; + // std::cerr << "Change attempt created successfully" << std::endl; for (insn_info *insn = crtl->ssa->first_insn(); insn; insn = next) { if (dump_file) @@ -1754,7 +1692,7 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> marked) // Skip artificial insns (or uid() < 0) if (insn->is_real()) { - std::cerr << "Insn: " << insn->uid() << " will be deleted\n"; + // std::cerr << "Insn: " << insn->uid() << " will be deleted\n"; auto change = insn_change::delete_insn(insn); // crtl->ssa->possibly_queue_changes(change); to_delete.safe_push(change); @@ -1763,20 +1701,20 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> marked) } } - std::cerr << "Selected unmarked insns" << std::endl; + // std::cerr << "Selected unmarked insns" << std::endl; auto_vec<insn_change*> changes(to_delete.length()); for (size_t i = 0; i != to_delete.length(); ++i) { changes.safe_push(&to_delete[i]); } - std::cerr << "Verification" << std::endl; + // std::cerr << "Verification" << std::endl; if (crtl->ssa->verify_insn_changes(changes)) { - std::cerr << "Changes are correct" << std::endl; + // std::cerr << "Changes are correct" << std::endl; // segfault: gcc.c-torture/execute/20000224-1.c crtl->ssa->change_insns(changes); } else { - std::cerr << "Changes are not correct\n"; + // std::cerr << "Changes are not correct\n"; } } @@ -1784,13 +1722,13 @@ static unsigned int rtl_ssa_dce() { rtl_ssa_dce_init(); - debug(crtl->ssa); + // debug(crtl->ssa); //std::cerr << "Next phase: prelive + mark: \n"; std::unordered_set<insn_info *> marked = rtl_ssa_dce_mark(); - std::cerr << "Marking done\n"; + // std::cerr << "Marking done\n"; rtl_ssa_dce_sweep(marked); - std::cerr << "Sweeping done\n"; + // std::cerr << "Sweeping done\n"; rtl_ssa_dce_done(); return 0;