[gcc(refs/users/omachota/heads/rtl-ssa-dce)] rtl-ssa-dce: bug report
Ondrej Machota
omachota@gcc.gnu.org
Thu Jun 19 22:02:35 GMT 2025
https://gcc.gnu.org/g:e6b162ba3f9c3b26f57e7f00dbfa8d2dc8656cf8
commit e6b162ba3f9c3b26f57e7f00dbfa8d2dc8656cf8
Author: Ondřej Machota <ondrejmachota@gmail.com>
Date: Fri Jun 20 00:01:49 2025 +0200
rtl-ssa-dce: bug report
Diff:
---
gcc/cse.cc | 2 +-
gcc/dce.cc | 517 +++---------------------------------------------
gcc/fwprop.cc | 2 +-
gcc/passes.def | 5 +-
gcc/rtl-ssa/changes.cc | 24 +--
gcc/rtl-ssa/functions.h | 2 +-
6 files changed, 34 insertions(+), 518 deletions(-)
diff --git a/gcc/cse.cc b/gcc/cse.cc
index 9c0924d73e1d..70d5caac4cac 100644
--- a/gcc/cse.cc
+++ b/gcc/cse.cc
@@ -7639,7 +7639,7 @@ rest_of_handle_cse2 (void)
bypassed safely. */
cse_condition_code_reg ();
- // delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
if (tem == 2)
{
diff --git a/gcc/dce.cc b/gcc/dce.cc
index 2a203b673f32..77ff0a4d2791 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -42,7 +42,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "dbgcnt.h"
#include "rtl-iter.h"
-#include <unordered_set>
using namespace rtl_ssa;
@@ -1318,9 +1317,13 @@ public:
} // namespace
-// TODO: naalokovat prazdnou a pak resize
-// -flto_partition=none
-// -ftime_report a v build adresari zkusit insn*.cc (emit, match, recog)
+rtl_opt_pass *
+make_pass_fast_rtl_dce (gcc::context *ctxt)
+{
+ return new pass_fast_rtl_dce (ctxt);
+}
+
+// offset_bitmap is a wrapper around sbitmap which takes care of negative indices
struct offset_bitmap
{
private:
@@ -1373,17 +1376,10 @@ private:
void mark_prelive_insn (insn_info *, auto_vec<set_info *> &);
auto_vec<set_info *> mark_prelive ();
void mark ();
- std::unordered_set<insn_info *> propagate_dead_phis ();
void reset_dead_debug_insn (insn_info *);
void reset_dead_debug ();
void sweep ();
- void debugize_insn (insn_info *);
-
- void unmark_debugizable(insn_info *, sbitmap);
- sbitmap find_debugizable(const std::unordered_set<insn_info *> &);
- void debugize_insns (const sbitmap);
-
offset_bitmap m_marked;
sbitmap mm_marked_phis;
};
@@ -1403,49 +1399,14 @@ rtl_ssa_dce::is_rtx_pattern_prelive (const_rtx insn)
}
}
-// odebrat auto
-
bool
rtl_ssa_dce::can_delete_call (const_rtx insn)
{
gcc_checking_assert (CALL_P (insn));
- // We cannot delete pure or const sibling calls because it is
- // hard to see the result.
- // if (!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)
-
- // && cfun->can_delete_dead_exceptions
- // )
- // return true;
- // Don't delete calls that may throw if we cannot do so.
-
- // pridat assert na const nebo pure
- // pouzivat gcc_checking_assert();
if (cfun->can_delete_dead_exceptions)
return true;
- // if (!insn_nothrow_p (insn))
- // return false;
return insn_nothrow_p (insn);
-
- // UD_DCE ignores this and works...
- /* If we can't alter cfg, even when the call can't throw exceptions, it
- might have EDGE_ABNORMAL_CALL edges and so we shouldn't delete such
- calls. */
- // gcc_assert (CALL_P (insn));
- // if (BLOCK_FOR_INSN (insn) && BB_END (BLOCK_FOR_INSN (insn)) == insn)
- // {
- // edge e;
- // edge_iterator ei;
-
- // FOR_EACH_EDGE (e, ei, BLOCK_FOR_INSN (insn)->succs)
- // if ((e->flags & EDGE_ABNORMAL_CALL) != 0)
- // return false;
- // }
- // return true;
}
bool
@@ -1503,8 +1464,8 @@ rtl_ssa_dce::is_rtx_prelive (const_rtx insn)
bool
rtl_ssa_dce::is_prelive (insn_info *insn)
{
- // bb head and end contain artificial uses that we need to mark as prelive
- // debug instructions are also prelive, however, they are not added to the
+ // Bb head and end contain artificial uses that we need to mark as prelive.
+ // Debug instructions are also prelive, however, they are not added to the
// worklist
if (insn->is_bb_head () || insn->is_bb_end () || insn->is_debug_insn ())
return true;
@@ -1522,21 +1483,20 @@ rtl_ssa_dce::is_prelive (insn_info *insn)
gcc_assert (def->is_reg ());
- // we should not delete the frame pointer because of the dward2frame pass
+ // We should not delete the frame pointer because of the dward2frame pass
if (frame_pointer_needed && def->regno () == HARD_FRAME_POINTER_REGNUM)
return true;
- // skip clobbers, they are handled inside is_rtx_prelive
+ // Skip clobbers, they are handled inside is_rtx_prelive
if (def->kind () == access_kind::CLOBBER)
continue;
gcc_assert (def->kind () == access_kind::SET);
- // 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;
- // what about reload? check cse.cc
unsigned int picreg = PIC_OFFSET_TABLE_REGNUM;
if (picreg != INVALID_REGNUM && fixed_regs[picreg]
&& def->regno () == picreg)
@@ -1546,6 +1506,7 @@ rtl_ssa_dce::is_prelive (insn_info *insn)
return is_rtx_prelive (insn->rtl ());
}
+// Marks INSN and adds its uses to worklist if INSN is not a debug instruction
void
rtl_ssa_dce::mark_prelive_insn (insn_info *insn, auto_vec<set_info *> &worklist)
{
@@ -1553,7 +1514,7 @@ rtl_ssa_dce::mark_prelive_insn (insn_info *insn, auto_vec<set_info *> &worklist)
fprintf (dump_file, "Insn %d marked as prelive\n", insn->uid ());
m_marked.set_bit(insn->uid ());
- // debug instruction are not added to worklist not to wake up possibly dead
+ // Debug instruction are not added to worklist. They would wake up possibly dead
// instructions
if (insn->is_debug_insn ())
return;
@@ -1566,6 +1527,7 @@ rtl_ssa_dce::mark_prelive_insn (insn_info *insn, auto_vec<set_info *> &worklist)
}
}
+// Scans all instructions and marks all which are prelive
auto_vec<set_info *>
rtl_ssa_dce::mark_prelive ()
{
@@ -1582,7 +1544,6 @@ rtl_ssa_dce::mark_prelive ()
return worklist;
}
-// kometare + PARAMETRY kapitalkami
void
rtl_ssa_dce::mark ()
{
@@ -1594,7 +1555,7 @@ rtl_ssa_dce::mark ()
{
set_info *set = worklist.pop ();
insn_info *insn = set->insn ();
- if (!insn) // TODO: is this possible?
+ if (!insn)
continue;
// Skip already visited visited instructions.
@@ -1636,15 +1597,15 @@ rtl_ssa_dce::mark ()
void
rtl_ssa_dce::reset_dead_debug_insn (insn_info *insn)
{
- gcc_assert (insn->is_debug_insn ());
+ gcc_checking_assert (insn->is_debug_insn ());
if (dump_file)
fprintf (dump_file, "Resetting debug insn: %d\n", insn->uid ());
m_marked.clear_bit (insn->uid ());
+ INSN_VAR_LOCATION_LOC (insn->rtl ()) = gen_rtx_UNKNOWN_VAR_LOC ();
insn_change change (insn);
change.new_uses = {};
- INSN_VAR_LOCATION_LOC (insn->rtl ()) = gen_rtx_UNKNOWN_VAR_LOC ();
crtl->ssa->change_insn (change);
}
@@ -1658,37 +1619,25 @@ rtl_ssa_dce::reset_dead_debug ()
if (!insn->is_debug_insn ())
continue;
- // When propagate_dead_phis is ready, check if insn is in marked. If true,
- // then try to create debug instructions RTL SSA does not contain debug
- // insntructions... we have to make sure that uses are correct
-
- // TODO : use iterate_safely?
for (use_info *use : insn->uses ())
{
def_info *def = use->def ();
insn_info *parent_insn = def->insn ();
- // Is this check needed?
if (parent_insn == nullptr)
continue;
// If we depend on a dead instruction, clear current instruction uses.
- bool shouldReset = false;
+ bool is_parent_marked = false;
if (parent_insn->is_phi ()) {
- shouldReset = bitmap_bit_p(mm_marked_phis, static_cast<phi_info *> (def)->uid ());
+ auto phi = static_cast<phi_info *> (def);
+ is_parent_marked = bitmap_bit_p(mm_marked_phis, phi->uid ());
} else {
- shouldReset = m_marked.get_bit(parent_insn->uid ());
+ is_parent_marked = m_marked.get_bit(parent_insn->uid ());
}
- if (shouldReset) {
+ if (!is_parent_marked) {
reset_dead_debug_insn (insn);
break;
}
-
- // sbitmap marked = parent_insn->is_phi () ? mm_marked_phis : mm_marked;
- // int uid = parent_insn->is_phi () ? static_cast<phi_info *> (def)->uid () : parent_insn->uid () + offset;
- // if (!bitmap_bit_p (marked, uid)) {
- // reset_dead_debug_insn (insn);
- // break;
- // }
}
}
}
@@ -1714,10 +1663,6 @@ rtl_ssa_dce::sweep ()
auto change = insn_change::delete_insn (insn);
to_delete.safe_push (std::move (change));
-
- // If we use following way with reverse_nondebug_insns, not all insns seem
- // to be deleted...
- // crtl->ssa->change_insn(change);
}
auto_vec<insn_change *> changes (to_delete.length ());
@@ -1731,14 +1676,10 @@ rtl_ssa_dce::sweep ()
fprintf (dump_file, "DCE: finish sweep phase\n");
}
-#include <iostream>
-
unsigned int
rtl_ssa_dce::execute (function *fn)
{
calculate_dominance_info (CDI_DOMINATORS);
- // internal compiler error: gcc.c-torture/execute/20040811-1.c -
- // rtl_ssa::function_info::add_phi_nodes
crtl->ssa = new rtl_ssa::function_info (fn);
int real_max = 0, artificial_min = 0;
std::size_t count = 0;
@@ -1750,48 +1691,18 @@ rtl_ssa_dce::execute (function *fn)
}
m_marked.resize(artificial_min, real_max + 1);
- // std::cout << "real_max: " << real_max << '\n';
- // std::cout << "artificial_min: " << artificial_min << '\n';
- // std::cout << "total: " << real_max - artificial_min + 3 << '\n';
- // std::cout << "count: " << count << '\n';
unsigned int phi_node_max = 0;
for (ebb_info *ebb : crtl->ssa->ebbs ())
for (phi_info *phi : ebb->phis ())
phi_node_max = std::max (phi_node_max, phi->uid ());
- // std::cout << "phi_node_max: " << phi_node_max << '\n';
mm_marked_phis = sbitmap_alloc(phi_node_max + 1);
bitmap_clear(mm_marked_phis);
- if (dump_file)
- dump (dump_file, crtl->ssa);
-
- // std::cout << '\n' << function_name(cfun) << '\n';
- // std::cout << "HARD_FRAME_POINTER_IS_ARG_POINTER: " <<
- // HARD_FRAME_POINTER_IS_ARG_POINTER << '\n'; std::cout <<
- // "HARD_FRAME_POINTER_IS_FRAME_POINTER: " <<
- // HARD_FRAME_POINTER_IS_FRAME_POINTER << '\n'; std::cout <<
- // "HARD_FRAME_POINTER_REGNUM: " << HARD_FRAME_POINTER_REGNUM << '\n';
- // std::cout << "FRAME_POINTER_REGNUM: " << FRAME_POINTER_REGNUM << '\n';
- // std::cout << "fixed_regs[HARD_FRAME_POINTER_REGNUM]: " <<
- // (fixed_regs[HARD_FRAME_POINTER_REGNUM] == 1) << '\n'; std::cout <<
- // "fixed_regs[FRAME_POINTER_REGNUM]: " << (fixed_regs[FRAME_POINTER_REGNUM]
- // == 1) << '\n'; std::cout << "global_regs[HARD_FRAME_POINTER_REGNUM]: " <<
- // (global_regs[HARD_FRAME_POINTER_REGNUM] == 1) << '\n'; std::cout <<
- // "global_regs[FRAME_POINTER_REGNUM]: " << (global_regs[FRAME_POINTER_REGNUM]
- // == 1) << '\n'; std::cout << "frame_pointer_needed: " <<
- // frame_pointer_needed << '\n';
-
mark ();
if (MAY_HAVE_DEBUG_BIND_INSNS)
- {
- auto dead_phis = propagate_dead_phis();
- auto debugizable = find_debugizable(dead_phis);
- debugize_insns(debugizable);
-
reset_dead_debug ();
- }
sweep ();
free_dominance_info (CDI_DOMINATORS);
@@ -1804,388 +1715,6 @@ rtl_ssa_dce::execute (function *fn)
return 0;
}
-// mark instructions that depend on a dead phi
-std::unordered_set<insn_info *>
-rtl_ssa_dce::propagate_dead_phis ()
-{
- std::unordered_set<phi_info *> visited_dead_phis;
- std::unordered_set<insn_info *> depends_on_dead_phi;
- auto_vec<set_info *> worklist;
-
- // add dead phis to worklist
- for (ebb_info *ebb : crtl->ssa->ebbs ())
- {
- for (phi_info *phi : ebb->phis ())
- {
- if (bitmap_bit_p (mm_marked_phis, phi->uid ()))
- continue;
-
- worklist.safe_push (phi);
- }
- }
-
- // suppose that debug insns are marked - non marked will be removed later
- // propagate dead phis via du chains and unmark reachable debug instructions
- while (!worklist.is_empty ())
- {
- set_info *set = worklist.pop ();
- insn_info *insn = set->insn ();
-
- if (insn->is_debug_insn ())
- {
- if (dump_file)
- fprintf (dump_file, "Debug insns %d depends on dead phi.\n",
- insn->uid ());
-
- m_marked.clear_bit (insn->uid ());
- // debug instructions dont have chains
- continue;
- }
-
- // mark
- if (insn->is_phi ())
- {
- gcc_checking_assert (!bitmap_bit_p(mm_marked_phis, static_cast<phi_info *> (set)->uid ()));
- visited_dead_phis.emplace (static_cast<phi_info *> (set));
- }
- else
- {
- gcc_checking_assert (!m_marked.get_bit (insn->uid ()));
- depends_on_dead_phi.emplace (insn);
- }
-
- for (use_info *use : set->all_uses ())
- {
- if (use->is_in_phi ())
- {
- // do not add already visited dead phis
- if (visited_dead_phis.count (use->phi ()) == 0)
- worklist.safe_push (use->phi ());
- }
- else
- {
- gcc_assert (use->is_in_any_insn ());
- // add all defs from insn to worklist
- for (def_info *def : use->insn ()->defs ())
- {
- if (def->kind () != access_kind::SET)
- continue;
-
- worklist.safe_push (static_cast<set_info *> (def));
- }
- }
- }
- }
-
- return depends_on_dead_phi;
-}
-
-void
-rtl_ssa_dce::debugize_insn (insn_info *insn)
-{
-
-}
-
-struct register_replacement {
- unsigned int regno;
- rtx expr;
-};
-
-static rtx
-replace_dead_reg(rtx x, const_rtx old_rtx ATTRIBUTE_UNUSED, void *data)
-{
- auto replacement = static_cast<register_replacement *>(data);
-
- if (REG_P (x) && REGNO (x) >= FIRST_VIRTUAL_REGISTER && replacement->regno == REGNO (x))
- {
- if (GET_MODE (x) == GET_MODE (replacement->expr))
- return replacement->expr;
- return lowpart_subreg (GET_MODE (x), replacement->expr, GET_MODE (replacement->expr));
- }
-
- return NULL_RTX;
-}
-
-// visit every marked instruction in INSN dependency tree and unmark it
-void
-rtl_ssa_dce::unmark_debugizable (insn_info *insn, sbitmap debugizable)
-{
- auto_vec<insn_info *> worklist;
- gcc_checking_assert (!insn->is_artificial ());
-
- bitmap_set_bit (debugizable, insn->uid ());
- worklist.safe_push (insn);
-
- // process all marked dependencies and unmark them
- while (!worklist.is_empty ()) {
- insn_info *current = worklist.pop ();
- int current_uid = current->uid ();
-
- // skip instruction that are not marked
- if (!bitmap_bit_p(debugizable, current_uid))
- continue;
-
- bitmap_clear_bit(debugizable, current_uid);
-
- // add all marked dependencies to the worklist
- for (def_info *def : current->defs())
- {
- if (def->kind() != access_kind::SET) // skip clobbers
- continue;
-
- auto *set = static_cast<set_info *>(def);
- for (use_info *use : set->all_uses())
- {
- // this phi node might not be dead
- if (use->is_in_phi ())
- continue;
-
- insn_info *use_insn = use->insn();
-
- // artificial instruction will never be debugizable
- if (use_insn->is_artificial ())
- continue;
-
- if (bitmap_bit_p(debugizable, use_insn->uid()))
- worklist.safe_push (use_insn);
- }
- }
- }
-}
-
-// return a bitmap which describes whether an instruction can be debugized
-// - that means replaced with a debug instruction
-sbitmap
-rtl_ssa_dce::find_debugizable(const std::unordered_set<insn_info *> &depends_on_dead_phi)
-{
- // only real instructions can be turned to debug instructions
- sbitmap debugizable = sbitmap_alloc (get_max_uid () + 1);
- bitmap_clear(debugizable);
-
- for (insn_info *insn : crtl->ssa->reverse_all_insns ()) {
- // Skip live nondebug instrunctions. Debug instructions are by default live
- // and we cannot skip them here - they have to be marked as debugizable
- if (insn->is_artificial () ||
- (m_marked.get_bit (insn->uid ()) && !insn->is_debug_insn()))
- continue;
-
- // instructions that depend on a dead phi node cannot be debugized
- if (depends_on_dead_phi.count (insn) > 0) {
- if (insn->is_debug_insn ())
- reset_dead_debug_insn (insn);
-
- // we don't have to call unmark_debugizable, because a dead nondebug
- // instructions that depends on a dead phi won't be turned into a
- // debug instrunction
- continue;
- }
-
- // handle debug instrunctions - mark them and skip
- if (insn->is_debug_insn ()) {
- bitmap_set_bit (debugizable, insn->uid ());
- continue;
- }
-
- // this insn may have some debugizable dependencies and if we find that
- // current insn is not debugizable, we have to reset those dependencies
-
- rtx_insn *rtl = insn->rtl ();
- def_array defs = insn->defs ();
- rtx rtx_set;
-
- // If insn has debug uses and will be deleted, signalize it
- if (!MAY_HAVE_DEBUG_BIND_INSNS ||
- (rtx_set = single_set (rtl)) == NULL_RTX ||
- side_effects_p (SET_SRC (rtx_set)) ||
- asm_noperands (PATTERN (rtl)) >= 0)
- {
- std::cerr << "FAILED TO CREATE DEBUG\n";
- unmark_debugizable(insn, debugizable);
- continue;
- }
-
- // insn is definitely a single_set, following if statement is useless:
- if (insn->num_defs () != 1)
- {
- gcc_assert (false);
- if (insn->num_defs() > 1)
- unmark_debugizable(insn, debugizable);
- std::cerr << "FAILED TO CREATE DEBUG\n";
- continue;
- }
-
- def_info *def = *defs.begin ();
- if (def->kind () != access_kind::SET) // Skip clobbers
- continue;
-
- set_info *set = static_cast<set_info *> (def);
-
- // if some dependent is a debugizable
- bool has_debug_uses = false;
- for (use_info *use : set->all_uses())
- {
- // skip phi nodes
- if (use->is_in_phi ())
- continue;
-
- insn_info *use_insn = use->insn();
- if (use_insn->is_artificial ())
- continue;
-
- if (bitmap_bit_p(debugizable, use_insn->uid ())) {
- has_debug_uses = true;
- break;
- }
- }
- // if (!set->has_nondebug_insn_uses ())
- if (!has_debug_uses)
- continue;
-
- bitmap_set_bit (debugizable, insn->uid ());
- }
-
- return debugizable;
-}
-
-// create new debug instructions according to the DEBUGIZABLE sbitmap
-void
-rtl_ssa_dce::debugize_insns (const sbitmap debugizable)
-{
- for (insn_info *insn : crtl->ssa->reverse_all_insns ())
- {
- if (insn->is_artificial () ||
- insn->is_debug_insn() ||
- !bitmap_bit_p(debugizable, insn->uid ()))
- continue;
-
- rtx_insn *rtl = insn->rtl ();
- def_array defs = insn->defs ();
- rtx rtx_set = single_set (rtl);
- def_info *def = *defs.begin ();
- gcc_checking_assert (def->kind () != access_kind::SET);
-
- set_info *set = static_cast<set_info *> (def);
-
- // turn instruction into debug
- rtx dval = make_debug_expr_from_rtl (SET_DEST (rtx_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 (rtx_set)),
- DEBUG_EXPR_TREE_DECL (dval),
- SET_SRC (rtx_set),
- VAR_INIT_STATUS_INITIALIZED);
-
- obstack_watermark watermark = crtl->ssa->new_change_attempt();
- insn_info *debug_insn = crtl->ssa->create_insn(watermark, DEBUG_INSN, bind_var_loc);
- insn_change change(debug_insn);
- change.new_uses = insn->uses();
- change.move_range = insn_range_info(insn);
- debug (change);
-
- if (!rtl_ssa::restrict_movement (change))
- std::cerr << "change move range location does not exists\n";
- crtl->ssa->change_insn(change);
- // rtx_insn *bind = emit_debug_insn_before (bind_var_loc, rtl);
-
- register_replacement replacement;
- for (use_info *u : set->all_uses ()) {
- // TODO: transform dependent insns
- if (u->is_artificial())
- continue;
-
- replacement.regno = u->regno();
- replacement.expr = dval;
-
- // if debugizable -> replace
-
- simplify_replace_fn_rtx(INSN_VAR_LOCATION_LOC(rtl), NULL_RTX, replace_dead_reg, &replacement);
- }
-
- // pr113089.c
- if (insn->uses().size() > 0) {
- // std::cerr << "Insn has uses...\n";
- }
-
- // debug (bind_var_loc);
- // debug (insn);
- // debug (change.insn ());
- // debug (crtl->ssa);
-
- // note:
- // 1. Walk over all insns from last to first. If an insntruction can be
- // debugized, update a bitmap. If the instruction is dead, walk over
- // its dependencies with worklist and reset the bitmap for visited
- // instructions.
- // 2. Do the actual debugizing.
-
- // rtx set;
- // // debugize_insns should be called only if MAY_HAVE_DEBUG_BIND_INSNS
- // if (MAY_HAVE_DEBUG_BIND_INSNS
- // && (set = single_set (rtl)) != NULL_RTX
- // && !(*defs.begin ())->has_nondebug_insn_uses()
- // // && is_dead_reg (SET_DEST (set), counts)
- // // Proc tam byla tato podminka?
- // // - debug statementy se sypou za kazdou definici ve zdrojaku, tedy
- // // proto se chci ptat na to, kdyz existuje debug pouziti, tak je to
- // // zajimava promenna
- // /* Used at least once in some DEBUG_INSN. */
- // // && counts[REGNO (SET_DEST (set)) + nreg] > 0
- // // Tohle je ten bind nebo cast debug instrukce?
- // /* And set exactly once. */
- // // && counts[REGNO (SET_DEST (set)) + nreg * 2] == 1
- // && !side_effects_p (SET_SRC (set))
- // && asm_noperands (PATTERN (rtl)) < 0)
- // {
-
- // }
- }
-
- sbitmap_free (debugizable);
- // TODO: check that all of the debug insn uses are live,
- // otherwise reset the instruction
-}
-
-static void
-test (insn_info *insn)
-{
- // Radeji bych zde videl pridani dval do rtl ssa
- // crtl->ssa->create_insn(watermark, DEBUG_INSN, rtx pat);
-
- // TODO : change ssa form - we have to keep uses in the first debug insn and
- // delete other instructions
- // make dval available in the following iteration
-}
-
-// static auto_vec<insn_change>
-// wip (std::unordered_set<insn_info *> &marked,
-// std::unordered_set<phi_info *> &marked_phis)
-// {
-// std::unordered_set<insn_info *> depends_on_dead_phi = propagate_dead_phis ();
-// for (insn_info *insn : crtl->ssa->all_insns ())
-// {
-// if (insn->is_phi ()) // insn->is_artificial() ??
-// continue;
-
-// // skip marked instructions
-// if (marked.count (insn) > 0) // debug instruction are still alive
-// continue;
-
-// // we cannot create debug instruction if we depend on a dead phi
-// if (depends_on_dead_phi.count (insn) > 0)
-// continue;
-
-// // insn is nondebug and dead
-// }
-// }
-
-rtl_opt_pass *
-make_pass_fast_rtl_dce (gcc::context *ctxt)
-{
- return new pass_fast_rtl_dce (ctxt);
-}
-
namespace {
const pass_data pass_data_rtl_ssa_dce = {
diff --git a/gcc/fwprop.cc b/gcc/fwprop.cc
index 4ee44adcde29..ff7caaa8074c 100644
--- a/gcc/fwprop.cc
+++ b/gcc/fwprop.cc
@@ -905,7 +905,7 @@ fwprop_done (void)
delete crtl->ssa;
crtl->ssa = nullptr;
- delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ // delete_trivially_dead_insns (get_insns (), max_reg_num ());
if (dump_file)
fprintf (dump_file,
diff --git a/gcc/passes.def b/gcc/passes.def
index 2509f44bc5c7..a4cd1eb741b2 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -489,7 +489,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_inc_dec);
NEXT_PASS (pass_initialize_regs);
NEXT_PASS (pass_rtl_ssa_dce);
- NEXT_PASS (pass_ud_rtl_dce);
+ // __NEXT_PAS (pass_ud_rtl_dce);
NEXT_PASS (pass_ext_dce);
NEXT_PASS (pass_combine);
NEXT_PASS (pass_late_combine);
@@ -532,7 +532,8 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_regrename);
NEXT_PASS (pass_fold_mem_offsets);
NEXT_PASS (pass_cprop_hardreg);
- // NEXT_PASS (pass_rtl_ssa_dce);
+ NEXT_PASS (pass_rtl_ssa_dce);
+ NEXT_PASS (pass_ud_rtl_dce);
// NEXT_PASS (pass_fast_rtl_dce);
NEXT_PASS (pass_reorder_blocks);
NEXT_PASS (pass_leaf_regs);
diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
index aab6251d2bb1..eb89eb664de0 100644
--- a/gcc/rtl-ssa/changes.cc
+++ b/gcc/rtl-ssa/changes.cc
@@ -256,30 +256,20 @@ rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
// SET has been deleted. Clean up all remaining uses. Such uses are
// either dead phis or now-redundant live-out uses.
void
-function_info::process_uses_of_deleted_def (set_info *set, auto_sbitmap &visited_phi_nodes)
+function_info::process_uses_of_deleted_def (set_info *set)
{
if (!set->has_any_uses ())
return;
- insn_info *set_insn = set->insn ();
- if (set_insn && set_insn->is_phi()) {
- auto *phi = static_cast<phi_info *> (set);
- bitmap_set_bit (visited_phi_nodes, phi->uid ());
- }
-
auto *use = *set->all_uses ().begin ();
do
{
auto *next_use = use->next_use ();
if (use->is_in_phi ())
{
- phi_info *phi = use->phi ();
- if (bitmap_bit_p(visited_phi_nodes, phi->uid ())) {
- remove_use (use);
- } else {
- process_uses_of_deleted_def (phi, visited_phi_nodes);
- delete_phi (phi);
- }
+ // This call will not recurse.
+ process_uses_of_deleted_def (use->phi ());
+ delete_phi (use->phi ());
}
else
{
@@ -870,11 +860,7 @@ function_info::change_insns (array_slice<insn_change *> changes)
{
auto *set = dyn_cast<set_info *> (def);
if (set && set->has_any_uses ())
- {
- auto_sbitmap visited_phis(m_next_phi_uid);
- bitmap_clear(visited_phis);
- process_uses_of_deleted_def (set, visited_phis);
- }
+ process_uses_of_deleted_def (set);
remove_def (def);
}
diff --git a/gcc/rtl-ssa/functions.h b/gcc/rtl-ssa/functions.h
index 033154dfa586..2e20f5e47d72 100644
--- a/gcc/rtl-ssa/functions.h
+++ b/gcc/rtl-ssa/functions.h
@@ -306,7 +306,7 @@ private:
bb_info *create_bb_info (basic_block);
void append_bb (bb_info *);
- void process_uses_of_deleted_def (set_info *set, auto_sbitmap &);
+ void process_uses_of_deleted_def (set_info *);
insn_info *add_placeholder_after (insn_info *);
void possibly_queue_changes (insn_change &);
void finalize_new_accesses (insn_change &, insn_info *,
More information about the Gcc-cvs
mailing list