/* Replace a statement at *SI_P with a sequence of statements in STMTS,
adjusting the replacement stmts location and virtual operands.
- If the statement has a lhs the last stmt in the sequence is expected
- to assign to that lhs. */
+
+ If the statements has an lhs, either:
+
+ - the last statement of the new sequence must assign to the same lhs or
+
+ - the caller must ensure that all uses of the old lhs have been
+ removed before calling this function. This includes removing
+ all debug uses. */
void
gsi_replace_with_seq_vops (gimple_stmt_iterator *si_p, gimple_seq stmts)
#include "value-prof.h"
#include "gimplify.h"
+/* Return true if VAR has no uses at all, including no debug uses. */
+
+static inline bool
+completely_unused (const_tree var)
+{
+ auto *head = &SSA_NAME_IMM_USE_NODE (var);
+ return head->next == head;
+}
/* Mark the statement STMT as modified, and update it. */
/* Replace the statement pointed-to by GSI to STMT. If UPDATE_EH_INFO
is true, the exception handling information of the original
- statement is moved to the new statement. Assignments must only be
- replaced with assignments to the same LHS. Returns whether EH edge
- cleanup is required. */
+ statement is moved to the new statement. Returns whether EH edge
+ cleanup is required.
+
+ If the two statements assign to different SSA names, the caller must
+ ensure that all uses of the old SSA name have been removed before
+ calling this function. This includes removing all debug uses. */
bool
gsi_replace (gimple_stmt_iterator *gsi, gimple *stmt, bool update_eh_info)
return false;
gcc_assert (!gimple_has_lhs (orig_stmt) || !gimple_has_lhs (stmt)
- || gimple_get_lhs (orig_stmt) == gimple_get_lhs (stmt));
+ || gimple_get_lhs (orig_stmt) == gimple_get_lhs (stmt)
+ || completely_unused (gimple_get_lhs (orig_stmt)));
gimple_set_location (stmt, gimple_location (orig_stmt));
gimple_set_bb (stmt, gsi_bb (*gsi));