https://gcc.gnu.org/g:668fb8231327b7385492464ab879fe06f9859ca1

commit 668fb8231327b7385492464ab879fe06f9859ca1
Author: Ondřej Machota <ondrejmach...@gmail.com>
Date:   Tue Apr 8 23:27:00 2025 +0200

    rtl-ssa-dce: delete dead debug insns

Diff:
---
 gcc/dce.cc | 138 ++++++++++++++++---------------------------------------------
 1 file changed, 35 insertions(+), 103 deletions(-)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index c0ca89980254..40b4cd991151 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -1421,42 +1421,24 @@ bool is_prelive(insn_info *insn)
   gcc_assert (insn->is_real());
   auto rtl = insn->rtl();
 
-  /* I guess that a lot of conditions bellow are captured by artificial uses
-     of bb head and end insns. */
   for (def_info * def : insn->defs()) {
     /* The purpose of this pass is not to eliminate stores to memory... */
     if (def->is_mem())
-      // TODO : clobbered memory?
       return true;
 
     gcc_assert(def->is_reg());
-    /* this ignores clobbers, which is probably fine */
 
     /* gcc.c-torture/execute/20000503-1.c - flags register is unused. Not all
        hard registers should be marked... */
+       
+    /* this ignores clobbers, which is probably fine */
     if (def->kind() != access_kind::SET)
       continue;
 
-    /* This might be messed up a bit */
-    // if (def->regno() == FRAME_POINTER_REGNUM
-    //     || def->regno() == STACK_POINTER_REGNUM)
-    //   return true;
-
     /* needed by gcc.c-torture/execute/pr51447.c */
     if (HARD_REGISTER_NUM_P (def->regno())
         && global_regs[def->regno()])
-        // { std::cout << "marked global reg: " << def->regno() << " in " << 
insn->uid() << '\n';
-          return true;
-        // }
-
-    // if (!HARD_FRAME_POINTER_IS_FRAME_POINTER
-    //     && def->regno() == HARD_FRAME_POINTER_REGNUM)
-    //   return true;
-
-    // if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-    //     && fixed_regs[ARG_POINTER_REGNUM]
-    //     && def->regno() == ARG_POINTER_REGNUM)
-    //   return true;
+        return true;
 
     unsigned int picreg = PIC_OFFSET_TABLE_REGNUM;
     if (picreg != INVALID_REGNUM
@@ -1469,20 +1451,24 @@ bool is_prelive(insn_info *insn)
 }
 
 static void
-rtl_ssa_dce_mark_prelive_insn(insn_info *info, vec<insn_info *> &worklist, 
+rtl_ssa_dce_mark_prelive_insn(insn_info *insn, auto_vec<set_info *> &worklist, 
       std::unordered_set<insn_info *> &marked)
 {
   if (dump_file)
-    fprintf(dump_file, "Insn %d is prelive\n", info->uid());
+    fprintf(dump_file, "Insn %d marked as prelive\n", insn->uid());
 
-  marked.emplace(info);
-  worklist.safe_push(info);
+  marked.emplace(insn);
+  for (use_info *use : insn->uses()) {
+    set_info* set = use->def();
+    if (set)
+      worklist.safe_push(set);
+  }
 }
 
-static auto_vec<insn_info *>
+static auto_vec<set_info *>
 rtl_ssa_dce_mark_prelive(std::unordered_set<insn_info *> &marked)
 {
-  auto_vec<insn_info *> worklist;
+  auto_vec<set_info *> worklist;
   for (insn_info * insn : crtl->ssa->all_insns()) {
     if (is_prelive(insn))
       rtl_ssa_dce_mark_prelive_insn(insn, worklist, marked);
@@ -1497,16 +1483,7 @@ rtl_ssa_dce_mark()
   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{};
-  auto prelive_insns = rtl_ssa_dce_mark_prelive(marked);
-  /* Extract uses from prelive insns to worklist */
-  auto_vec<set_info *> worklist{};
-  for (insn_info * insn : prelive_insns) {
-    for (auto&& use : insn->uses()) {
-      set_info* set = use->def();
-      if (set)
-        worklist.safe_push(set);
-    }
-  }
+  auto worklist = rtl_ssa_dce_mark_prelive(marked);
 
   while (!worklist.is_empty()) {
     set_info* set = worklist.pop();
@@ -1581,78 +1558,31 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> 
marked)
   crtl->ssa->change_insns(changes);
 }
 
-// WIP
-static void
-rtl_ssa_dce_transform_insns_to_debug() {
-  std::unordered_set<int> is_debug;
-  // Should we use ssa when modifing insns? if yes, we want in-place replace
-
-  /* chceme prochazet v post orderu, abychom nejdrive zpracovali zavislosti
-     a pak az definici nelze jen menit instrukce, protoze musime informaci
-     propagovat pres phi node */
-  /* We check, whether all insns that use a definition from the current insn
-     are only debug insns */
-  for (insn_info * insn : crtl->ssa->reverse_all_insns()) {
-    if (insn->is_debug_insn()) { // phi is never debug
-        // TODO : store info about this insn
-        is_debug.emplace(insn->uid());
-        continue;
-    }
+static void reset_debug_insn_uses(insn_info * insn) {
+  gcc_assert(insn->is_debug_insn());
 
-    if (insn->is_phi()) {
-      // for each phi_info
-      for (def_info *def : insn->defs()) {
-        phi_info *pi = as_a<phi_info *> (def);
-        
-      }
-    }
+  if (dump_file)
+    fprintf(dump_file, "Resetting debug insn: %d\n", insn->uid());
 
-    rtx_insn * rtl = insn->rtl();
-    rtx set;
-    if (!(MAY_HAVE_DEBUG_BIND_INSNS 
-      && (set = single_set (rtl)) != NULL_RTX 
-      && (!side_effects_p (SET_SRC (set))
-      && asm_noperands (PATTERN (rtl)) < 0))) {
+  insn_change change (insn);
+  change.new_uses = {};
+  INSN_VAR_LOCATION_LOC (insn->rtl()) = gen_rtx_UNKNOWN_VAR_LOC ();
+  crtl->ssa->change_insn (change);
+}
+
+// WIP
+static void
+rtl_ssa_dce_reset_dead_debug(std::unordered_set<insn_info *> &marked) {
+  for (insn_info *insn : crtl->ssa->all_insns()) {
+    if (!insn->is_debug_insn())
       continue;
-    }
 
-    bool should_be_debug = true;
-    for (def_info *def : insn->defs()) {
-      // TODO : how to cast this correctly? - clobber_info
-      // access_kind for def_insn is only SET or CLOBBER
-      if (def->kind() == access_kind::CLOBBER)
-        continue;
-      set_info* si = as_a<set_info*>(def);
-      // TODO : use has_nondebug_uses or has_nondebug_insn_uses - what is the 
difference? phi?
-      // after that we will use rtl-ssa change API to make the insn debug (it 
will hopefully
-      // recalculate has_nondebug_uses of other instructions...)
-      for (use_info * use : si->all_uses()) {
-        auto iii = use->insn()->is_debug_insn();
+    for (use_info * use: insn->uses()) {
+      if (marked.count(use->def()->insn()) == 0) {
+        reset_debug_insn_uses(insn);
+        break;
       }
     }
-
-    if (!should_be_debug) {
-      continue;
-    }
-
-    // TODO : perform a change
-    /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL).  */
-    rtx dval = make_debug_expr_from_rtl (SET_DEST (set));
-
-    /* Emit a debug bind insn before the insn in which
-        reg dies.  */
-    rtx bind_var_loc =
-      gen_rtx_VAR_LOCATION (GET_MODE (SET_DEST (set)),
-          DEBUG_EXPR_TREE_DECL (dval),
-          SET_SRC (set),
-          VAR_INIT_STATUS_INITIALIZED);
-
-    rtx_insn * bind = emit_debug_insn_before (bind_var_loc, rtl);
-    // auto debug_insn = insn_info(insn->bb(), bind, 0);
-    auto attempt = crtl->ssa->new_change_attempt ();
-    auto change = insn_change(insn);
-    // TODO : delete rtx from cfg and replace insn in ssa to debug_insn 
-    // delete_insn_and_edges or delete_insn - do we need to delete edges?
   }
 }
 
@@ -1681,6 +1611,8 @@ rtl_ssa_dce()
   rtl_ssa_dce_init();
   // debug(crtl->ssa);
   std::unordered_set<insn_info *> marked = rtl_ssa_dce_mark();
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
+    rtl_ssa_dce_reset_dead_debug(marked);
   rtl_ssa_dce_sweep(marked);
   // std::cerr << "\033[31m" << "SSA debug start" << "\033[0m" << "\n";
   // debug (crtl->ssa);

Reply via email to