https://gcc.gnu.org/g:622c367a5fc67ebbda55c02aba391d86738dc6ad

commit 622c367a5fc67ebbda55c02aba391d86738dc6ad
Author: Ondřej Machota <ondrejmach...@gmail.com>
Date:   Wed Mar 12 13:12:43 2025 +0100

    rtl-ssa-dce: improve marking, but still not correct

Diff:
---
 gcc/dce.cc | 211 +++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 113 insertions(+), 98 deletions(-)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index d1558f2a9798..cfa58f21dc03 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -1390,10 +1390,12 @@ bool side_effects_with_mem (const_rtx x)
       return true;
 
     case MEM: // We might want tu return true iff volatile or mem is a 
destination
+      // write or possible null read
     case ASM_INPUT:
     case ASM_OPERANDS:
            return true;
 
+    // This should rather by RTX_BODY in is_rtx_insn_prelive - like global 
clobber
     case USE:
       return true;
 
@@ -1471,6 +1473,9 @@ 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
+    return true;
+
   if (side_effects_with_mem(body) || can_throw_internal(body))
     return true;
 
@@ -1588,6 +1593,7 @@ rtl_ssa_dce_mark()
   auto_vec<set_info *> worklist_new{};
   for (auto && item : worklist) {
     insn_info * insn = item;
+    std::cerr << "cp Current: " << insn->uid() << '\n';
     for (auto&& use : insn->uses()) {
       set_info* set = use->def();
       if (set) {
@@ -1603,118 +1609,119 @@ rtl_ssa_dce_mark()
       continue;
     }
 
-    if (!(marked.count(insn) > 0))
-    {
-      marked.emplace(insn);
-    }
+    /*
+     * 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';
+    // if (insn->uid() == -21) {
+      // std::cerr << "Insn -21 phi? " << insn->is_phi() << '\n';
+    // }
 
-    // use_array uses = insn->uses();
-    if (insn->is_phi()) {
-      phi_info* pi = as_a<phi_info *> (set);
-      
-      for (auto && input : pi->inputs()) {
-        use_info* use = input;
-        set_info* parent_set = use->def();
-        if (!parent_set) { // Clobber...
-          continue;
-        }
-
-        worklist_new.safe_push(parent_set);
-      }
-    } else {
-      if (dump_file)
-        fprintf(dump_file, "  Adding insn %d to worklist - mark\n", 
insn->uid());
-      
-      for (auto && use__ : insn->uses()) {
-        use_info * use = use__;
-        set_info* parent_set = use->def();
-        if (!parent_set) {
-          continue;
-        }
-
-        worklist_new.safe_push(parent_set);
-      }
+    if ((marked.count(insn) > 0)) {
+      continue;
     }
-  }
 
-  if (dump_file)
-    fprintf(dump_file, "Finished inherently live, marking parents\n");
-  while (!worklist.is_empty())
-  {
-    insn_info *insn = worklist.pop();
+    marked.emplace(insn);
+
     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';
-      }
+      phi_info* pi = as_a<phi_info *> (set);
+      uses = pi->inputs();
     }
 
     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) {
+      fprintf(dump_file, "  Adding insn %d to worklist - mark\n", insn->uid());
+    
+    for (auto && use__ : uses) {
+      use_info * use = use__;
+      set_info* parent_set = use->def();
+      if (!parent_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);
-      }
+      worklist_new.safe_push(parent_set);
     }
+  }
+
+  // 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());
-  }
+  // for (auto&& insn : marked) {
+  //   if (dump_file)
+  //     fprintf(dump_file, "  Marked insn: %d\n", insn->uid());
+  // }
 
   // TODO : control dependence
   return marked;
@@ -1729,6 +1736,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;
   for (insn_info *insn = crtl->ssa->first_insn(); insn; insn = next)
   {
     if (dump_file)
@@ -1746,6 +1754,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";
         auto change = insn_change::delete_insn(insn);
         // crtl->ssa->possibly_queue_changes(change);
         to_delete.safe_push(change);
@@ -1753,14 +1762,18 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> 
marked)
       }
     }
   }
+
+  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;
   if (crtl->ssa->verify_insn_changes(changes)) {
-    //std::cerr << "Changes are correct\n";
+    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";
@@ -1775,7 +1788,9 @@ rtl_ssa_dce()
 
   //std::cerr << "Next phase: prelive + mark: \n";
   std::unordered_set<insn_info *> marked = rtl_ssa_dce_mark();
+  std::cerr << "Marking done\n";
   rtl_ssa_dce_sweep(marked);
+  std::cerr << "Sweeping done\n";
   rtl_ssa_dce_done();
 
   return 0;

Reply via email to