From: Richard Biener <rguenther@suse.de>
To: Jakub Jelinek <jakub@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] Handle __builtin_unreachable () using assertions in VRP
Date: Tue, 29 Oct 2013 14:41:00 -0000 [thread overview]
Message-ID: <alpine.LNX.2.00.1310291512100.11149@zhemvz.fhfr.qr> (raw)
In-Reply-To: <20131029135401.GC30970@tucnak.zalov.cz>
On Tue, 29 Oct 2013, Jakub Jelinek wrote:
> On Tue, Oct 29, 2013 at 12:28:49PM +0100, Richard Biener wrote:
> > Otherwise ok.
>
> So like this?
Yes, Thanks.
Richard.
> 2013-10-29 Jakub Jelinek <jakub@redhat.com>
>
> * tree-cfg.c (assert_unreachable_fallthru_edge_p): New function.
> * tree-cfg.h (assert_unreachable_fallthru_edge_p): New prototype.
> * tree-vrp.c (all_imm_uses_in_stmt_or_feed_cond): New function.
> (remove_range_assertions): If ASSERT_EXPR_VAR has no other immediate
> uses but in the condition and ASSERT_EXPR and the other successor of
> the predecessor bb is __builtin_unreachable (), set_range_info of the
> ASSERT_EXPR_VAR to the range info of the ASSERT_EXPR's lhs.
>
> --- gcc/tree-cfg.c.jj 2013-10-29 09:25:55.000000000 +0100
> +++ gcc/tree-cfg.c 2013-10-29 14:32:53.235150267 +0100
> @@ -380,6 +380,50 @@ computed_goto_p (gimple t)
> && TREE_CODE (gimple_goto_dest (t)) != LABEL_DECL);
> }
>
> +/* Returns true for edge E where e->src ends with a GIMPLE_COND and
> + the other edge points to a bb with just __builtin_unreachable ().
> + I.e. return true for C->M edge in:
> + <bb C>:
> + ...
> + if (something)
> + goto <bb N>;
> + else
> + goto <bb M>;
> + <bb N>:
> + __builtin_unreachable ();
> + <bb M>: */
> +
> +bool
> +assert_unreachable_fallthru_edge_p (edge e)
> +{
> + basic_block pred_bb = e->src;
> + gimple last = last_stmt (pred_bb);
> + if (last && gimple_code (last) == GIMPLE_COND)
> + {
> + basic_block other_bb = EDGE_SUCC (pred_bb, 0)->dest;
> + if (other_bb == e->dest)
> + other_bb = EDGE_SUCC (pred_bb, 1)->dest;
> + if (EDGE_COUNT (other_bb->succs) == 0)
> + {
> + gimple_stmt_iterator gsi = gsi_after_labels (other_bb);
> + gimple stmt;
> +
> + if (gsi_end_p (gsi))
> + return false;
> + stmt = gsi_stmt (gsi);
> + if (is_gimple_debug (stmt))
> + {
> + gsi_next_nondebug (&gsi);
> + if (gsi_end_p (gsi))
> + return false;
> + stmt = gsi_stmt (gsi);
> + }
> + return gimple_call_builtin_p (stmt, BUILT_IN_UNREACHABLE);
> + }
> + }
> + return false;
> +}
> +
>
> /* Search the CFG for any computed gotos. If found, factor them to a
> common computed goto site. Also record the location of that site so
> --- gcc/tree-vrp.c.jj 2013-10-29 09:25:38.382477963 +0100
> +++ gcc/tree-vrp.c 2013-10-29 14:36:23.695060600 +0100
> @@ -6459,6 +6459,33 @@ check_all_array_refs (void)
> }
> }
>
> +/* Return true if all imm uses of VAR are either in STMT, or
> + feed (optionally through a chain of single imm uses) GIMPLE_COND
> + in basic block COND_BB. */
> +
> +static bool
> +all_imm_uses_in_stmt_or_feed_cond (tree var, gimple stmt, basic_block cond_bb)
> +{
> + use_operand_p use_p, use2_p;
> + imm_use_iterator iter;
> +
> + FOR_EACH_IMM_USE_FAST (use_p, iter, var)
> + if (USE_STMT (use_p) != stmt)
> + {
> + gimple use_stmt = USE_STMT (use_p);
> + if (is_gimple_debug (use_stmt))
> + continue;
> + while (is_gimple_assign (use_stmt)
> + && single_imm_use (gimple_assign_lhs (use_stmt),
> + &use2_p, &use_stmt))
> + ;
> + if (gimple_code (use_stmt) != GIMPLE_COND
> + || gimple_bb (use_stmt) != cond_bb)
> + return false;
> + }
> + return true;
> +}
> +
> /* Convert range assertion expressions into the implied copies and
> copy propagate away the copies. Doing the trivial copy propagation
> here avoids the need to run the full copy propagation pass after
> @@ -6488,12 +6515,16 @@ remove_range_assertions (void)
> {
> basic_block bb;
> gimple_stmt_iterator si;
> + /* 1 if looking at ASSERT_EXPRs immediately at the beginning of
> + a basic block preceeded by GIMPLE_COND branching to it and
> + __builtin_trap, -1 if not yet checked, 0 otherwise. */
> + int is_unreachable;
>
> /* Note that the BSI iterator bump happens at the bottom of the
> loop and no bump is necessary if we're removing the statement
> referenced by the current BSI. */
> FOR_EACH_BB (bb)
> - for (si = gsi_start_bb (bb); !gsi_end_p (si);)
> + for (si = gsi_after_labels (bb), is_unreachable = -1; !gsi_end_p (si);)
> {
> gimple stmt = gsi_stmt (si);
> gimple use_stmt;
> @@ -6501,6 +6532,7 @@ remove_range_assertions (void)
> if (is_gimple_assign (stmt)
> && gimple_assign_rhs_code (stmt) == ASSERT_EXPR)
> {
> + tree lhs = gimple_assign_lhs (stmt);
> tree rhs = gimple_assign_rhs1 (stmt);
> tree var;
> tree cond = fold (ASSERT_EXPR_COND (rhs));
> @@ -6509,22 +6541,49 @@ remove_range_assertions (void)
>
> gcc_assert (cond != boolean_false_node);
>
> - /* Propagate the RHS into every use of the LHS. */
> var = ASSERT_EXPR_VAR (rhs);
> - FOR_EACH_IMM_USE_STMT (use_stmt, iter,
> - gimple_assign_lhs (stmt))
> + gcc_assert (TREE_CODE (var) == SSA_NAME);
> +
> + if (!POINTER_TYPE_P (TREE_TYPE (lhs))
> + && SSA_NAME_RANGE_INFO (lhs))
> + {
> + if (is_unreachable == -1)
> + {
> + is_unreachable = 0;
> + if (single_pred_p (bb)
> + && assert_unreachable_fallthru_edge_p
> + (single_pred_edge (bb)))
> + is_unreachable = 1;
> + }
> + /* Handle
> + if (x_7 >= 10 && x_7 < 20)
> + __builtin_unreachable ();
> + x_8 = ASSERT_EXPR <x_7, ...>;
> + if the only uses of x_7 are in the ASSERT_EXPR and
> + in the condition. In that case, we can copy the
> + range info from x_8 computed in this pass also
> + for x_7. */
> + if (is_unreachable
> + && all_imm_uses_in_stmt_or_feed_cond (var, stmt,
> + single_pred (bb)))
> + set_range_info (var, SSA_NAME_RANGE_INFO (lhs)->min,
> + SSA_NAME_RANGE_INFO (lhs)->max);
> + }
> +
> + /* Propagate the RHS into every use of the LHS. */
> + FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
> FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
> - {
> - SET_USE (use_p, var);
> - gcc_assert (TREE_CODE (var) == SSA_NAME);
> - }
> + SET_USE (use_p, var);
>
> /* And finally, remove the copy, it is not needed. */
> gsi_remove (&si, true);
> release_defs (stmt);
> }
> else
> - gsi_next (&si);
> + {
> + gsi_next (&si);
> + is_unreachable = 0;
> + }
> }
> }
>
> --- gcc/tree-cfg.h.jj 2013-10-21 09:00:52.000000000 +0200
> +++ gcc/tree-cfg.h 2013-10-29 14:17:52.927812547 +0100
> @@ -51,6 +51,7 @@ extern bool is_ctrl_stmt (gimple);
> extern bool is_ctrl_altering_stmt (gimple);
> extern bool simple_goto_p (gimple);
> extern bool stmt_ends_bb_p (gimple);
> +extern bool assert_unreachable_fallthru_edge_p (edge);
> extern void delete_tree_cfg_annotations (void);
> extern gimple first_stmt (basic_block);
> extern gimple last_stmt (basic_block);
>
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend
next prev parent reply other threads:[~2013-10-29 14:12 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-25 9:13 Jakub Jelinek
2013-10-29 12:05 ` Richard Biener
2013-10-29 14:15 ` Jakub Jelinek
2013-10-29 14:41 ` Richard Biener [this message]
2013-11-04 1:00 ` Tom de Vries
2013-11-04 10:46 ` Tom de Vries
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LNX.2.00.1310291512100.11149@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).