On 05/04/2017 04:59 AM, Richard Biener wrote:
I think this is a hack ;) Basically the issue is that jump-threading
uses ASSERT_EXPRs
at all (which are an implementation detail of VRP). As far as I
understand it does that
because VRP can do "fancy" things and create ASSERT_EXPRs that do not directly
map to the conditional but to its operand def stmts.
Agreed it's a hack, but perhaps for different reasons.
The only reason we have a threading pass inside VRP is so that we can
get access to the internal state. It pre-dates the ability to query any
kind of range data outside of VRP by a decade.
The long term plan is to drop the threading passes from VRP once we can
get accurate ranges outside VRP using Andrew's work. Once we can do
that, DOM or backward threader can query that data and the jump
threading pass inside VRP becomes redundant/useless.
The first major milestone for that work will be the ability to drop
ASSERT_EXPRs completely from the IL, but still get just as accurate
range information. ASSERT_EXPRs are really just an implementation
detail inside VRP.
--
You understanding is slightly wrong however, The ASSERT_EXPRs and
conditionals map 100% through propagation and into simplification. It's
only during simplification that we lose the direct mapping as we change
the conditional in order to remove the unnecessary type conversion.
Threading runs after simplification.
Another approach here would be to simplify the ASSERT_EXPR in the same
manner that we simplify the conditional. That may even be better for
various reasons in the short term. Let me poke at that.
I have meanwhile factored this "fancieness" out into (ok, bad name...)
register_edge_assert_for which records all these fancy asserts in a
vec. This is
now used from EVRP:
gimple *stmt = last_stmt (pred_e->src);
if (stmt
&& gimple_code (stmt) == GIMPLE_COND
&& (op0 = gimple_cond_lhs (stmt))
&& TREE_CODE (op0) == SSA_NAME
&& (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
|| POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Visiting controlling predicate ");
print_gimple_stmt (dump_file, stmt, 0, 0);
}
/* Entering a new scope. Try to see if we can find a VR
here. */
tree op1 = gimple_cond_rhs (stmt);
if (TREE_OVERFLOW_P (op1))
op1 = drop_tree_overflow (op1);
tree_code code = gimple_cond_code (stmt);
auto_vec<assert_info, 8> asserts;
register_edge_assert_for (op0, pred_e, code, op0, op1, asserts);
if (TREE_CODE (op1) == SSA_NAME)
register_edge_assert_for (op1, pred_e, code, op0, op1, asserts);
regular VRP transforms those into its own assert representation in
finish_register_edge_assert_for (though assert_info should be enough
for jump threading).
Yea, this looks like a much simplified form of what Andrew has done.
I wasn't aware of this stuff from evrp, it may be useful to simplify the
3rd patch in this series (which is still evolving and tries to put in a
real solution for the conditional equivalence problems).
So I think it should be possible for jump threading to use this new
machinery (and even DOM based jump threading or backwards threading
could make use of this!)
Roughly the plan.
I think Aldy is close to being ready to start review work on the new API
class for querying ranges. I think it addresses the big issues we both
want to see addressed (no more ANTI ranges, no fixed number of intervals
within a range representation). Removal of ANTI ranges does
significantly simplify things on the client side which IMHO should be
the driver at this point.
In parallel I expect to carve out two more hunks of Andrew's work in the
near future. Essentially they're APIs that allow efficient computation
and mapping of blocks that generate range data for a particular name and
walkers. They should allow simplification of some stuff in DOM and
improve the most glaring weakness in the backwards threader.
jeff