This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
- From: David Malcolm <dmalcolm at redhat dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: Jakub Jelinek <jakub at redhat dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>, GCC Development <gcc at gcc dot gnu dot org>, Jeff Law <law at redhat dot com>
- Date: Sat, 15 Nov 2014 06:00:30 -0500
- Subject: Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
- Authentication-results: sourceware.org; auth=none
- References: <1415373690-26193-1-git-send-email-dmalcolm at redhat dot com> <1415373690-26193-5-git-send-email-dmalcolm at redhat dot com> <CAFiYyc2rg+T5d7rkTBPLeWKGnWMgv07j_N8KaFfr0NK1CjsfVQ at mail dot gmail dot com> <CAFiYyc2Y4uWt3Ec-D=c+LmKyBb1s0UPkP=8sSr1+5_nb7NruyA at mail dot gmail dot com> <20141108135646 dot GU5026 at tucnak dot redhat dot com> <1415658470 dot 2209 dot 20 dot camel at surprise> <20141111072614 dot GW5026 at tucnak dot redhat dot com> <CAFiYyc1jfx05qxvsCGqbdDL=ouH0hMp2A1ufandUbb-EfUAukg at mail dot gmail dot com> <1415842862 dot 2209 dot 101 dot camel at surprise> <CAFiYyc0H958TKBOb7F20hg8++YnOQYeMcQEZ2Ba+Q0F6hobeKw at mail dot gmail dot com>
On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
> >> >> > > To be constructive here - the above case is from within a
> >> >> > > GIMPLE_ASSIGN case label
> >> >> > > and thus I'd have expected
> >> >> > >
> >> >> > > case GIMPLE_ASSIGN:
> >> >> > > {
> >> >> > > gassign *a1 = as_a <gassign *> (s1);
> >> >> > > gassign *a2 = as_a <gassign *> (s2);
> >> >> > > lhs1 = gimple_assign_lhs (a1);
> >> >> > > lhs2 = gimple_assign_lhs (a2);
> >> >> > > if (TREE_CODE (lhs1) != SSA_NAME
> >> >> > > && TREE_CODE (lhs2) != SSA_NAME)
> >> >> > > return (operand_equal_p (lhs1, lhs2, 0)
> >> >> > > && gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
> >> >> > > gimple_assign_rhs1 (a2)));
> >> >> > > else if (TREE_CODE (lhs1) == SSA_NAME
> >> >> > > && TREE_CODE (lhs2) == SSA_NAME)
> >> >> > > return vn_valueize (lhs1) == vn_valueize (lhs2);
> >> >> > > return false;
> >> >> > > }
> >> >> > >
> >> >> > > instead. That's the kind of changes I have expected and have approved of.
> >> >> >
> >> >> > But even that looks like just adding extra work for all developers, with no
> >> >> > gain. You only have to add extra code and extra temporaries, in switches
> >> >> > typically also have to add {} because of the temporaries and thus extra
> >> >> > indentation level, and it doesn't simplify anything in the code.
> >> >>
> >> >> The branch attempts to use the C++ typesystem to capture information
> >> >> about the kinds of gimple statement we expect, both:
> >> >> (A) so that the compiler can detect type errors, and
> >> >> (B) as a comprehension aid to the human reader of the code
> >> >>
> >> >> The ideal here is when function params and struct field can be
> >> >> strengthened from "gimple" to a subclass ptr. This captures the
> >> >> knowledge that every use of a function or within a struct has a given
> >> >> gimple code.
> >> >
> >> > I just don't like all the as_a/is_a stuff enforced everywhere,
> >> > it means more typing, more temporaries, more indentation.
> >> > So, as I view it, instead of the checks being done cheaply (yes, I think
> >> > the gimple checking as we have right now is very cheap) under the
> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
> >> > put the burden on the developers, who has to check that manually through
> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax.
> >> > I just don't see that as a step forward, instead a huge step backwards.
> >> > But perhaps I'm alone with this.
> >> > Can you e.g. compare the size of - lines in your patchset combined, and
> >> > size of + lines in your patchset? As in, if your changes lead to less
> >> > typing or more.
> >>
> >> I see two ways out here. One is to add overloads to all the functions
> >> taking the special types like
> >>
> >> tree
> >> gimple_assign_rhs1 (gimple *);
> >>
> >> or simply add
> >>
> >> gassign *operator ()(gimple *g) { return as_a <gassign *> (g); }
> >>
> >> into a gimple-compat.h header which you include in places that
> >> are not converted "nicely".
> >
> > Thanks for the suggestions.
> >
> > Am I missing something, or is the gimple-compat.h idea above not valid C
> > ++?
> >
> > Note that "gimple" is still a typedef to
> > gimple_statement_base *
> > (as noted before, the gimple -> gimple * change would break everyone
> > else's patches, so we talked about that as a followup patch for early
> > stage3).
> >
> > Given that, if I try to create an "operator ()" outside of a class, I
> > get this error:
> >
> > âgassign* operator()(gimple)â must be a nonstatic member function
> >
> > which is emitted from cp/decl.c's grok_op_properties:
> > /* An operator function must either be a non-static member function
> > or have at least one parameter of a class, a reference to a class,
> > an enumeration, or a reference to an enumeration. 13.4.0.6 */
> >
> > I tried making it a member function of gimple_statement_base, but that
> > doesn't work either: we want a conversion
> > from a gimple_statement_base * to a gassign *, not
> > from a gimple_statement_base to a gassign *.
> >
> > Is there some syntactic trick here that I'm missing? Sorry if I'm being
> > dumb (I can imagine there's a way of doing it by making "gimple" become
> > some kind of wrapped ptr class, but that way lies madness, surely).
>
> Hmm.
>
> struct assign;
> struct base {
> operator assign *() const { return (assign *)this; }
> };
> struct assign : base {
> };
>
> void foo (assign *);
> void bar (base *b)
> {
> foo (b);
> }
>
> doesn't work, but
>
> void bar (base &b)
> {
> foo (b);
> }
>
> does. Indeed C++ doesn't seem to provide what is necessary
> for the compat trick :(
>
> So the gimple-compat.h header would need to provide
> additional overloads for the affected functions like
>
> inline tree
> gimple_assign_rhs1 (gimple *g)
> {
> return gimple_assign_rhs1 (as_a <gassign *> (g));
> }
>
> that would work for me as well.
>
> >> Both avoid manually making the compiler happy (which the
> >> explicit as_a<> stuff is! It doesn't add any "checking" - it's
> >> just placing the as_a<> at the callers and thus make the
> >> runtine ICE fire there).
> >>
> >> As much as I don't like "global" conversion operators I don't
> >> like adding overloads to all of the accessor functions even more.
> >
> > (nods)
> >
> > Some other options:
> >
> > Option 3: only convert the "easy" accessors: the ones I already did in
> > the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
> > which is this 92-patch kit:
> > "[gimple-classes, committed 00/92] Initial slew of commits":
> > https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
> > Doing so converts about half of the gimple_foo_ accessors to taking a
> > gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use. I believe
> > the quality of those patches was higher than the later ones on the
> > branch: I was doing the places that didn't require the invasive/verbose
> > changes seen in the later patches. Shelve the remaining ~80
> > increasingly ugly patches, starting a new branch to contain just the
> > good ones.
I've created a branch "dmalcolm/gimple-classes-v2-option-3"
https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/gimple-classes-v2-option-3
which takes the work reviewed by Jeff and the most trivial of the merger
followup work, throwing away the ~80 unloved followup patches on
dmalcolm/gimple-classes.
I've merged from yesterday's trunk r217593 into that new branch,
resolving conflicts.
I did this in two parts: the basic merger as
bd7fe714158f0c600caa05be7d744fd9139b8afb
resolving conflicts, with a followup patch to fixup new code from trunk
that used accessors that on the branch required a gimple subclass.
Attached is that 2nd part of the merger.
Successfully bootstrapped and regrtested on x86_64-unknown-linux-gnu;
same regrtest results as a control bootstrap of trunk's r217593.
I appreciate Jakub and others have concerns about the overall approach.
I'm not sure which of option 2 (gimple-compat.h), option 3 (this one),
option 4 (just convert fields and non-accessor params), or defer to gcc
6 is the best one, but I'm sleep-deprived and wanted to submit this
before the stage1 deadline.
The other commits on this pruned branch that haven't been reviewed yet
are:
[gimple-classes, committed 88/92] Preparatory work before subclass
renaming
https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02820.html
[gimple-classes, committed 89/92] Eliminate subclass typedefs from
coretypes.h
https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02838.html
[gimple-classes, committed 90/92] Automated renaming of gimple
subclasses
https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02828.html
[gimple-classes, committed 91/92] Remove out-of-date references to
typedefs]
https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02874.html
[gimple-classes, committed 92/92] Update gimple.texi class hierarchy
diagram
https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02818.html
[gimple-classes] Merge trunk r216157-r216746 into branch
https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html
Also, presumably if this were merged, it would require a followup with
the gimple to gimple * fixup you wanted? (which we talked about doing as
an early stage3 thing IIRC [1]).
Thanks
Dave
[1] e.g. https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01536.html
> > Option 4: don't convert any accessors, but instead focus on fields of
> > structs (e.g. "call_stmt" within a cgraph_edge), and on params of other
> > functions (e.g. phi-manipulation code). That way we'd avoid the
> > inconsistency of some accessors using GIMPLE_CHECK and some using
> > subclasses - all would continue to consistently use GIMPLE_CHECK, but
> > there would be some extra type-checking and self-documentation of the
> > expected statement kinds in the code.
> >
> >
> >
> > FWIW, option 3 is my preferred approach (I've already done the bulk of
> > the work and it's already been reviewed; it would need an update merger
> > from trunk, and there's the big gimple to gimple * fixup you wanted).
>
> Works for me as well. The compat solution looks somewhat appealing
> as we can then incrementally fix up things rather than requiring to
> mass-convert everything.
>
> Thanks,
> Richard.
>
> >> Whether you enable them generally or just for selected files
> >> via a gimple-compat.h will be up to you (but I'd rather get
> >> rid of them at some point).
> >>
> >> Note this allows seamless transform of "random" functions
> >> taking a gimple now but really only expecting a single kind.
> >>
> >> Note that we don't absolutely have to rush this all in for GCC 5.
> >> Being the very first for GCC 6 stage1 is another possibility.
> >> We just should get it right.
> >
> > Thanks
> > Dave
> >
>From 533f5852c8aef75bf4f14b03744e5e09429a882c Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Sat, 15 Nov 2014 05:02:09 -0500
Subject: [PATCH] Fixups after merge
gcc/ChangeLog.gimple-classes:
* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee):
Strengthen locals "dbndret" and "ibndret" from gimple to gcall *.
* gimple-iterator.c (gsi_for_phi): New function.
* gimple-iterator.h (gsi_for_phi): New prototype.
* internal-fn.c (expand_ADD_OVERFLOW): Strengthen param "stmt"
from gimple to gcall *.
(expand_SUB_OVERFLOW): Likewise.
(expand_MUL_OVERFLOW): Likewise.
* ipa-icf-gimple.c (func_checker::compare_bb): Add checked casts
within case GIMPLE_CALL.
(func_checker::compare_gimple_call): Strengthen params from gimple
to gcall *.
* ipa-icf-gimple.h (func_checker::compare_gimple_call): Likewise.
* sanopt.c (sanopt_optimize_walker): Replace check for GIMPLE_ASM
with a dyn_cast, introducing local "asm_stmt" and using it in
place of "stmt" for typesafety.
* tree-chkp.c (chkp_recompute_phi_bounds): Strengthen locals
"bounds_phi" and "ptr_phi" from gimple to gphi *.
(chkp_add_bounds_to_ret_stmt): Strengthen local "ret" from gimple
to greturn *.
(chkp_add_bounds_to_call_stmt): Strengthen locals "call" and
"new_call" from gimple to gcall *.
(chkp_build_returned_bound): Likewise for param "call".
(chkp_retbnd_call_by_val): Likewise for return type.
(chkp_get_bounds_by_definition): Strengthen param "iter" from
gimple_stmt_iterator * to gphi_iterator *. Add a checked cast
within case GIMPLE_CALL. Use gsi_for_phi rather than
gsi_for_stmt.
(chkp_find_bounds_1): Strengthen local "phi_iter" from
gimple_stmt_iterator to gphi_iterator. Replace check for
GIMPLE_PHI with a dyn_cast, introducing local "def_phi" and using
in place of "def_stmt" for typesafety.
(chkp_copy_bounds_for_assign): Add checked cast.
(chkp_instrument_function): Within case GIMPLE_RETURN, add local
greturn * "r" from a checked cast and use in place of "s" for
typesafety.
* tree-chkp.h (chkp_retbnd_call_by_val): Strengthen return type
from gimple to gcall *.
* tree-inline.c (copy_bb): Update for renaming of field
"gimple_call" to "call_stmt" on the gimple-classes branch.
(expand_call_inline): Strengthen local "retbnc" from gimple to
gcall *.
* tree-ssa-forwprop.c (pass_forwprop::execute): Replace check for
GIMPLE_COND with a dyn_cast, introducing local "cond" and using
in place of "stmt" for typesafety.
* value-prof.c (gimple_ic): Strengthen local "iretbnd_stmt" from
gimple to gcall *. Weaken top-level local "psi" from
gphi_iterator back to gimple_stmt_iterator, reintroducing the
name as a phi_iterator within the for loop that needs it.
---
gcc/ChangeLog.gimple-classes | 52 ++++++++++++++++++++++++++++++
gcc/cgraph.c | 4 +--
gcc/gimple-iterator.c | 13 ++++++++
gcc/gimple-iterator.h | 1 +
gcc/internal-fn.c | 6 ++--
gcc/ipa-icf-gimple.c | 5 +--
gcc/ipa-icf-gimple.h | 2 +-
gcc/sanopt.c | 7 ++--
gcc/tree-chkp.c | 76 +++++++++++++++++++++++---------------------
gcc/tree-chkp.h | 2 +-
gcc/tree-inline.c | 30 ++++++++---------
gcc/tree-ssa-forwprop.c | 8 ++---
gcc/value-prof.c | 6 ++--
13 files changed, 141 insertions(+), 71 deletions(-)
diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 133965c..ec8fc5a 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,3 +1,55 @@
+2014-11-14 David Malcolm <dmalcolm@redhat.com>
+
+ * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee):
+ Strengthen locals "dbndret" and "ibndret" from gimple to gcall *.
+ * gimple-iterator.c (gsi_for_phi): New function.
+ * gimple-iterator.h (gsi_for_phi): New prototype.
+ * internal-fn.c (expand_ADD_OVERFLOW): Strengthen param "stmt"
+ from gimple to gcall *.
+ (expand_SUB_OVERFLOW): Likewise.
+ (expand_MUL_OVERFLOW): Likewise.
+ * ipa-icf-gimple.c (func_checker::compare_bb): Add checked casts
+ within case GIMPLE_CALL.
+ (func_checker::compare_gimple_call): Strengthen params from gimple
+ to gcall *.
+ * ipa-icf-gimple.h (func_checker::compare_gimple_call): Likewise.
+ * sanopt.c (sanopt_optimize_walker): Replace check for GIMPLE_ASM
+ with a dyn_cast, introducing local "asm_stmt" and using it in
+ place of "stmt" for typesafety.
+ * tree-chkp.c (chkp_recompute_phi_bounds): Strengthen locals
+ "bounds_phi" and "ptr_phi" from gimple to gphi *.
+ (chkp_add_bounds_to_ret_stmt): Strengthen local "ret" from gimple
+ to greturn *.
+ (chkp_add_bounds_to_call_stmt): Strengthen locals "call" and
+ "new_call" from gimple to gcall *.
+ (chkp_build_returned_bound): Likewise for param "call".
+ (chkp_retbnd_call_by_val): Likewise for return type.
+ (chkp_get_bounds_by_definition): Strengthen param "iter" from
+ gimple_stmt_iterator * to gphi_iterator *. Add a checked cast
+ within case GIMPLE_CALL. Use gsi_for_phi rather than
+ gsi_for_stmt.
+ (chkp_find_bounds_1): Strengthen local "phi_iter" from
+ gimple_stmt_iterator to gphi_iterator. Replace check for
+ GIMPLE_PHI with a dyn_cast, introducing local "def_phi" and using
+ in place of "def_stmt" for typesafety.
+ (chkp_copy_bounds_for_assign): Add checked cast.
+ (chkp_instrument_function): Within case GIMPLE_RETURN, add local
+ greturn * "r" from a checked cast and use in place of "s" for
+ typesafety.
+ * tree-chkp.h (chkp_retbnd_call_by_val): Strengthen return type
+ from gimple to gcall *.
+ * tree-inline.c (copy_bb): Update for renaming of field
+ "gimple_call" to "call_stmt" on the gimple-classes branch.
+ (expand_call_inline): Strengthen local "retbnc" from gimple to
+ gcall *.
+ * tree-ssa-forwprop.c (pass_forwprop::execute): Replace check for
+ GIMPLE_COND with a dyn_cast, introducing local "cond" and using
+ in place of "stmt" for typesafety.
+ * value-prof.c (gimple_ic): Strengthen local "iretbnd_stmt" from
+ gimple to gcall *. Weaken top-level local "psi" from
+ gphi_iterator back to gimple_stmt_iterator, reintroducing the
+ name as a phi_iterator within the for loop that needs it.
+
2014-10-28 David Malcolm <dmalcolm@redhat.com>
* auto-profile.c (autofdo::function_instance::find_icall_target_map):
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index a854b4a..71e6146 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1363,8 +1363,8 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
{
tree dresult = gimple_call_lhs (new_stmt);
tree iresult = gimple_call_lhs (e2->call_stmt);
- gimple dbndret = chkp_retbnd_call_by_val (dresult);
- gimple ibndret = chkp_retbnd_call_by_val (iresult);
+ gcall *dbndret = chkp_retbnd_call_by_val (dresult);
+ gcall *ibndret = chkp_retbnd_call_by_val (iresult);
struct cgraph_edge *iedge
= e2->caller->cgraph_node::get_edge (ibndret);
struct cgraph_edge *dedge;
diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c
index 3d8bd6f..e7a4658 100644
--- a/gcc/gimple-iterator.c
+++ b/gcc/gimple-iterator.c
@@ -639,6 +639,19 @@ gsi_for_stmt (gimple stmt)
return i;
}
+/* Finds iterator for PHI. */
+
+gphi_iterator
+gsi_for_phi (gphi *phi)
+{
+ gphi_iterator i;
+ basic_block bb = gimple_bb (phi);
+
+ i = gsi_start_phis (bb);
+ i.ptr = phi;
+
+ return i;
+}
/* Move the statement at FROM so it comes right after the statement at TO. */
diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h
index 79585d2..fb6cc07 100644
--- a/gcc/gimple-iterator.h
+++ b/gcc/gimple-iterator.h
@@ -79,6 +79,7 @@ extern void gsi_insert_after (gimple_stmt_iterator *, gimple,
enum gsi_iterator_update);
extern bool gsi_remove (gimple_stmt_iterator *, bool);
extern gimple_stmt_iterator gsi_for_stmt (gimple);
+extern gphi_iterator gsi_for_phi (gphi *);
extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index de08486..8bf43d9 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -1813,7 +1813,7 @@ expand_arith_overflow (enum tree_code code, gimple stmt)
/* Expand ADD_OVERFLOW STMT. */
static void
-expand_ADD_OVERFLOW (gimple stmt)
+expand_ADD_OVERFLOW (gcall *stmt)
{
expand_arith_overflow (PLUS_EXPR, stmt);
}
@@ -1821,7 +1821,7 @@ expand_ADD_OVERFLOW (gimple stmt)
/* Expand SUB_OVERFLOW STMT. */
static void
-expand_SUB_OVERFLOW (gimple stmt)
+expand_SUB_OVERFLOW (gcall *stmt)
{
expand_arith_overflow (MINUS_EXPR, stmt);
}
@@ -1829,7 +1829,7 @@ expand_SUB_OVERFLOW (gimple stmt)
/* Expand MUL_OVERFLOW STMT. */
static void
-expand_MUL_OVERFLOW (gimple stmt)
+expand_MUL_OVERFLOW (gcall *stmt)
{
expand_arith_overflow (MULT_EXPR, stmt);
}
diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 2ec2a1c..8f2a438 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -595,7 +595,8 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
switch (gimple_code (s1))
{
case GIMPLE_CALL:
- if (!compare_gimple_call (s1, s2))
+ if (!compare_gimple_call (as_a <gcall *> (s1),
+ as_a <gcall *> (s2)))
return return_different_stmts (s1, s2, "GIMPLE_CALL");
break;
case GIMPLE_ASSIGN:
@@ -656,7 +657,7 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
call statements are semantically equivalent. */
bool
-func_checker::compare_gimple_call (gimple s1, gimple s2)
+func_checker::compare_gimple_call (gcall *s1, gcall *s2)
{
unsigned i;
tree t1, t2;
diff --git a/gcc/ipa-icf-gimple.h b/gcc/ipa-icf-gimple.h
index b84b122..cb9b1fc 100644
--- a/gcc/ipa-icf-gimple.h
+++ b/gcc/ipa-icf-gimple.h
@@ -161,7 +161,7 @@ public:
/* Verifies for given GIMPLEs S1 and S2 that
call statements are semantically equivalent. */
- bool compare_gimple_call (gimple s1, gimple s2);
+ bool compare_gimple_call (gcall *s1, gcall *s2);
/* Verifies for given GIMPLEs S1 and S2 that
assignment statements are semantically equivalent. */
diff --git a/gcc/sanopt.c b/gcc/sanopt.c
index f6e8ee7..e1d11e0 100644
--- a/gcc/sanopt.c
+++ b/gcc/sanopt.c
@@ -418,10 +418,11 @@ sanopt_optimize_walker (basic_block bb, struct sanopt_ctx *ctx)
{
/* Handle asm volatile or asm with "memory" clobber
the same as potentionally freeing call. */
- if (gimple_code (stmt) == GIMPLE_ASM
+ gasm *asm_stmt = dyn_cast <gasm *> (stmt);
+ if (asm_stmt
&& asan_check_optimize
- && (gimple_asm_clobbers_memory_p (stmt)
- || gimple_asm_volatile_p (stmt)))
+ && (gimple_asm_clobbers_memory_p (asm_stmt)
+ || gimple_asm_volatile_p (asm_stmt)))
info->freeing_call_events++;
gsi_next (&gsi);
continue;
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index df7d425..aadb1cf 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -691,18 +691,15 @@ chkp_recompute_phi_bounds (tree const &bounds, tree *slot,
void *res ATTRIBUTE_UNUSED)
{
tree ptr = *slot;
- gimple bounds_phi;
- gimple ptr_phi;
+ gphi *bounds_phi;
+ gphi *ptr_phi;
unsigned i;
gcc_assert (TREE_CODE (bounds) == SSA_NAME);
gcc_assert (TREE_CODE (ptr) == SSA_NAME);
- bounds_phi = SSA_NAME_DEF_STMT (bounds);
- ptr_phi = SSA_NAME_DEF_STMT (ptr);
-
- gcc_assert (bounds_phi && gimple_code (bounds_phi) == GIMPLE_PHI);
- gcc_assert (ptr_phi && gimple_code (ptr_phi) == GIMPLE_PHI);
+ bounds_phi = as_a <gphi *> (SSA_NAME_DEF_STMT (bounds));
+ ptr_phi = as_a <gphi *> (SSA_NAME_DEF_STMT (ptr));
for (i = 0; i < gimple_phi_num_args (bounds_phi); i++)
{
@@ -1198,7 +1195,7 @@ chkp_get_registered_bounds (tree ptr)
static void
chkp_add_bounds_to_ret_stmt (gimple_stmt_iterator *gsi)
{
- gimple ret = gsi_stmt (*gsi);
+ greturn *ret = as_a <greturn *> (gsi_stmt (*gsi));
tree retval = gimple_return_retval (ret);
tree ret_decl = DECL_RESULT (cfun->decl);
tree bounds;
@@ -1593,7 +1590,7 @@ chkp_find_bound_slots (const_tree type, bitmap res)
static void
chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
{
- gimple call = gsi_stmt (*gsi);
+ gcall *call = as_a <gcall *> (gsi_stmt (*gsi));
unsigned arg_no = 0;
tree fndecl = gimple_call_fndecl (call);
tree fntype;
@@ -1602,7 +1599,7 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
bool use_fntype = false;
tree op;
ssa_op_iter iter;
- gimple new_call;
+ gcall *new_call;
/* Do nothing for internal functions. */
if (gimple_call_internal_p (call))
@@ -2040,7 +2037,7 @@ chkp_get_nonpointer_load_bounds (void)
/* Build bounds returned by CALL. */
static tree
-chkp_build_returned_bound (gimple call)
+chkp_build_returned_bound (gcall *call)
{
gimple_stmt_iterator gsi;
tree bounds;
@@ -2146,7 +2143,7 @@ chkp_build_returned_bound (gimple call)
/* Return bounds used as returned by call
which produced SSA name VAL. */
-gimple
+gcall *
chkp_retbnd_call_by_val (tree val)
{
if (TREE_CODE (val) != SSA_NAME)
@@ -2159,7 +2156,7 @@ chkp_retbnd_call_by_val (tree val)
FOR_EACH_IMM_USE_FAST (use_p, use_iter, val)
if (gimple_code (USE_STMT (use_p)) == GIMPLE_CALL
&& gimple_call_fndecl (USE_STMT (use_p)) == chkp_ret_bnd_fndecl)
- return USE_STMT (use_p);
+ return as_a <gcall *> (USE_STMT (use_p));
return NULL;
}
@@ -2554,11 +2551,11 @@ chkp_compute_bounds_for_assignment (tree node, gimple assign)
Return computed bounds. */
static tree
chkp_get_bounds_by_definition (tree node, gimple def_stmt,
- gimple_stmt_iterator *iter)
+ gphi_iterator *iter)
{
tree var, bounds;
enum gimple_code code = gimple_code (def_stmt);
- gimple stmt;
+ gphi *stmt;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -2619,7 +2616,7 @@ chkp_get_bounds_by_definition (tree node, gimple def_stmt,
break;
case GIMPLE_CALL:
- bounds = chkp_build_returned_bound (def_stmt);
+ bounds = chkp_build_returned_bound (as_a <gcall *> (def_stmt));
break;
case GIMPLE_PHI:
@@ -2634,7 +2631,7 @@ chkp_get_bounds_by_definition (tree node, gimple def_stmt,
var = chkp_get_tmp_var ();
stmt = create_phi_node (var, gimple_bb (def_stmt));
bounds = gimple_phi_result (stmt);
- *iter = gsi_for_stmt (stmt);
+ *iter = gsi_for_phi (stmt);
bounds = chkp_maybe_copy_and_register_bounds (node, bounds);
@@ -3344,21 +3341,21 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
if (!bounds)
{
gimple def_stmt = SSA_NAME_DEF_STMT (ptr_src);
- gimple_stmt_iterator phi_iter;
+ gphi_iterator phi_iter;
bounds = chkp_get_bounds_by_definition (ptr_src, def_stmt, &phi_iter);
gcc_assert (bounds);
- if (gimple_code (def_stmt) == GIMPLE_PHI)
+ if (gphi *def_phi = dyn_cast <gphi *> (def_stmt))
{
unsigned i;
- for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
+ for (i = 0; i < gimple_phi_num_args (def_phi); i++)
{
- tree arg = gimple_phi_arg_def (def_stmt, i);
+ tree arg = gimple_phi_arg_def (def_phi, i);
tree arg_bnd;
- gimple phi_bnd;
+ gphi *phi_bnd;
arg_bnd = chkp_find_bounds (arg, NULL);
@@ -3368,10 +3365,10 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
Previous call to chkp_find_bounds could create
new basic block and therefore change phi statement
phi_iter points to. */
- phi_bnd = gsi_stmt (phi_iter);
+ phi_bnd = phi_iter.phi ();
add_phi_arg (phi_bnd, arg_bnd,
- gimple_phi_arg_edge (def_stmt, i),
+ gimple_phi_arg_edge (def_phi, i),
UNKNOWN_LOCATION);
}
@@ -3829,7 +3826,9 @@ chkp_copy_bounds_for_assign (gimple assign, struct cgraph_edge *edge)
|| fndecl == chkp_bndldx_fndecl
|| fndecl == chkp_ret_bnd_fndecl);
- new_edge = edge->caller->create_edge (callee, stmt, edge->count,
+ new_edge = edge->caller->create_edge (callee,
+ as_a <gcall *> (stmt),
+ edge->count,
edge->frequency);
new_edge->frequency = compute_call_stmt_bb_frequency
(edge->caller->decl, gimple_bb (stmt));
@@ -3985,18 +3984,21 @@ chkp_instrument_function (void)
break;
case GIMPLE_RETURN:
- if (gimple_return_retval (s) != NULL_TREE)
- {
- chkp_process_stmt (&i, gimple_return_retval (s),
- gimple_location (s),
- integer_zero_node,
- NULL_TREE, NULL_TREE, safe);
-
- /* Additionally we need to add bounds
- to return statement. */
- chkp_add_bounds_to_ret_stmt (&i);
- }
- break;
+ {
+ greturn *r = as_a <greturn *> (s);
+ if (gimple_return_retval (r) != NULL_TREE)
+ {
+ chkp_process_stmt (&i, gimple_return_retval (r),
+ gimple_location (r),
+ integer_zero_node,
+ NULL_TREE, NULL_TREE, safe);
+
+ /* Additionally we need to add bounds
+ to return statement. */
+ chkp_add_bounds_to_ret_stmt (&i);
+ }
+ }
+ break;
case GIMPLE_CALL:
chkp_add_bounds_to_call_stmt (&i);
diff --git a/gcc/tree-chkp.h b/gcc/tree-chkp.h
index a349baf..71a29c0 100644
--- a/gcc/tree-chkp.h
+++ b/gcc/tree-chkp.h
@@ -46,7 +46,7 @@ extern tree chkp_build_bndstx_call (tree addr, tree ptr, tree bounds);
extern void chkp_find_bound_slots (const_tree type, bitmap res);
extern void chkp_build_bndstx (tree addr, tree ptr, tree bounds,
gimple_stmt_iterator *gsi);
-extern gimple chkp_retbnd_call_by_val (tree val);
+extern gcall *chkp_retbnd_call_by_val (tree val);
extern bool chkp_function_instrumented_p (tree fndecl);
extern void chkp_function_mark_instrumented (tree fndecl);
extern void chkp_copy_bounds_for_assign (gimple assign,
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 48bbb2e..58a0629 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1815,13 +1815,13 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
we handle not instrumented call in instrumented
function. */
nargs_to_copy = nargs;
- if (gimple_call_with_bounds_p (id->gimple_call)
+ if (gimple_call_with_bounds_p (id->call_stmt)
&& !gimple_call_with_bounds_p (stmt))
{
- for (i = gimple_call_num_args (id->gimple_call) - nargs;
- i < gimple_call_num_args (id->gimple_call);
+ for (i = gimple_call_num_args (id->call_stmt) - nargs;
+ i < gimple_call_num_args (id->call_stmt);
i++)
- if (POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i)))
+ if (POINTER_BOUNDS_P (gimple_call_arg (id->call_stmt, i)))
nargs_to_copy--;
remove_bounds = true;
}
@@ -1840,20 +1840,20 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
{
/* Append the rest of arguments removing bounds. */
unsigned cur = gimple_call_num_args (call_stmt);
- i = gimple_call_num_args (id->gimple_call) - nargs;
- for (i = gimple_call_num_args (id->gimple_call) - nargs;
- i < gimple_call_num_args (id->gimple_call);
+ i = gimple_call_num_args (id->call_stmt) - nargs;
+ for (i = gimple_call_num_args (id->call_stmt) - nargs;
+ i < gimple_call_num_args (id->call_stmt);
i++)
- if (!POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i)))
- argarray[cur++] = gimple_call_arg (id->gimple_call, i);
+ if (!POINTER_BOUNDS_P (gimple_call_arg (id->call_stmt, i)))
+ argarray[cur++] = gimple_call_arg (id->call_stmt, i);
gcc_assert (cur == n);
}
else
{
/* Append the arguments passed in '...' */
memcpy (argarray.address () + gimple_call_num_args (call_stmt),
- gimple_call_arg_ptr (id->gimple_call, 0)
- + (gimple_call_num_args (id->gimple_call) - nargs),
+ gimple_call_arg_ptr (id->call_stmt, 0)
+ + (gimple_call_num_args (id->call_stmt) - nargs),
nargs * sizeof (tree));
}
@@ -1889,10 +1889,10 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
nargs--;
/* For instrumented calls we should ignore bounds. */
- for (i = gimple_call_num_args (id->gimple_call) - nargs;
- i < gimple_call_num_args (id->gimple_call);
+ for (i = gimple_call_num_args (id->call_stmt) - nargs;
+ i < gimple_call_num_args (id->call_stmt);
i++)
- if (POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i)))
+ if (POINTER_BOUNDS_P (gimple_call_arg (id->call_stmt, i)))
nargs--;
count = build_int_cst (integer_type_node, nargs);
@@ -4509,7 +4509,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
if (gimple_call_with_bounds_p (stmt)
&& TREE_CODE (modify_dest) == SSA_NAME)
{
- gimple retbnd = chkp_retbnd_call_by_val (modify_dest);
+ gcall *retbnd = chkp_retbnd_call_by_val (modify_dest);
if (retbnd)
{
return_bounds = gimple_call_lhs (retbnd);
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index f0e51bb..4484513 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2223,10 +2223,10 @@ pass_forwprop::execute (function *fun)
bitmap_set_bit (to_purge, bb->index);
/* Cleanup the CFG if we simplified a condition to
true or false. */
- if (gimple_code (stmt) == GIMPLE_COND
- && (gimple_cond_true_p (stmt)
- || gimple_cond_false_p (stmt)))
- cfg_changed = true;
+ if (gcond *cond = dyn_cast <gcond *> (stmt))
+ if (gimple_cond_true_p (cond)
+ || gimple_cond_false_p (cond))
+ cfg_changed = true;
update_stmt (stmt);
}
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 26cd65f..7aac67d 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -1391,7 +1391,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call,
gcall *dcall_stmt;
gassign *load_stmt;
gcond *cond_stmt;
- gimple iretbnd_stmt = NULL;
+ gcall *iretbnd_stmt = NULL;
tree tmp0, tmp1, tmp;
basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL;
tree optype = build_pointer_type (void_type_node);
@@ -1400,7 +1400,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call,
int lp_nr, dflags;
edge e_eh, e;
edge_iterator ei;
- gphi_iterator psi;
+ gimple_stmt_iterator psi;
cond_bb = gimple_bb (icall_stmt);
gsi = gsi_for_stmt (icall_stmt);
@@ -1557,7 +1557,7 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call,
if (e_eh->flags & (EDGE_EH | EDGE_ABNORMAL))
{
e = make_edge (dcall_bb, e_eh->dest, e_eh->flags);
- for (psi = gsi_start_phis (e_eh->dest);
+ for (gphi_iterator psi = gsi_start_phis (e_eh->dest);
!gsi_end_p (psi); gsi_next (&psi))
{
gphi *phi = psi.phi ();
--
1.8.5.3