https://gcc.gnu.org/g:7cbb0ce1fbec2adad90bd7c14342243ea9505ff9

commit 7cbb0ce1fbec2adad90bd7c14342243ea9505ff9
Author: Ondřej Machota <ondrejmach...@gmail.com>
Date:   Mon Mar 31 11:19:18 2025 +0200

    rtl-ssa-dce: format code

Diff:
---
 gcc/dce.cc | 306 +++++++++++++++++++------------------------------------------
 1 file changed, 94 insertions(+), 212 deletions(-)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index a90a8d9ccf53..d16cec35eb16 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -1325,8 +1325,10 @@ struct offset_bitmap {
     sbitmap m_bitmap;
   
   public:
-    offset_bitmap(size_t size, int offset) : m_offset{offset}, 
m_bitmap{sbitmap_alloc(size)} {}
-    offset_bitmap(int min_index, int max_index) : 
offset_bitmap(size_t(max_index - min_index), min_index) {}
+    offset_bitmap(size_t size, int offset) : m_offset{offset},
+      m_bitmap{sbitmap_alloc(size)} {}
+    offset_bitmap(int min_index, int max_index) : 
+      offset_bitmap(size_t(max_index - min_index), min_index) {}
 
     void clear_bit(int index) {
       bitmap_clear_bit(m_bitmap, index + m_offset);
@@ -1345,75 +1347,7 @@ struct offset_bitmap {
     }
 };
 
-bool side_effects_with_mem (const_rtx x)
-{
-  const RTX_CODE code = GET_CODE (x);
-  switch (code)
-    {
-    case LABEL_REF:
-    case SYMBOL_REF:
-    case CONST:
-    CASE_CONST_ANY:
-    case PC:
-    case REG:
-    case SCRATCH:
-    case ADDR_VEC:
-    case ADDR_DIFF_VEC:
-    case VAR_LOCATION:
-      return false;
-
-    case CLOBBER:
-      /* Reject CLOBBER with a non-VOID mode.  These are made by combine.cc
-        when some combination can't be done.  If we see one, don't think
-        that we can simplify the expression.  */
-      return (GET_MODE (x) != VOIDmode);
-
-    case PRE_INC:
-    case PRE_DEC:
-    case POST_INC:
-    case POST_DEC:
-    case PRE_MODIFY:
-    case POST_MODIFY:
-    case CALL:
-    case UNSPEC_VOLATILE:
-      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;
-
-    default:
-      break;
-    }
-
-  /* Recursively scan the operands of this expression.  */
-
-  {
-    const char *fmt = GET_RTX_FORMAT (code);
-    int i;
-
-    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-      {
-       if (fmt[i] == 'e')
-         {
-           if (side_effects_with_mem (XEXP (x, i)))
-             return true;
-         }
-       else if (fmt[i] == 'E')
-         {
-           int j;
-           for (j = 0; j < XVECLEN (x, i); j++)
-             if (side_effects_with_mem (XVECEXP (x, i, j)))
-               return true;
-         }
-      }
-  }
-  return false;
-}
-
-bool is_ssa_prelive(const_rtx insn) {
+bool is_rtx_prelive(const_rtx insn) {
   switch (GET_CODE(insn)) {
     case PREFETCH:
     case UNSPEC:
@@ -1429,15 +1363,12 @@ bool is_rtx_insn_prelive(rtx_insn *insn) {
   gcc_assert(insn != nullptr);
 
   if (!NONJUMP_INSN_P (insn))
-  {
-    // This handles jumps, debug_insns, call_insn, ...
+    /* This handles jumps, debug_insns, call_insn, ... */
     return true;
-  }
 
-  // TODO : handle calls correctly
   if (CALL_P (insn)
       /* We cannot delete pure or const sibling calls because it is
-        hard to see the result.  */
+              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.  */
@@ -1447,111 +1378,74 @@ bool is_rtx_insn_prelive(rtx_insn *insn) {
     return true;
     // return !find_call_stack_args (as_a <rtx_call_insn *> (insn), false, 
fast, arg_stores);
 
-  // Only rtx_insn should be handled here
+  /* Only rtx_insn should be handled here */
   gcc_assert(GET_CODE(insn) == 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))
+  if (!(cfun->can_delete_dead_exceptions && can_alter_cfg)
+      && !insn_nothrow_p (insn))
     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))
+  if (RTX_FRAME_RELATED_P (insn) && crtl->shrink_wrapped_separate 
+      && find_reg_note (insn, REG_CFA_RESTORE, NULL))
     return true;
 
-  // TODO : asm_noperands???
-
   rtx body = PATTERN(insn);
   switch (GET_CODE(body)) {
     case CLOBBER: // gcc/gcc/testsuite/gcc.c-torture/compile/20000605-1.c
     case USE:
     case VAR_LOCATION:
-    case PREFETCH: // This and following case might be removed since they are 
part of deletable_insn_p_1
-    case TRAP_IF:
+    /* Following cases might be removed since they are part of is_rtx_prelive 
*/
+    case PREFETCH:
+    case TRAP_IF: /* testsuite/gcc.c-torture/execute/20020418-1.c */
     case UNSPEC:
       return true;
 
     case PARALLEL:
       for (int i = XVECLEN (body, 0) - 1; i >= 0; i--)
-        if (is_ssa_prelive (XVECEXP (body, 0, i)))
+        if (is_rtx_prelive (XVECEXP (body, 0, i)))
           return true;
       return false;
 
     default:
-      return is_ssa_prelive (body);
+      return is_rtx_prelive (body);
   }
-
-  // See deletable_insn_p_1 for UNSPEC. TRAP_IF is caught by 
may_trap_or_fault_p
-
-  // may_trap_or_fault_p helps a lot to pass some tests from 
RUNTESTSFLAGS=execute.exp
-  // e. g. this one: testsuite/gcc.c-torture/execute/20020418-1.c
-  // TODO : debug the testcase
-  // It seems that the issue was due to trap_if rtl insn and fixed with 
may_trap_or_fault_p
-  if (side_effects_with_mem(body)) // may_trap_or_fault_p(body) replaced by 
TRAP_IF
-    return true;
-
-  return false;
 }
 
 bool is_prelive(insn_info *insn)
 {
-  if (insn->is_artificial()) // phis are never prelive, bb head + end are 
artificial
+  /* Phi insns are never prelive, bb head + end also are artificial */
+  if (insn->is_artificial())
     return false;
 
-  /*
-   * There are a few functions we can use to detect if an instruction is
-   * inherently live:
-   * rtlanal.cc:
-   *  bool side_effects_p (const_rtx x);
-   *  bool volatile_insn_p (const_rtx x);
-   *
-   * rtlanal.h
-   *  bool has_side_effects (); inside class rtx_properties
-   *
-   * dce.cc:
-   *  static bool deletable_insn_p_1(rtx body); uses bool volatile_insn_p 
(const_rtx x);
-   *  static bool deletable_insn_p(rtx_insn *insn, bool fast, bitmap 
arg_stores);
-   * 
-   * Possibly the most accurate way would be to rewrite `static bool
-   * deletable_insn_p(rtx_insn *insn, bool fast, bitmap arg_stores);`
-   * 
-  */
-
-  // Now, we only have to handle rtx insns
   gcc_assert (insn->is_real());
   auto rtl = insn->rtl();
 
   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?
+    /* 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
-
-
-    // TODO : find something similar to mark_artificial_uses to mark only
-    // artificially-used registers
-    //  check: df_get_regular_block_artificial_uses
-    //  That should fix following test as assume
-    // gcc.c-torture/execute/20000503-1.c - flags register is unused
+    /* this ignores clobbers, which is probably fine */
+
+    /* TODO : find something similar to mark_artificial_uses to mark only
+       artificially-used registers.
+       - df_get_regular_block_artificial_uses
+       That should fix following test as assume
+       gcc.c-torture/execute/20000503-1.c - flags register is unused. Not all
+       hard registers should be marked... */
     if (def->kind() != access_kind::SET)
       continue;
 
-    // We need to perform some kind of reset_unmarked_insns_debug_uses
-    // to be able to reproduce ud_dce - now only 4 tests are falling
-    // because of debug_insn being dependent on parallel with set flags 
-    // gcc.c-torture/execute/20051215-1.c
-    // gcc.c-torture/execute/20100805-1.c
-    // gcc.c-torture/execute/pr39339.c
-    // gcc.c-torture/execute/pr47925.c
-
-    // This might be messed up a bit
+    /* 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
+    /* needed by gcc.c-torture/execute/pr51447.c */
     if (HARD_REGISTER_NUM_P (def->regno())
         && global_regs[def->regno()])
         return true;
@@ -1573,26 +1467,27 @@ bool is_prelive(insn_info *insn)
 
     // TODO : eh?
 
-    // if (def->kind() == access_kind::SET 
-    //     && (HARD_REGISTER_NUM_P(def->regno())
-    //     || (pic_offset_table_rtx != nullptr 
-    //       && def->regno() == REGNO (pic_offset_table_rtx)
-    //       && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER))
-    //   ) {
-    //   // find_reg_note(insn->rtl(), REG_UNUSED, def->regno())
-    //   return true;
-    // }
+    /*
+    if (def->kind() == access_kind::SET 
+        && (HARD_REGISTER_NUM_P(def->regno())
+        || (pic_offset_table_rtx != nullptr 
+          && def->regno() == REGNO (pic_offset_table_rtx)
+          && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER))
+      ) {
+      // find_reg_note(insn->rtl(), REG_UNUSED, def->regno())
+      return true;
+    } */
   }
 
   return is_rtx_insn_prelive(rtl);
 }
 
 static void
-rtl_ssa_dce_mark_live(insn_info *info, vec<insn_info *> &worklist, 
std::unordered_set<insn_info *> &marked)
+rtl_ssa_dce_mark_prelive(insn_info *info, vec<insn_info *> &worklist, 
+      std::unordered_set<insn_info *> &marked)
 {
-  int info_uid = info->uid();
   if (dump_file)
-    fprintf(dump_file, "  Adding insn %d to worklist\n", info_uid);
+    fprintf(dump_file, "Insn %d is prelive\n", info->uid());
 
   marked.emplace(info);
   worklist.safe_push(info);
@@ -1601,17 +1496,10 @@ 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)
 {
-  insn_info *next;
   auto_vec<insn_info *> worklist;
-  for (insn_info *insn = crtl->ssa->first_insn(); insn; insn = next)
-  {
-    next = insn->next_any_insn();
+  for (insn_info * insn : crtl->ssa->all_insns()) {
     if (is_prelive(insn))
-      {
-        rtl_ssa_dce_mark_live(insn, worklist, marked);
-      }
-
-    // Might help to fix -DPREVENT_OPTIMIZATION? (insn->can_be_optimized () || 
insn->is_debug_insn ())
+      rtl_ssa_dce_mark_prelive(insn, worklist, marked);
   }
 
   return worklist;
@@ -1621,85 +1509,77 @@ static std::unordered_set<insn_info *>
 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
+  /* 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 prelive_insns = rtl_ssa_dce_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) {
+      if (set)
         worklist.safe_push(set);
-      }
     }
   }
 
   while (!worklist.is_empty()) {
     set_info* set = worklist.pop();
     insn_info* insn = set->insn();
-    if (!insn) {
+    if (!insn)
       continue;
-    }
-
-    /*
-     * 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
-    */
 
+    /* A phi insn might be visited more times because of having more phi nodes
+       The phi insn is never marked, only phi nodes (phi_info) */
     auto uid = insn->uid();
-    if ((marked.count(insn) > 0) && !insn->is_phi()) {
+    if ((marked.count(insn) > 0) && !insn->is_phi())
       continue;
-    }
 
     marked.emplace(insn);
 
     use_array uses = insn->uses();
     if (insn->is_phi()) {
-      // Each phi node has a unique uid, yeeey
-      // So, only one bitmap (with shift) in needed.
+      /* Each phi node has a unique uid, so only one bitmap (with shift) in
+         might be used. */
       phi_info* pi = as_a<phi_info *> (set);
       auto pi_uid = pi->uid();
-      if (marked_phi_nodes.count(pi) > 0) {
+      if (marked_phi_nodes.count(pi) > 0)
         continue;
-      }
+
       marked_phi_nodes.emplace(pi);
       uses = pi->inputs();
     }
 
     if (dump_file)
-      fprintf(dump_file, "  Adding insn %d to worklist - mark\n", insn->uid());
+      fprintf(dump_file, "Adding insn %d to worklist\n", insn->uid());
     
     for (use_info * use : uses) {
       set_info* parent_set = use->def();
-      if (!parent_set) {
+      if (!parent_set)
         continue;
-      }
 
       worklist.safe_push(parent_set);
     }
   }
 
-  // TODO : control dependence
   return marked;
 }
 
 static void
 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 *>
+  /* We can get the number of items in the `marked` set and create an array
+     of changes with appropriate size */
   auto_vec<insn_change> to_delete;
   for (insn_info * insn : crtl->ssa->all_insns()) {
-    // artificial and marked insns cannot be deleted
+    /* artificial and marked insns cannot be deleted */
     if (insn->is_artificial() || marked.count(insn) > 0)
       continue;
 
     auto change = insn_change::delete_insn(insn);
     to_delete.safe_push(change);
     if (dump_file)
-      fprintf(dump_file, "  Sweeping insn %d\n", insn->uid());
-    // crtl->ssa->change_insn(change);
+      fprintf(dump_file, "Sweeping insn %d\n", insn->uid());
+    /* crtl->ssa->change_insn(change); */
   }
 
   auto attempt = crtl->ssa->new_change_attempt ();
@@ -1709,19 +1589,21 @@ rtl_ssa_dce_sweep(std::unordered_set<insn_info *> 
marked)
   }
 
   gcc_assert (crtl->ssa->verify_insn_changes(changes));
-    // segfault: gcc.c-torture/execute/20000224-1.c
+  /* segfault: gcc.c-torture/execute/20000224-1.c */
   crtl->ssa->change_insns(changes);
 }
 
+// WIP
 static void
 rtl_ssa_dce_transform_insns_to_debug() {
   std::unordered_set<int> is_debug;
-  // TODO : make sure, that phi_nodes have unique id from all insns
   // 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, if insns that use a definition from current insn are all debug
+  /* 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
@@ -1803,36 +1685,36 @@ rtl_ssa_dce_done()
 
   delete crtl->ssa;
   crtl->ssa = nullptr;
-
-  if (dump_file)
-    fprintf(dump_file, "\nFinished running rtl_ssa_dce\n\n");
 }
 
 static unsigned int
 rtl_ssa_dce()
 {
-  // for (int i = 0; i < FIRST_VIRTUAL_REGISTER; ++i) {
-  //   if (global_regs[i] > 0)
-  //     std::cerr << "Global reg needed: " << i << '\n';
-  //   if (fixed_regs[i] > 0) 
-  //     std::cerr << "Fixed reg: " << i << '\n';
-  // }
-  // std::cerr << "RTL SSA BEGIN\n" << std::endl;
   rtl_ssa_dce_init();
   std::unordered_set<insn_info *> marked = rtl_ssa_dce_mark();
   rtl_ssa_dce_sweep(marked);
-  std::cerr << "\033[31m" << "SSA debug start" << "\033[0m" << "\n";
-  debug (crtl->ssa);
-  for (insn_info * insn : crtl->ssa->all_insns()) {
-    if (insn->is_artificial())
-      continue;
-    debug(insn->rtl());
-  }
-  std::cerr << "\033[31m" << "SSA debug end" << "\033[0m" << "\n";
-  rtl_ssa_dce_done();
-  // if (delete_trivially_dead_insns(get_insns (), max_reg_num ())) {
-  //   std::cerr << "\033[31m" << "rtl_ssa_dce did not delete everything :(" 
<< "\033[0m" << "\n";
+  // std::cerr << "\033[31m" << "SSA debug start" << "\033[0m" << "\n";
+  // debug (crtl->ssa);
+  // for (insn_info * insn : crtl->ssa->all_insns()) {
+  //   if (insn->is_artificial())
+  //     continue;
+  //   debug(insn->rtl());
   // }
+  // std::cerr << "\033[31m" << "SSA debug end" << "\033[0m" << "\n";
+  rtl_ssa_dce_done();
+
+  /* We need to perform some kind of reset_unmarked_insns_debug_uses
+     to be able to reproduce ud_dce - now only 4 tests are falling
+     because of debug_insn being dependent on parallel with set flags 
+     - gcc.c-torture/execute/20051215-1.c
+     - gcc.c-torture/execute/20100805-1.c
+     - gcc.c-torture/execute/pr39339.c
+     - gcc.c-torture/execute/pr47925.c */
+
+  /*
+  if (delete_trivially_dead_insns(get_insns (), max_reg_num ())) {
+    std::cerr << "\033[31m" << "rtl_ssa_dce did not delete everything :(" << 
"\033[0m" << "\n";
+  } */
 
   return 0;
 }
@@ -1872,7 +1754,7 @@ namespace
 
     unsigned int execute(function *) final override { return rtl_ssa_dce(); }
 
-  }; // class pass_fast_rtl_dce
+  }; // class pass_rtl_ssa_dce
 
 } // namespace

Reply via email to