https://gcc.gnu.org/g:0a294fa7512b77426e8a5106f9679439a7729f74

commit 0a294fa7512b77426e8a5106f9679439a7729f74
Author: Ondřej Machota <ondrejmach...@gmail.com>
Date:   Tue Feb 25 08:44:25 2025 +0100

    rtl-ssa: dce another prelive conditions

Diff:
---
 gcc/dce.cc | 125 ++++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 100 insertions(+), 25 deletions(-)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index 49bc4c3c6780..f51f27dbd143 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -17,6 +17,8 @@ You should have received a copy of the GNU General Public 
License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
+#include <iostream>
+#include <ostream>
 #define INCLUDE_ALGORITHM
 #define INCLUDE_FUNCTIONAL
 #define INCLUDE_ARRAY
@@ -1305,13 +1307,29 @@ public:
 } // namespace
 
 
+bool sets_global_register(const_rtx rtx) {
+  auto code = GET_CODE(rtx);
+  if (GET_RTX_CLASS(code) != RTX_INSN)
+    return false;
+
+  return sets_global_register(static_cast<const rtx_insn*>(rtx));
+}
+
+// We should mark stack registers
 bool sets_global_register(rtx_insn* insn) {
   rtx set = single_set(insn);
   if (!set)
     return false;
 
   rtx dest = SET_DEST(set);
-  if (REG_P(dest) && HARD_REGISTER_NUM_P(REGNO(dest)) && 
global_regs[REGNO(dest)]) {
+
+  // TODO : rewrite to simple return
+  std::cerr << "first pseudo: " << FIRST_PSEUDO_REGISTER << '\n';
+  std::cerr << "register: " << REGNO(dest) << "\n";
+  debug(insn);
+  // If I understand correctly, global_regs[i] is 1 iff reg i is used
+  if (REG_P(dest) && HARD_REGISTER_NUM_P(REGNO(dest))) { // && 
global_regs[REGNO(dest)]
+    std::cerr << "sets_global_register: true\n";
     return true;
   }
 
@@ -1329,6 +1347,7 @@ bool is_control_flow(rtx_code code) {
     case RETURN:
     case SIMPLE_RETURN:
     case EH_RETURN:
+    case LABEL_REF:
       return true;
 
     default:
@@ -1336,13 +1355,66 @@ bool is_control_flow(rtx_code code) {
   }
 }
 
-bool handle_rtl_previle(rtx_insn *insn) {
-  // TODO : handle everything except parallel
+bool is_unary_mem_modification(rtx_code code) {
+  switch (code) {
+    case PRE_DEC:
+    case PRE_INC:
+    case POST_DEC:
+    case POST_INC:
+    case PRE_MODIFY:
+    case POST_MODIFY:
+      return true;
+
+    default:
+      return false;
+  }
+}
+
+bool is_rtx_insn_prelive(const_rtx rtx) {
+  if (rtx == nullptr) {
+    return false;
+  }
+
+  auto code = GET_CODE(rtx);
+  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
+    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)
+    return true;
+
+  if (is_unary_mem_modification(code))
+    return true;
+
+  // TODO : parallel, {pre,post}_{int,dec}, {pre,post}_modify, 
may_trap_or_fault_p
+  // 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))) {
+      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;
 }
 
 bool is_prelive(insn_info *insn)
 {
-  if (insn->is_artificial()) // phis are never prelive
+  if (insn->is_artificial()) // phis are never prelive, bb head + end are 
artificial
     return false;
 
   /*
@@ -1377,8 +1449,8 @@ bool is_prelive(insn_info *insn)
   // We need to describe all possible prelive instructions, a list of all the 
instructions is inside `rtl.def`
 
   // Control flow
-  auto rtl_code = GET_CODE(rtl);
-  if (is_control_flow(rtl_code))
+  auto code = GET_CODE(rtl);
+  if (is_control_flow(code))
     return true;
 
   // Mark set of a global register
@@ -1386,9 +1458,16 @@ bool is_prelive(insn_info *insn)
     return true;
 
   // Call is inside side_effects_p
-  if (volatile_refs_p(rtl) || can_throw_internal(rtl) || BARRIER_P(rtl) || 
rtl_code == PREFETCH)
+  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)
     return true;
 
+  if (code == PARALLEL) {
+
+  }
+
   // TODO : handle parallel, {pre,post}_{int,dec}, {pre,post}_modify
 
   return false;
@@ -1421,9 +1500,7 @@ rtl_ssa_dce_mark_live(insn_info *info, vec<insn_info *> 
&worklist, std::unordere
 {
   int info_uid = info->uid();
   if (dump_file)
-  {
     fprintf(dump_file, "  Adding insn %d to worklist\n", info_uid);
-  }
 
   marked.emplace(info);
   worklist.safe_push(info);
@@ -1436,10 +1513,6 @@ rtl_ssa_dce_prelive(std::unordered_set<insn_info *> 
marked)
   auto_vec<insn_info *> worklist;
   for (insn_info *insn = crtl->ssa->first_insn(); insn; insn = next)
   {
-    if (dump_file)
-    {
-      fprintf(dump_file, "Insn: %d\n", insn->uid());
-    }
     next = insn->next_any_insn();
     /*
     I would like to mark visited instruction with something like plf (Pass 
local flags) as in gimple
@@ -1482,6 +1555,7 @@ rtl_ssa_dce_mark(std::unordered_set<insn_info *> marked)
     def_array defs = insn->defs(); // array - because of phi?
     if (dump_file)
       fprintf(dump_file, "Looking at: %d, defs: %d\n", insn->uid(), 
defs.size());
+    // I hope that the ssa form uses defs and we don't have to scan inner 
content
     for (size_t i = 0; i < defs.size(); i++)
     {
       insn_info *parent_insn = defs[i]->insn();
@@ -1499,7 +1573,7 @@ rtl_ssa_dce_mark(std::unordered_set<insn_info *> marked)
       }
     }
 
-    auto bb = insn->bb();
+    // auto bb = insn->bb();
   }
 
   // TODO : control dependence
@@ -1527,11 +1601,7 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> marked)
       {
         fprintf(dump_file, "  Sweeping insn %d\n", insn->uid());
       }
-      // rtx_insn* rtl = insn->rtl();
-      // How to delete phis?
-      // if (rtl != nullptr) {
-      //   delete_insn(rtl);
-      // }
+
       if (insn->rtl())
       {
         auto change = insn_change::delete_insn(insn);
@@ -1539,17 +1609,20 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> 
marked)
         to_delete.safe_push(change);
         // crtl->ssa->change_insn(change);
       }
-      // insn->rtl()->set_deleted();
     }
   }
   
-  auto_vec<insn_change*> changes{to_delete.length()};
-  for (auto i = 0; i != to_delete.length(); ++i) {
-    changes[i] = &to_delete[i];
+  auto_vec<insn_change*> changes(to_delete.length());
+  for (size_t i = 0; i != to_delete.length(); ++i) {
+    changes.safe_push(&to_delete[i]);
   }
 
-  crtl->ssa->change_insns(changes);
-  // if (verify_insn_changes())
+  if (crtl->ssa->verify_insn_changes(changes)) {
+    std::cerr << "Changes are correct\n";
+    // crtl->ssa->change_insns(changes);
+  } else {
+    std::cerr << "Changes are not correct\n";
+  }
 }
 
 static unsigned int
@@ -1559,6 +1632,8 @@ rtl_ssa_dce()
   // unordered_set seems to be the easiest option
   std::unordered_set<insn_info *> marked;
   rtl_ssa_dce_init();
+  debug(crtl->ssa);
+  std::cerr << "Next phase: prelive + mark: \n";
   rtl_ssa_dce_mark(marked);
   rtl_ssa_dce_sweep(marked);
   rtl_ssa_dce_done();

Reply via email to