https://gcc.gnu.org/g:aecd918163914a09df0f619a9f3163dcadfaf425

commit aecd918163914a09df0f619a9f3163dcadfaf425
Author: Ondřej Machota <ondrejmach...@gmail.com>
Date:   Sun Mar 9 20:59:45 2025 +0100

    rtl-ssa: dce fix bad marked insn map passing

Diff:
---
 gcc/dce.cc | 146 ++++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 116 insertions(+), 30 deletions(-)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index f51f27dbd143..9a217a795b76 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -1316,6 +1316,7 @@ bool sets_global_register(const_rtx rtx) {
 }
 
 // We should mark stack registers
+// use HARD_FRAME_POINTER_REGNUM, REGNO_PTR_FRAME_P
 bool sets_global_register(rtx_insn* insn) {
   rtx set = single_set(insn);
   if (!set)
@@ -1370,21 +1371,55 @@ bool is_unary_mem_modification(rtx_code code) {
   }
 }
 
-bool is_rtx_insn_prelive(const_rtx rtx) {
-  if (rtx == nullptr) {
-    return false;
+bool is_rtx_insn_prelive(rtx_insn *insn) {
+  gcc_assert(insn != nullptr);
+
+  // TODO : handle calls correctly
+  if (CALL_P (insn)
+      /* We cannot delete pure or const sibling calls because it is
+        hard to see the result.  */
+      && (!SIBLING_CALL_P (insn))
+      /* We can delete dead const or pure calls as long as they do not
+         infinite loop.  */
+      && (RTL_CONST_OR_PURE_CALL_P (insn) && !RTL_LOOPING_CONST_OR_PURE_CALL_P 
(insn))
+      /* Don't delete calls that may throw if we cannot do so.  */
+      && can_delete_call (insn))
+    return true;
+    // return !find_call_stack_args (as_a <rtx_call_insn *> (insn), false, 
fast, arg_stores);
+
+  // Jumps, notes, barriers should not be deleted
+    // According to the docs, rtl ssa does not contain noteS and barrierS 
+  if (!NONJUMP_INSN_P (insn))
+  {
+    std::cerr << "found jump instruction\n";
+    debug(insn);
+    return true;
   }
 
-  auto code = GET_CODE(rtx);
-  if (is_control_flow(code))
+  // Only rtx_insn should be handled here
+  auto code = GET_CODE(insn);
+  gcc_assert(code == INSN);
+
+  /* Don't delete insns that may throw if we cannot do so.  */
+  if (!(cfun->can_delete_dead_exceptions && can_alter_cfg) && !insn_nothrow_p 
(insn))
     return true;
 
+  /* TODO : What about call argumets? Accoring to the docs, for function 
prologue the RTX_FRAME_RELATED_P
+     should return true.
+  */  
+  /* Callee-save restores are needed.  */
+  if (RTX_FRAME_RELATED_P (insn) && crtl->shrink_wrapped_separate && 
find_reg_note (insn, REG_CFA_RESTORE, NULL))
+    return true;
+
+  // if (is_control_flow(code))
+  //   return true;
+
   // Mark set of a global register
-  if (sets_global_register(rtx)) // check rtx_class with GET_RTX_CLASS if 
RTX_ISNS and convert if needed
+  if (sets_global_register(insn)) // check rtx_class with GET_RTX_CLASS if 
RTX_ISNS and convert if needed
     return true;
 
-  // Call is inside side_effects_p - how to mark parameter registers?
-  if (volatile_refs_p(rtx) || can_throw_internal(rtx) || BARRIER_P(rtx) || 
code == PREFETCH)
+  rtx body = PATTERN(insn);
+  if (side_effects_p(body) || can_throw_internal(body))
     return true;
 
   if (is_unary_mem_modification(code))
@@ -1394,21 +1429,34 @@ bool is_rtx_insn_prelive(const_rtx rtx) {
   // Parallel is handled by volatile_refs_p
 
   switch (code) {
-    
-  }
-
-  const char *const fmt = GET_RTX_FORMAT (code);
-  for (size_t i = 0; i < GET_RTX_LENGTH(code); ++i) {
-    if (fmt[i] == 'e' && is_rtx_insn_prelive(XEXP(rtx, i))) {
+    case MEM:
+    case ASM_INPUT:
+    case ASM_OPERANDS:
       return true;
-    } else if (fmt[i] == 'E') {
-      for (size_t j = 0; j < XVECLEN(rtx, i); ++j) {
-        if (is_rtx_insn_prelive(XVECEXP(rtx, i, j)))
-          return true;
-      }
-    }
+
+    case PARALLEL:
+      for (int i = XVECLEN (body, 0) - 1; i >= 0; i--)
+             if (!deletable_insn_p_1 (XVECEXP (body, 0, i)))
+               return true;
+      return false;
+      break;
+
+    default:
+      break;
   }
 
+  // const char *const fmt = GET_RTX_FORMAT (code);
+  // for (size_t i = 0; i < GET_RTX_LENGTH(code); ++i) {
+  //   if (fmt[i] == 'e' && is_rtx_insn_prelive(XEXP(rtx, i))) {
+  //     return true;
+  //   } else if (fmt[i] == 'E') {
+  //     for (size_t j = 0; j < XVECLEN(rtx, i); ++j) {
+  //       if (is_rtx_insn_prelive(XVECEXP(rtx, i, j)))
+  //         return true;
+  //     }
+  //   }
+  // }
+
   return false;
 }
 
@@ -1443,7 +1491,7 @@ bool is_prelive(insn_info *insn)
   if (!INSN_P(rtl)) // This might be useless
     return false;
 
-  rtx pat = PATTERN(rtl); // if we use this instead of rtl, then rtl notes 
wont be checked
+  return is_rtx_insn_prelive(rtl);
   
   // TODO : join if statements
   // We need to describe all possible prelive instructions, a list of all the 
instructions is inside `rtl.def`
@@ -1461,7 +1509,7 @@ bool is_prelive(insn_info *insn)
   std::cerr << "Prelive: " << GET_RTX_NAME(code) << '\n';
   // debug(insn);
   debug(rtl);
-  if (volatile_refs_p(rtl) || can_throw_internal(rtl) || BARRIER_P(rtl) || 
code == PREFETCH)
+  if (side_effects_p(rtl) || can_throw_internal(rtl) || BARRIER_P(rtl) || code 
== PREFETCH)
     return true;
 
   if (code == PARALLEL) {
@@ -1496,7 +1544,7 @@ rtl_ssa_dce_done()
 }
 
 static void
-rtl_ssa_dce_mark_live(insn_info *info, vec<insn_info *> &worklist, 
std::unordered_set<insn_info *> marked)
+rtl_ssa_dce_mark_live(insn_info *info, vec<insn_info *> &worklist, 
std::unordered_set<insn_info *> &marked)
 {
   int info_uid = info->uid();
   if (dump_file)
@@ -1507,7 +1555,7 @@ rtl_ssa_dce_mark_live(insn_info *info, vec<insn_info *> 
&worklist, std::unordere
 }
 
 static auto_vec<insn_info *>
-rtl_ssa_dce_prelive(std::unordered_set<insn_info *> marked)
+rtl_ssa_dce_prelive(std::unordered_set<insn_info *> &marked)
 {
   insn_info *next;
   auto_vec<insn_info *> worklist;
@@ -1542,9 +1590,10 @@ rtl_ssa_dce_prelive(std::unordered_set<insn_info *> 
marked)
   return worklist;
 }
 
-static void
-rtl_ssa_dce_mark(std::unordered_set<insn_info *> marked)
+static std::unordered_set<insn_info *>
+rtl_ssa_dce_mark()
 {
+  std::unordered_set<insn_info *> marked{};
   auto worklist = rtl_ssa_dce_prelive(marked);
 
   if (dump_file)
@@ -1577,6 +1626,7 @@ rtl_ssa_dce_mark(std::unordered_set<insn_info *> marked)
   }
 
   // TODO : control dependence
+  return marked;
 }
 
 static void
@@ -1588,6 +1638,7 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> marked)
   // it might be better to iterate over `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 ();
   for (insn_info *insn = crtl->ssa->first_insn(); insn; insn = next)
   {
     if (dump_file)
@@ -1619,7 +1670,7 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> marked)
 
   if (crtl->ssa->verify_insn_changes(changes)) {
     std::cerr << "Changes are correct\n";
-    // crtl->ssa->change_insns(changes);
+    crtl->ssa->change_insns(changes);
   } else {
     std::cerr << "Changes are not correct\n";
   }
@@ -1630,11 +1681,46 @@ rtl_ssa_dce()
 {
   // I can do something like invert phi uid and shift it
   // unordered_set seems to be the easiest option
-  std::unordered_set<insn_info *> marked;
   rtl_ssa_dce_init();
-  debug(crtl->ssa);
+
+  for (rtl_ssa::bb_info* bb : crtl->ssa->bbs()) {
+    // debug(bb);
+    std::cerr << "BASIC BLOCK: " << bb->index() << '\n';
+    std::cerr << "PRINTING INSNS:\n";
+    for (rtl_ssa::insn_info* insn : bb->all_insns()) {
+      std::cerr << "PRINTING INSN\n";
+      debug(insn);
+      if (insn->is_real()) {
+        std::cerr << "RTL PART\n";
+        debug(insn->rtl());
+      } else {
+        std::cerr << "NON REAL INSN\n";
+      }
+
+      rtl_ssa::use_array ua = insn->uses();
+      std::cerr << "USES\n";
+      for (size_t i = 0; i < ua.size(); i++)
+      {
+        std::cerr << "USE: " << i << '\n';
+        ua[i]->def();
+        debug(ua[i]->insn());
+      }
+
+      // rtl_ssa::def_array df = insn->defs();
+      // std::cerr << "DEFS\n";
+      // for (size_t i = 0; i < df.size(); i++)
+      // {
+      //   std::cerr << "DEF: " << i << '\n';
+      //   debug(df[i]->insn());
+      // }
+    }
+
+    std::cerr << "\n\n\n";
+  }
+
+  // debug(crtl->ssa);
   std::cerr << "Next phase: prelive + mark: \n";
-  rtl_ssa_dce_mark(marked);
+  std::unordered_set<insn_info *> marked = rtl_ssa_dce_mark();
   rtl_ssa_dce_sweep(marked);
   rtl_ssa_dce_done();

Reply via email to