}
/* Implement rule 1b above. PREDS is the AND predicate to simplify
- in place. Returns true if CHAIN simplifies to true. */
+ in place. Returns true if CHAIN simplifies to true or false. */
static bool
simplify_1b (pred_chain &chain)
{
chain.ordered_remove (j);
chain.ordered_remove (i);
+ if (chain.is_empty ())
+ return true;
i--;
break;
}
::simplify_1a (m_preds[i]);
if (::simplify_1b (m_preds[i]))
{
+ m_preds[i].release ();
m_preds.ordered_remove (i);
i--;
}
while (!work_list.is_empty ())
{
pred_info pi = work_list.pop ();
- predicate pred;
/* The predicate object is not modified here, only NORM_CHAIN and
WORK_LIST are appended to. */
- pred.normalize (&norm_chain, pi, BIT_AND_EXPR, &work_list, &mark_set);
+ unsigned oldlen = m_preds.length ();
+ normalize (&norm_chain, pi, BIT_AND_EXPR, &work_list, &mark_set);
+ gcc_assert (m_preds.length () == oldlen);
}
m_preds.safe_push (norm_chain);
dump (dump_file, use_or_def, is_use ? "[USE]:\n" : "[DEF]:\n");
}
- predicate norm_preds;
+ predicate norm_preds (empty_val ());
for (unsigned i = 0; i < m_preds.length (); i++)
{
if (m_preds[i].length () != 1)
if (this == &rhs)
return *this;
+ m_cval = rhs.m_cval;
+
unsigned n = m_preds.length ();
for (unsigned i = 0; i != n; ++i)
m_preds[i].release ();
/* Try to build the predicate expression under which the PHI flows
into its use. This will be empty if the PHI is defined and used
in the same bb. */
- predicate use_preds;
+ predicate use_preds (true);
if (!init_use_preds (use_preds, def_bb, use_bb))
return false;
use_preds.simplify (use_stmt, /*is_use=*/true);
+ if (use_preds.is_false ())
+ return true;
+ if (use_preds.is_true ())
+ return false;
use_preds.normalize (use_stmt, /*is_use=*/true);
/* Try to prune the dead incoming phi edges. */
return false;
m_phi_def_preds.simplify (phi);
+ if (m_phi_def_preds.is_false ())
+ return false;
+ if (m_phi_def_preds.is_true ())
+ return true;
m_phi_def_preds.normalize (phi);
}
{
public:
/* Construct with the specified EVAL object. */
- predicate () : m_preds (vNULL) { }
+ predicate (bool empty_val) : m_preds (vNULL), m_cval (empty_val) { }
/* Copy. */
predicate (const predicate &rhs) : m_preds (vNULL) { *this = rhs; }
return m_preds.is_empty ();
}
+ bool is_true () const
+ {
+ return is_empty () && m_cval;
+ }
+
+ bool is_false () const
+ {
+ return is_empty () && !m_cval;
+ }
+
+ bool empty_val () const
+ {
+ return m_cval;
+ }
+
const pred_chain_union chain () const
{
return m_preds;
bool simplify_3 ();
bool simplify_4 ();
- /* Representation of the predicate expression(s). */
+ /* Representation of the predicate expression(s). The predicate is
+ m_cval || m_preds[0] || ... */
pred_chain_union m_preds;
+ bool m_cval;
};
/* Represents a complex Boolean predicate expression. */
/* Construct with the specified EVAL object. */
uninit_analysis (func_t &eval)
- : m_phi_def_preds (), m_eval (eval) { }
+ : m_phi_def_preds (false), m_eval (eval) { }
/* Copy. */
uninit_analysis (const uninit_analysis &rhs) = delete;