This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][4.5] Move gimplifier predicates


On Sat, Dec 6, 2008 at 6:10 PM, Richard Guenther <rguenther@suse.de> wrote:
> On Fri, 5 Dec 2008, Richard Guenther wrote:
>
>> On Fri, 5 Dec 2008, Diego Novillo wrote:
>>
>> > On Thu, Dec 4, 2008 at 12:10, Richard Guenther <rguenther@suse.de> wrote:
>> > >
>> > > This moves gimplifier predicates to where they belong and makes them
>> > > private. ?Apart from the uses in walk_gimple_op for which I have no
>> > > clue what this monster-function tries to do - Diego, do you remember?
>> >
>> > Sure. ?It walks the trees in the tuple operand slots. ?This is still
>> > different than the operand scanner, as it is a pure tree walk. ?It's
>> > seldom used, but still needed.
>> >
>> > > Index: trunk/gcc/gimple.c
>> > > ===================================================================
>> > > *** trunk.orig/gcc/gimple.c ? ? 2008-12-04 11:18:08.000000000 +0100
>> > > --- trunk/gcc/gimple.c ?2008-12-04 15:00:49.000000000 +0100
>> > > *************** walk_gimple_op (gimple stmt, walk_tree_f
>> > > *** 1373,1378 ****
>> > > --- 1373,1381 ----
>> > > ? ?struct pointer_set_t *pset = (wi) ? wi->pset : NULL;
>> > > ? ?unsigned i;
>> > > ? ?tree ret = NULL_TREE;
>> > > + ? /* ??? ?We shouldn't be using these here. ?*/
>> > > + ? extern bool is_gimple_formal_tmp_var (tree);
>> > > + ? extern bool is_gimple_mem_rhs (tree);
>> >
>> > Why not? ?gimple.c and gimplify.c are joined at the hip after all.
>> > It's perfectly fine for walk_gimple_op to want to use these
>> > predicates. ?The only way I see to get rid of them would be if the
>> > functionality they provide is not needed (i.e., wi->val_only).
>> >
>> > In fact, is_gimple_formal_tmp_var and is_gimple_mem_rhs make more
>> > sense to be provided by gimple.c instead of gimplify.c.
>>
>> The problem is that the _formal_tmp stuff does only work in the context
>> of gimplification. ?Which means that these are not predicates that
>> you can reliably use from elsewhere which means that they better should
>> not be exported. ?As is_gimple_mem_rhs calls a _formal_tmp variant the
>> same is true for it.
>>
>> See the strange places we set DECL_GIMPLE_FORMAL_TEMP_P in gimplify.c
>> and how we clean that flag again in pop_gimplify_context (not
>> reliably though dependent on what set that flag).
>>
>> This patch developed in the course of trying to understand the
>> correctness and optimization parts of DECL_GIMPLE_FORMAL_TEMP_P and
>> in trying to make DECL_GIMPLE_REG_P handling more general and not
>> dependent on is_gimple_reg_type.
>>
>> I will just put this patch on hold until I have more convincing
>> evidence in this area, but I do not agree with your simple
>> rationale ;)
>
> So the following removes DECL_GIMPLE_FORMAL_TEMP_P and instead fixes
> the long-standing post-modify fixme and moves the EH related split of
> the assignment and call into EH lowering which is IMHO where it belongs.
> It fixes some more stuff noticed in intermediate fallouts as well.
> It does not remove the temporary decl sharing with poor mans CSE.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for 4.5?
>
> As I want to extend the use of DECL_GIMPLE_REG_P this cleanup makes
> it easier to see what is going on.

I am currently re-bootstrapping and testing this patch and plan to commit it
soon.  Andrew - I believe the bytecode-only Java frontend always generates
the necessary temporaries, thus if there is no objection from you the Java parts
go in as posted.

Thanks,
Richard.

> Thanks,
> Richard.
>
> 2008-12-04 ?Richard Guenther ?<rguenther@suse.de>
>
> ? ? ? ?* tree.h (DECL_GIMPLE_FORMAL_TEMP_P): Remove.
> ? ? ? ?(struct tree_decl_with_vis): Remove gimple_formal_temp member.
> ? ? ? ?* tree-eh.c (lower_eh_constructs_2): Move LHS assignment to
> ? ? ? ?a separate statement.
> ? ? ? ?* gimplify.c (pop_gimplify_context): Remove formal temp handling.
> ? ? ? ?(lookup_tmp_var): Likewise.
> ? ? ? ?(is_gimple_formal_tmp_or_call_rhs): Remove.
> ? ? ? ?(is_gimple_reg_or_call_rhs): Rename to ...
> ? ? ? ?(is_gimple_reg_rhs_or_call): ... this.
> ? ? ? ?(is_gimple_mem_or_call_rhs): Rename to ...
> ? ? ? ?(is_gimple_mem_rhs_or_call): ... this.
> ? ? ? ?(internal_get_tmp_var): Use is_gimple_reg_rhs_or_call. ?Set
> ? ? ? ?DECL_GIMPLE_REG_P only if is_formal is true.
> ? ? ? ?(gimplify_compound_lval): Use is_gimple_reg. ?Remove workaround
> ? ? ? ?for non-proper post-modify expression gimplification.
> ? ? ? ?(gimplify_self_mod_expr): For post-modify expressions gimplify
> ? ? ? ?the lvalue to a minimal lvalue.
> ? ? ? ?(rhs_predicate_for): Remove formal temp case.
> ? ? ? ?(gimplify_modify_expr_rhs): Likewise.
> ? ? ? ?(gimplify_addr_expr): Use is_gimple_reg.
> ? ? ? ?(gimplify_expr): Remove formal temp cases.
> ? ? ? ?(gimple_regimplify_operands): Likewise.
> ? ? ? ?* tree-ssa-pre.c (get_or_alloc_expr_for): Treat EXC_PTR_EXPR
> ? ? ? ?and FILTER_EXPR like constants.
> ? ? ? ?* gimple.c (walk_gimple_op): Fix val_only initialization, use
> ? ? ? ?is_gimple_reg.
> ? ? ? ?(is_gimple_formal_tmp_rhs): Remove.
> ? ? ? ?(is_gimple_reg_rhs): Remove special casing.
> ? ? ? ?(is_gimple_mem_rhs): Fix.
> ? ? ? ?(is_gimple_reg): Move DECL_GIMPLE_REG_P handling earlier.
> ? ? ? ?(is_gimple_formal_tmp_var): Remove.
> ? ? ? ?(is_gimple_formal_tmp_reg): Likewise.
> ? ? ? ?(is_gimple_min_lval): Allow invariant component ref parts.
> ? ? ? ?* gimple.h (is_gimple_formal_tmp_rhs, is_gimple_formal_tmp_var,
> ? ? ? ?is_gimple_formal_tmp_reg): Remove declarations.
> ? ? ? ?* tree-cfg.c (verify_expr): Verify that variables with address
> ? ? ? ?taken do not have DECL_GIMPLE_REG_P set.
> ? ? ? ?* tree-mudflap.c (mf_build_check_statement_for): Use
> ? ? ? ?force_gimple_operand instead of gimplify_expr.
>
> ? ? ? ?java/
> ? ? ? ?* java-gimplify.c (java_gimplify_expr): Do not manually gimplify
> ? ? ? ?the first operand of binary and comaprison expressions.
>
> Index: gcc/java/java-gimplify.c
> ===================================================================
> *** gcc/java/java-gimplify.c ? ?(revision 142487)
> --- gcc/java/java-gimplify.c ? ?(working copy)
> *************** java_gimplify_expr (tree *expr_p, gimple
> *** 95,120 ****
> ? ? ? ?gcc_unreachable ();
>
> ? ? ?default:
> - ? ? ? /* Java insists on strict left-to-right evaluation of expressions.
> - ? ? ? ?A problem may arise if a variable used in the LHS of a binary
> - ? ? ? ?operation is altered by an assignment to that value in the RHS
> - ? ? ? ?before we've performed the operation. ?So, we always copy every
> - ? ? ? ?LHS to a temporary variable.
> -
> - ? ? ? ?FIXME: Are there any other cases where we should do this?
> - ? ? ? ?Parameter lists, maybe? ?Or perhaps that's unnecessary because
> - ? ? ? ?the front end already generates SAVE_EXPRs. ?*/
> -
> - ? ? ? if (TREE_CODE_CLASS (code) == tcc_binary
> - ? ? ? ? || TREE_CODE_CLASS (code) == tcc_comparison)
> - ? ? ? {
> - ? ? ? ? enum gimplify_status stat
> - ? ? ? ? ? = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ?is_gimple_formal_tmp_var, fb_rvalue);
> - ? ? ? ? if (stat == GS_ERROR)
> - ? ? ? ? ? return stat;
> - ? ? ? }
> -
> ? ? ? ?return GS_UNHANDLED;
> ? ? ?}
>
> --- 95,100 ----
> Index: gcc/tree.h
> ===================================================================
> *** gcc/tree.h ?(revision 142487)
> --- gcc/tree.h ?(working copy)
> *************** struct tree_parm_decl GTY(())
> *** 2918,2928 ****
> ? ?/* Used to indicate that this DECL has weak linkage. ?*/
> ?#define DECL_WEAK(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.weak_flag)
>
> - /* Internal to the gimplifier. ?Indicates that the value is a formal
> - ? ?temporary controlled by the gimplifier. ?*/
> - #define DECL_GIMPLE_FORMAL_TEMP_P(DECL) \
> - ? DECL_WITH_VIS_CHECK (DECL)->decl_with_vis.gimple_formal_temp
> -
> ?/* Used to indicate that the DECL is a dllimport. ?*/
> ?#define DECL_DLLIMPORT_P(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.dllimport_flag)
>
> --- 2918,2923 ----
> *************** struct tree_decl_with_vis GTY(())
> *** 3034,3040 ****
> ? unsigned thread_local:1;
> ? unsigned common_flag:1;
> ? unsigned in_text_section : 1;
> - ?unsigned gimple_formal_temp : 1;
> ? unsigned dllimport_flag : 1;
> ? unsigned based_on_restrict_p : 1;
> ? /* Used by C++. ?Might become a generic decl flag. ?*/
> --- 3029,3034 ----
> *************** struct tree_decl_with_vis GTY(())
> *** 3052,3058 ****
>
> ? /* Belongs to VAR_DECL exclusively. ?*/
> ? ENUM_BITFIELD(tls_model) tls_model : 3;
> ! ?/* 12 unused bits. */
> ?};
>
> ?/* In a VAR_DECL that's static,
> --- 3046,3052 ----
>
> ? /* Belongs to VAR_DECL exclusively. ?*/
> ? ENUM_BITFIELD(tls_model) tls_model : 3;
> ! ?/* 13 unused bits. */
> ?};
>
> ?/* In a VAR_DECL that's static,
> Index: gcc/tree-eh.c
> ===================================================================
> *** gcc/tree-eh.c ? ? ? (revision 142487)
> --- gcc/tree-eh.c ? ? ? (working copy)
> *************** lower_eh_constructs_2 (struct leh_state
> *** 1823,1828 ****
> --- 1823,1847 ----
> ? ? ?{
> ? ? ?case GIMPLE_CALL:
> ? ? ?case GIMPLE_ASSIGN:
> + ? ? ? /* If the stmt can throw use a new temporary for the assignment
> + ? ? ? ? ?to a LHS. ?This makes sure the old value of the LHS is
> + ? ? ? ?available on the EH edge. ?*/
> + ? ? ? if (stmt_could_throw_p (stmt)
> + ? ? ? ? && gimple_has_lhs (stmt)
> + ? ? ? ? && !tree_could_throw_p (gimple_get_lhs (stmt))
> + ? ? ? ? && is_gimple_reg_type (TREE_TYPE (gimple_get_lhs (stmt))))
> + ? ? ? {
> + ? ? ? ? tree lhs = gimple_get_lhs (stmt);
> + ? ? ? ? tree tmp = create_tmp_var (TREE_TYPE (lhs), NULL);
> + ? ? ? ? gimple s = gimple_build_assign (lhs, tmp);
> + ? ? ? ? gimple_set_location (s, gimple_location (stmt));
> + ? ? ? ? gimple_set_block (s, gimple_block (stmt));
> + ? ? ? ? gimple_set_lhs (stmt, tmp);
> + ? ? ? ? if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE
> + ? ? ? ? ? ? || TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE)
> + ? ? ? ? ? DECL_GIMPLE_REG_P (tmp) = 1;
> + ? ? ? ? gsi_insert_after (gsi, s, GSI_SAME_STMT);
> + ? ? ? }
> ? ? ? ?/* Look for things that can throw exceptions, and record them. ?*/
> ? ? ? ?if (state->cur_region && stmt_could_throw_p (stmt))
> ? ? ? ?{
> Index: gcc/gimplify.c
> ===================================================================
> *** gcc/gimplify.c ? ? ?(revision 142487)
> --- gcc/gimplify.c ? ? ?(working copy)
> *************** void
> *** 212,227 ****
> ?pop_gimplify_context (gimple body)
> ?{
> ? ?struct gimplify_ctx *c = gimplify_ctxp;
> - ? tree t;
>
> ? ?gcc_assert (c && (c->bind_expr_stack == NULL
> ? ? ? ? ? ? ? ? ? ?|| VEC_empty (gimple, c->bind_expr_stack)));
> ? ?VEC_free (gimple, heap, c->bind_expr_stack);
> ? ?gimplify_ctxp = c->prev_context;
>
> - ? for (t = c->temps; t ; t = TREE_CHAIN (t))
> - ? ? DECL_GIMPLE_FORMAL_TEMP_P (t) = 0;
> -
> ? ?if (body)
> ? ? ?declare_vars (c->temps, body, false);
> ? ?else
> --- 212,223 ----
> *************** lookup_tmp_var (tree val, bool is_formal
> *** 607,615 ****
> ? ? ? ?}
> ? ? ?}
>
> - ? if (is_formal)
> - ? ? DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1;
> -
> ? ?return ret;
> ?}
>
> --- 603,608 ----
> *************** lookup_tmp_var (tree val, bool is_formal
> *** 620,651 ****
> ? ? gimplify_modify_expr. ?*/
>
> ?static bool
> ! is_gimple_formal_tmp_or_call_rhs (tree t)
> ?{
> ! ? return TREE_CODE (t) == CALL_EXPR || is_gimple_formal_tmp_rhs (t);
> ! }
> !
> ! /* Returns true iff T is a valid RHS for an assignment to a renamed
> ! ? ?user -- or front-end generated artificial -- variable. ?*/
> !
> ! static bool
> ! is_gimple_reg_or_call_rhs (tree t)
> ! {
> ! ? /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto
> ! ? ? ?and the LHS is a user variable, then we need to introduce a formal
> ! ? ? ?temporary. ?This way the optimizers can determine that the user
> ! ? ? ?variable is only modified if evaluation of the RHS does not throw.
> !
> ! ? ? ?Don't force a temp of a non-renamable type; the copy could be
> ! ? ? ?arbitrarily expensive. ?Instead we will generate a VDEF for
> ! ? ? ?the assignment. ?*/
> !
> ! ? if (is_gimple_reg_type (TREE_TYPE (t))
> ! ? ? ? && ((TREE_CODE (t) == CALL_EXPR && TREE_SIDE_EFFECTS (t))
> ! ? ? ? ? || tree_could_throw_p (t)))
> ! ? ? return false;
> !
> ! ? return is_gimple_formal_tmp_or_call_rhs (t);
> ?}
>
> ?/* Return true if T is a valid memory RHS or a CALL_EXPR. ?Note that
> --- 613,622 ----
> ? ? gimplify_modify_expr. ?*/
>
> ?static bool
> ! is_gimple_reg_rhs_or_call (tree t)
> ?{
> ! ? return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
> ! ? ? ? ? || TREE_CODE (t) == CALL_EXPR);
> ?}
>
> ?/* Return true if T is a valid memory RHS or a CALL_EXPR. ?Note that
> *************** is_gimple_reg_or_call_rhs (tree t)
> *** 653,680 ****
> ? ? rationale for this in gimplify_modify_expr. ?*/
>
> ?static bool
> ! is_gimple_mem_or_call_rhs (tree t)
> ?{
> ? ?/* If we're dealing with a renamable type, either source or dest must be
> ? ? ? a renamed variable. ?*/
> ? ?if (is_gimple_reg_type (TREE_TYPE (t)))
> ? ? ?return is_gimple_val (t);
> ? ?else
> ! ? ? return is_gimple_formal_tmp_or_call_rhs (t);
> ?}
>
> !
> ! /* Returns a formal temporary variable initialized with VAL. ?PRE_P is as
> ! ? ?in gimplify_expr. ?Only use this function if:
> !
> ! ? ?1) The value of the unfactored expression represented by VAL will not
> ! ? ? ? change between the initialization and use of the temporary, and
> ! ? ?2) The temporary will not be otherwise modified.
> !
> ! ? ?For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
> ! ? ?and #2 means it is inappropriate for && temps.
> !
> ! ? ?For other cases, use get_initialized_tmp_var instead. ?*/
>
> ?static tree
> ?internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
> --- 624,641 ----
> ? ? rationale for this in gimplify_modify_expr. ?*/
>
> ?static bool
> ! is_gimple_mem_rhs_or_call (tree t)
> ?{
> ? ?/* If we're dealing with a renamable type, either source or dest must be
> ? ? ? a renamed variable. ?*/
> ? ?if (is_gimple_reg_type (TREE_TYPE (t)))
> ? ? ?return is_gimple_val (t);
> ? ?else
> ! ? ? return (is_gimple_val (t) || is_gimple_lvalue (t)
> ! ? ? ? ? ? || TREE_CODE (t) == CALL_EXPR);
> ?}
>
> ! /* Helper for get_formal_tmp_var and get_initialized_tmp_var. ?*/
>
> ?static tree
> ?internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
> *************** internal_get_tmp_var (tree val, gimple_s
> *** 684,690 ****
>
> ? ?/* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
> ? ? ? can create an INIT_EXPR and convert it into a GIMPLE_CALL below. ?*/
> ! ? gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_or_call_rhs,
> ? ? ? ? ? ? ? ? fb_rvalue);
>
> ? ?t = lookup_tmp_var (val, is_formal);
> --- 645,651 ----
>
> ? ?/* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
> ? ? ? can create an INIT_EXPR and convert it into a GIMPLE_CALL below. ?*/
> ! ? gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
> ? ? ? ? ? ? ? ? fb_rvalue);
>
> ? ?t = lookup_tmp_var (val, is_formal);
> *************** internal_get_tmp_var (tree val, gimple_s
> *** 705,715 ****
> ? ? ? ? ? ? ?SET_DECL_RESTRICT_BASE (t, u);
> ? ? ? ? ? ?}
> ? ? ? ?}
> - ? ? }
>
> ! ? if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
> ! ? ? ? || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
> ! ? ? DECL_GIMPLE_REG_P (t) = 1;
>
> ? ?mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
>
> --- 666,676 ----
> ? ? ? ? ? ? ?SET_DECL_RESTRICT_BASE (t, u);
> ? ? ? ? ? ?}
> ? ? ? ?}
>
> ! ? ? ? if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
> ! ? ? ? ? || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
> ! ? ? ? DECL_GIMPLE_REG_P (t) = 1;
> ! ? ? }
>
> ? ?mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
>
> *************** internal_get_tmp_var (tree val, gimple_s
> *** 733,741 ****
> ? ?return t;
> ?}
>
> ! /* Returns a formal temporary variable initialized with VAL. ?PRE_P
> ! ? ?points to a sequence where side-effects needed to compute VAL should be
> ! ? ?stored. ?*/
>
> ?tree
> ?get_formal_tmp_var (tree val, gimple_seq *pre_p)
> --- 694,710 ----
> ? ?return t;
> ?}
>
> ! /* Returns a formal temporary variable initialized with VAL. ?PRE_P is as
> ! ? ?in gimplify_expr. ?Only use this function if:
> !
> ! ? ?1) The value of the unfactored expression represented by VAL will not
> ! ? ? ? change between the initialization and use of the temporary, and
> ! ? ?2) The temporary will not be otherwise modified.
> !
> ! ? ?For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
> ! ? ?and #2 means it is inappropriate for && temps.
> !
> ! ? ?For other cases, use get_initialized_tmp_var instead. ?*/
>
> ?tree
> ?get_formal_tmp_var (tree val, gimple_seq *pre_p)
> *************** gimplify_compound_lval (tree *expr_p, gi
> *** 2001,2007 ****
> ? ? ? ? ? ? ? ?{
> ? ? ? ? ? ? ? ? ?TREE_OPERAND (t, 2) = low;
> ? ? ? ? ? ? ? ? ?tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? post_p, is_gimple_formal_tmp_reg,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fb_rvalue);
> ? ? ? ? ? ? ? ? ?ret = MIN (ret, tret);
> ? ? ? ? ? ? ? ?}
> --- 1970,1976 ----
> ? ? ? ? ? ? ? ?{
> ? ? ? ? ? ? ? ? ?TREE_OPERAND (t, 2) = low;
> ? ? ? ? ? ? ? ? ?tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? post_p, is_gimple_reg,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fb_rvalue);
> ? ? ? ? ? ? ? ? ?ret = MIN (ret, tret);
> ? ? ? ? ? ? ? ?}
> *************** gimplify_compound_lval (tree *expr_p, gi
> *** 2021,2027 ****
> ? ? ? ? ? ? ? ?{
> ? ? ? ? ? ? ? ? ?TREE_OPERAND (t, 3) = elmt_size;
> ? ? ? ? ? ? ? ? ?tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? post_p, is_gimple_formal_tmp_reg,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fb_rvalue);
> ? ? ? ? ? ? ? ? ?ret = MIN (ret, tret);
> ? ? ? ? ? ? ? ?}
> --- 1990,1996 ----
> ? ? ? ? ? ? ? ?{
> ? ? ? ? ? ? ? ? ?TREE_OPERAND (t, 3) = elmt_size;
> ? ? ? ? ? ? ? ? ?tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? post_p, is_gimple_reg,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fb_rvalue);
> ? ? ? ? ? ? ? ? ?ret = MIN (ret, tret);
> ? ? ? ? ? ? ? ?}
> *************** gimplify_compound_lval (tree *expr_p, gi
> *** 2044,2050 ****
> ? ? ? ? ? ? ? ?{
> ? ? ? ? ? ? ? ? ?TREE_OPERAND (t, 2) = offset;
> ? ? ? ? ? ? ? ? ?tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? post_p, is_gimple_formal_tmp_reg,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fb_rvalue);
> ? ? ? ? ? ? ? ? ?ret = MIN (ret, tret);
> ? ? ? ? ? ? ? ?}
> --- 2013,2019 ----
> ? ? ? ? ? ? ? ?{
> ? ? ? ? ? ? ? ? ?TREE_OPERAND (t, 2) = offset;
> ? ? ? ? ? ? ? ? ?tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? post_p, is_gimple_reg,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fb_rvalue);
> ? ? ? ? ? ? ? ? ?ret = MIN (ret, tret);
> ? ? ? ? ? ? ? ?}
> *************** gimplify_compound_lval (tree *expr_p, gi
> *** 2067,2085 ****
>
> ? ? ? ?if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
> ? ? ? ?{
> ! ? ? ? ? /* Gimplify the dimension.
> ! ? ? ? ? ? ?Temporary fix for gcc.c-torture/execute/20040313-1.c.
> ! ? ? ? ? ? ?Gimplify non-constant array indices into a temporary
> ! ? ? ? ? ? ?variable.
> ! ? ? ? ? ? ?FIXME - The real fix is to gimplify post-modify
> ! ? ? ? ? ? ?expressions into a minimal gimple lvalue. ?However, that
> ! ? ? ? ? ? ?exposes bugs in alias analysis. ?The alias analyzer does
> ! ? ? ? ? ? ?not handle &PTR->FIELD very well. ?Will fix after the
> ! ? ? ? ? ? ?branch is merged into mainline (dnovillo 2004-05-03). ?*/
> ? ? ? ? ?if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
> ? ? ? ? ? ?{
> ? ? ? ? ? ? ?tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? is_gimple_formal_tmp_reg, fb_rvalue);
> ? ? ? ? ? ? ?ret = MIN (ret, tret);
> ? ? ? ? ? ?}
> ? ? ? ?}
> --- 2036,2046 ----
>
> ? ? ? ?if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
> ? ? ? ?{
> ! ? ? ? ? /* Gimplify the dimension. ?*/
> ? ? ? ? ?if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
> ? ? ? ? ? ?{
> ? ? ? ? ? ? ?tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? is_gimple_val, fb_rvalue);
> ? ? ? ? ? ? ?ret = MIN (ret, tret);
> ? ? ? ? ? ?}
> ? ? ? ?}
> *************** gimplify_self_mod_expr (tree *expr_p, gi
> *** 2171,2179 ****
> ? ?rhs = TREE_OPERAND (*expr_p, 1);
>
> ? ?/* For postfix operator, we evaluate the LHS to an rvalue and then use
> ! ? ? ?that as the result value and in the postqueue operation. ?*/
> ? ?if (postfix)
> ? ? ?{
> ? ? ? ?ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
> ? ? ? ?if (ret == GS_ERROR)
> ? ? ? ?return ret;
> --- 2132,2149 ----
> ? ?rhs = TREE_OPERAND (*expr_p, 1);
>
> ? ?/* For postfix operator, we evaluate the LHS to an rvalue and then use
> ! ? ? ?that as the result value and in the postqueue operation. ?We also
> ! ? ? ?make sure to make lvalue a minimal lval, see
> ! ? ? ?gcc.c-torture/execute/20040313-1.c for an example where this matters. ?*/
> ? ?if (postfix)
> ? ? ?{
> + ? ? ? if (!is_gimple_min_lval (lvalue))
> + ? ? ? {
> + ? ? ? ? mark_addressable (lvalue);
> + ? ? ? ? lvalue = build_fold_addr_expr (lvalue);
> + ? ? ? ? gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue);
> + ? ? ? ? lvalue = build_fold_indirect_ref (lvalue);
> + ? ? ? }
> ? ? ? ?ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
> ? ? ? ?if (ret == GS_ERROR)
> ? ? ? ?return ret;
> *************** gimplify_init_ctor_eval (tree object, VE
> *** 3445,3456 ****
> ?gimple_predicate
> ?rhs_predicate_for (tree lhs)
> ?{
> ! ? if (is_gimple_formal_tmp_var (lhs))
> ! ? ? return is_gimple_formal_tmp_or_call_rhs;
> ! ? else if (is_gimple_reg (lhs))
> ! ? ? return is_gimple_reg_or_call_rhs;
> ? ?else
> ! ? ? return is_gimple_mem_or_call_rhs;
> ?}
>
>
> --- 3415,3424 ----
> ?gimple_predicate
> ?rhs_predicate_for (tree lhs)
> ?{
> ! ? if (is_gimple_reg (lhs))
> ! ? ? return is_gimple_reg_rhs_or_call;
> ? ?else
> ! ? ? return is_gimple_mem_rhs_or_call;
> ?}
>
>
> *************** gimplify_modify_expr_rhs (tree *expr_p,
> *** 4031,4041 ****
> ? ? ? ? ? ? ? ? ? ? || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
> ? ? ? ? ? ? ?/* Don't force regs into memory. ?*/
> ? ? ? ? ? ? ?use_target = false;
> - ? ? ? ? ? else if (TREE_CODE (*to_p) == VAR_DECL
> - ? ? ? ? ? ? ? ? ? ?&& DECL_GIMPLE_FORMAL_TEMP_P (*to_p))
> - ? ? ? ? ? ? /* Don't use the original target if it's a formal temp; we
> - ? ? ? ? ? ? ? ?don't want to take their addresses. ?*/
> - ? ? ? ? ? ? use_target = false;
> ? ? ? ? ? ?else if (TREE_CODE (*expr_p) == INIT_EXPR)
> ? ? ? ? ? ? ?/* It's OK to use the target directly if it's being
> ? ? ? ? ? ? ? ? initialized. */
> --- 3999,4004 ----
> *************** gimplify_addr_expr (tree *expr_p, gimple
> *** 4535,4541 ****
> ? ? ? ? This mostly happens if the frontend passed us something that
> ? ? ? ? it could not mark addressable yet, like a fortran
> ? ? ? ? pass-by-reference parameter (int) floatvar. ?*/
> ! ? ? ? if (is_gimple_formal_tmp_var (TREE_OPERAND (expr, 0)))
> ? ? ? ?TREE_OPERAND (expr, 0)
> ? ? ? ? ?= get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p);
>
> --- 4498,4504 ----
> ? ? ? ? This mostly happens if the frontend passed us something that
> ? ? ? ? it could not mark addressable yet, like a fortran
> ? ? ? ? pass-by-reference parameter (int) floatvar. ?*/
> ! ? ? ? if (is_gimple_reg (TREE_OPERAND (expr, 0)))
> ? ? ? ?TREE_OPERAND (expr, 0)
> ? ? ? ? ?= get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p);
>
> *************** gimplify_expr (tree *expr_p, gimple_seq
> *** 6178,6193 ****
> ? ?if (gimple_test_f == is_gimple_reg)
> ? ? ?gcc_assert (fallback & (fb_rvalue | fb_lvalue));
> ? ?else if (gimple_test_f == is_gimple_val
> - ? ? ? ? ? ?|| gimple_test_f == is_gimple_formal_tmp_rhs
> - ? ? ? ? ? ?|| gimple_test_f == is_gimple_formal_tmp_or_call_rhs
> - ? ? ? ? ? ?|| gimple_test_f == is_gimple_formal_tmp_reg
> - ? ? ? ? ? ?|| gimple_test_f == is_gimple_formal_tmp_var
> ? ? ? ? ? ? || gimple_test_f == is_gimple_call_addr
> ? ? ? ? ? ? || gimple_test_f == is_gimple_condexpr
> ? ? ? ? ? ? || gimple_test_f == is_gimple_mem_rhs
> ! ? ? ? ? ? ?|| gimple_test_f == is_gimple_mem_or_call_rhs
> ? ? ? ? ? ? || gimple_test_f == is_gimple_reg_rhs
> ! ? ? ? ? ? ?|| gimple_test_f == is_gimple_reg_or_call_rhs
> ? ? ? ? ? ? || gimple_test_f == is_gimple_asm_val)
> ? ? ?gcc_assert (fallback & fb_rvalue);
> ? ?else if (gimple_test_f == is_gimple_min_lval
> --- 6141,6152 ----
> ? ?if (gimple_test_f == is_gimple_reg)
> ? ? ?gcc_assert (fallback & (fb_rvalue | fb_lvalue));
> ? ?else if (gimple_test_f == is_gimple_val
> ? ? ? ? ? ? || gimple_test_f == is_gimple_call_addr
> ? ? ? ? ? ? || gimple_test_f == is_gimple_condexpr
> ? ? ? ? ? ? || gimple_test_f == is_gimple_mem_rhs
> ! ? ? ? ? ? ?|| gimple_test_f == is_gimple_mem_rhs_or_call
> ? ? ? ? ? ? || gimple_test_f == is_gimple_reg_rhs
> ! ? ? ? ? ? ?|| gimple_test_f == is_gimple_reg_rhs_or_call
> ? ? ? ? ? ? || gimple_test_f == is_gimple_asm_val)
> ? ? ?gcc_assert (fallback & fb_rvalue);
> ? ?else if (gimple_test_f == is_gimple_min_lval
> *************** gimplify_expr (tree *expr_p, gimple_seq
> *** 6986,6992 ****
> ? ? ? ?gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
> ? ? ? ?*expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
> ? ? ?}
> ! ? else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_or_call_rhs (*expr_p))
> ? ? ?{
> ? ? ? ?/* An rvalue will do. ?Assign the gimplified expression into a
> ? ? ? ? new temporary TMP and replace the original expression with
> --- 6945,6951 ----
> ? ? ? ?gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
> ? ? ? ?*expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
> ? ? ?}
> ! ? else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
> ? ? ?{
> ? ? ? ?/* An rvalue will do. ?Assign the gimplified expression into a
> ? ? ? ? new temporary TMP and replace the original expression with
> *************** gimplify_expr (tree *expr_p, gimple_seq
> *** 7001,7009 ****
> ? ? ? ?*expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
> ? ? ? ?else
> ? ? ? ?*expr_p = get_formal_tmp_var (*expr_p, pre_p);
> -
> - ? ? ? if (TREE_CODE (*expr_p) != SSA_NAME)
> - ? ? ? DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1;
> ? ? ?}
> ? ?else
> ? ? ?{
> --- 6960,6965 ----
> *************** gimple_regimplify_operands (gimple stmt,
> *** 7449,7455 ****
> ? ? ? ?lhs = gimple_get_lhs (stmt);
> ? ? ? ?/* If regimplification of the LHS changed it in a way that requires
> ? ? ? ? a simple RHS, create temporary. ?*/
> ! ? ? ? if (orig_lhs != lhs && !is_gimple_formal_tmp_var (lhs))
> ? ? ? ?{
> ? ? ? ? ?bool need_temp = false;
>
> --- 7405,7411 ----
> ? ? ? ?lhs = gimple_get_lhs (stmt);
> ? ? ? ?/* If regimplification of the LHS changed it in a way that requires
> ? ? ? ? a simple RHS, create temporary. ?*/
> ! ? ? ? if (orig_lhs != lhs && !is_gimple_reg (lhs))
> ? ? ? ?{
> ? ? ? ? ?bool need_temp = false;
>
> *************** gimple_regimplify_operands (gimple stmt,
> *** 7498,7504 ****
> ? ? ? ? ? ?{
> ? ? ? ? ? ? ?tree temp = create_tmp_var (TREE_TYPE (lhs), NULL);
>
> - ? ? ? ? ? ? DECL_GIMPLE_FORMAL_TEMP_P (temp) = 1;
> ? ? ? ? ? ? ?if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE
> ? ? ? ? ? ? ? ? ?|| TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE)
> ? ? ? ? ? ? ? ?DECL_GIMPLE_REG_P (temp) = 1;
> --- 7454,7459 ----
> Index: gcc/tree-ssa-pre.c
> ===================================================================
> *** gcc/tree-ssa-pre.c ?(revision 142487)
> --- gcc/tree-ssa-pre.c ?(working copy)
> *************** get_or_alloc_expr_for (tree t)
> *** 1044,1050 ****
> ?{
> ? ?if (TREE_CODE (t) == SSA_NAME)
> ? ? ?return get_or_alloc_expr_for_name (t);
> ! ? else if (is_gimple_min_invariant (t))
> ? ? ?return get_or_alloc_expr_for_constant (t);
> ? ?else
> ? ? ?{
> --- 1044,1052 ----
> ?{
> ? ?if (TREE_CODE (t) == SSA_NAME)
> ? ? ?return get_or_alloc_expr_for_name (t);
> ! ? else if (is_gimple_min_invariant (t)
> ! ? ? ? ? ?|| TREE_CODE (t) == EXC_PTR_EXPR
> ! ? ? ? ? ?|| TREE_CODE (t) == FILTER_EXPR)
> ? ? ?return get_or_alloc_expr_for_constant (t);
> ? ?else
> ? ? ?{
> Index: gcc/tree-mudflap.c
> ===================================================================
> *** gcc/tree-mudflap.c ?(revision 142487)
> --- gcc/tree-mudflap.c ?(working copy)
> *************** mf_build_check_statement_for (tree base,
> *** 503,509 ****
> ? ?tree mf_elem;
> ? ?tree mf_limit;
> ? ?gimple g;
> ! ? gimple_seq seq;
>
> ? ?/* We first need to split the current basic block, and start altering
> ? ? ? the CFG. ?This allows us to insert the statements we're about to
> --- 503,509 ----
> ? ?tree mf_elem;
> ? ?tree mf_limit;
> ? ?gimple g;
> ! ? gimple_seq seq, stmts;
>
> ? ?/* We first need to split the current basic block, and start altering
> ? ? ? the CFG. ?This allows us to insert the statements we're about to
> *************** mf_build_check_statement_for (tree base,
> *** 553,566 ****
> ? ?/* Build: __mf_base = (uintptr_t) <base address expression>. ?*/
> ? ?seq = gimple_seq_alloc ();
> ? ?t = fold_convert (mf_uintptr_type, unshare_expr (base));
> ! ? gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
> ? ?g = gimple_build_assign (mf_base, t);
> ? ?gimple_set_location (g, location);
> ? ?gimple_seq_add_stmt (&seq, g);
>
> ? ?/* Build: __mf_limit = (uintptr_t) <limit address expression>. ?*/
> ? ?t = fold_convert (mf_uintptr_type, unshare_expr (limit));
> ! ? gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
> ? ?g = gimple_build_assign (mf_limit, t);
> ? ?gimple_set_location (g, location);
> ? ?gimple_seq_add_stmt (&seq, g);
> --- 553,568 ----
> ? ?/* Build: __mf_base = (uintptr_t) <base address expression>. ?*/
> ? ?seq = gimple_seq_alloc ();
> ? ?t = fold_convert (mf_uintptr_type, unshare_expr (base));
> ! ? t = force_gimple_operand (t, &stmts, false, NULL_TREE);
> ! ? gimple_seq_add_seq (&seq, stmts);
> ? ?g = gimple_build_assign (mf_base, t);
> ? ?gimple_set_location (g, location);
> ? ?gimple_seq_add_stmt (&seq, g);
>
> ? ?/* Build: __mf_limit = (uintptr_t) <limit address expression>. ?*/
> ? ?t = fold_convert (mf_uintptr_type, unshare_expr (limit));
> ! ? t = force_gimple_operand (t, &stmts, false, NULL_TREE);
> ! ? gimple_seq_add_seq (&seq, stmts);
> ? ?g = gimple_build_assign (mf_limit, t);
> ? ?gimple_set_location (g, location);
> ? ?gimple_seq_add_stmt (&seq, g);
> *************** mf_build_check_statement_for (tree base,
> *** 577,583 ****
> ? ? ? ? ? ? ? ?TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
> ? ? ? ? ? ? ? ?mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
> ? ?t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
> ! ? gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
> ? ?g = gimple_build_assign (mf_elem, t);
> ? ?gimple_set_location (g, location);
> ? ?gimple_seq_add_stmt (&seq, g);
> --- 579,586 ----
> ? ? ? ? ? ? ? ?TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
> ? ? ? ? ? ? ? ?mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
> ? ?t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
> ! ? t = force_gimple_operand (t, &stmts, false, NULL_TREE);
> ! ? gimple_seq_add_seq (&seq, stmts);
> ? ?g = gimple_build_assign (mf_elem, t);
> ? ?gimple_set_location (g, location);
> ? ?gimple_seq_add_stmt (&seq, g);
> *************** mf_build_check_statement_for (tree base,
> *** 622,628 ****
> ? ? ? result of the evaluation of 't' in a temporary variable which we
> ? ? ? can use as the condition for the conditional jump. ?*/
> ? ?t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
> ! ? gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
> ? ?cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
> ? ?g = gimple_build_assign ?(cond, t);
> ? ?gimple_set_location (g, location);
> --- 625,632 ----
> ? ? ? result of the evaluation of 't' in a temporary variable which we
> ? ? ? can use as the condition for the conditional jump. ?*/
> ? ?t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
> ! ? t = force_gimple_operand (t, &stmts, false, NULL_TREE);
> ! ? gimple_seq_add_seq (&seq, stmts);
> ? ?cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
> ? ?g = gimple_build_assign ?(cond, t);
> ? ?gimple_set_location (g, location);
> *************** mf_build_check_statement_for (tree base,
> *** 663,669 ****
> ? ?v = fold_build2 (PLUS_EXPR, integer_type_node,
> ? ? ? ? ? ? ? ? ? fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
> ? ? ? ? ? ? ? ? ? integer_one_node);
> ! ? gimplify_expr (&v, &seq, &seq, is_gimple_mem_rhs, fb_rvalue);
> ? ?g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
> ? ?gimple_seq_add_stmt (&seq, g);
>
> --- 667,674 ----
> ? ?v = fold_build2 (PLUS_EXPR, integer_type_node,
> ? ? ? ? ? ? ? ? ? fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
> ? ? ? ? ? ? ? ? ? integer_one_node);
> ! ? v = force_gimple_operand (v, &stmts, true, NULL_TREE);
> ! ? gimple_seq_add_seq (&seq, stmts);
> ? ?g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
> ? ?gimple_seq_add_stmt (&seq, g);
>
> Index: gcc/gimple.c
> ===================================================================
> *** gcc/gimple.c ? ? ? ?(revision 142487)
> --- gcc/gimple.c ? ? ? ?(working copy)
> *************** walk_gimple_op (gimple stmt, walk_tree_f
> *** 1380,1386 ****
> ? ? ? ?/* Walk the RHS operands. ?A formal temporary LHS may use a
> ? ? ? ? COMPONENT_REF RHS. ?*/
> ? ? ? ?if (wi)
> ! ? ? ? wi->val_only = !is_gimple_formal_tmp_var (gimple_assign_lhs (stmt));
>
> ? ? ? ?for (i = 1; i < gimple_num_ops (stmt); i++)
> ? ? ? ?{
> --- 1380,1387 ----
> ? ? ? ?/* Walk the RHS operands. ?A formal temporary LHS may use a
> ? ? ? ? COMPONENT_REF RHS. ?*/
> ? ? ? ?if (wi)
> ! ? ? ? wi->val_only = !is_gimple_reg (gimple_assign_lhs (stmt))
> ! ? ? ? ? ? ? ? ? ? ? ? ?|| !gimple_assign_single_p (stmt);
>
> ? ? ? ?for (i = 1; i < gimple_num_ops (stmt); i++)
> ? ? ? ?{
> *************** is_gimple_operand (const_tree op)
> *** 2559,2595 ****
> ? ?return op && get_gimple_rhs_class (TREE_CODE (op)) == GIMPLE_SINGLE_RHS;
> ?}
>
> -
> - /* Return true if T is a GIMPLE RHS for an assignment to a temporary. ?*/
> -
> - bool
> - is_gimple_formal_tmp_rhs (tree t)
> - {
> - ? if (is_gimple_lvalue (t) || is_gimple_val (t))
> - ? ? return true;
> -
> - ? return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
> - }
> -
> ?/* Returns true iff T is a valid RHS for an assignment to a renamed
> ? ? user -- or front-end generated artificial -- variable. ?*/
>
> ?bool
> ?is_gimple_reg_rhs (tree t)
> ?{
> ! ? /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto
> ! ? ? ?and the LHS is a user variable, then we need to introduce a formal
> ! ? ? ?temporary. ?This way the optimizers can determine that the user
> ! ? ? ?variable is only modified if evaluation of the RHS does not throw.
> !
> ! ? ? ?Don't force a temp of a non-renamable type; the copy could be
> ! ? ? ?arbitrarily expensive. ?Instead we will generate a VDEF for
> ! ? ? ?the assignment. ?*/
> !
> ! ? if (is_gimple_reg_type (TREE_TYPE (t)) && tree_could_throw_p (t))
> ! ? ? return false;
> !
> ! ? return is_gimple_formal_tmp_rhs (t);
> ?}
>
> ?/* Returns true iff T is a valid RHS for an assignment to an un-renamed
> --- 2560,2572 ----
> ? ?return op && get_gimple_rhs_class (TREE_CODE (op)) == GIMPLE_SINGLE_RHS;
> ?}
>
> ?/* Returns true iff T is a valid RHS for an assignment to a renamed
> ? ? user -- or front-end generated artificial -- variable. ?*/
>
> ?bool
> ?is_gimple_reg_rhs (tree t)
> ?{
> ! ? return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
> ?}
>
> ?/* Returns true iff T is a valid RHS for an assignment to an un-renamed
> *************** is_gimple_mem_rhs (tree t)
> *** 2603,2609 ****
> ? ?if (is_gimple_reg_type (TREE_TYPE (t)))
> ? ? ?return is_gimple_val (t);
> ? ?else
> ! ? ? return is_gimple_formal_tmp_rhs (t);
> ?}
>
> ?/* ?Return true if T is a valid LHS for a GIMPLE assignment expression. ?*/
> --- 2580,2586 ----
> ? ?if (is_gimple_reg_type (TREE_TYPE (t)))
> ? ? ?return is_gimple_val (t);
> ? ?else
> ! ? ? return is_gimple_val (t) || is_gimple_lvalue (t);
> ?}
>
> ?/* ?Return true if T is a valid LHS for a GIMPLE assignment expression. ?*/
> *************** is_gimple_reg (tree t)
> *** 2895,2900 ****
> --- 2872,2883 ----
> ? ?if (!is_gimple_variable (t))
> ? ? ?return false;
>
> + ? /* Complex and vector values must have been put into SSA-like form.
> + ? ? ?That is, no assignments to the individual components. ?*/
> + ? if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
> + ? ? ? || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
> + ? ? return DECL_GIMPLE_REG_P (t);
> +
> ? ?if (!is_gimple_reg_type (TREE_TYPE (t)))
> ? ? ?return false;
>
> *************** is_gimple_reg (tree t)
> *** 2921,2965 ****
> ? ?if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
> ? ? ?return false;
>
> - ? /* Complex and vector values must have been put into SSA-like form.
> - ? ? ?That is, no assignments to the individual components. ?*/
> - ? if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
> - ? ? ? || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
> - ? ? return DECL_GIMPLE_REG_P (t);
> -
> ? ?return true;
> ?}
>
>
> - /* Returns true if T is a GIMPLE formal temporary variable. ?*/
> -
> - bool
> - is_gimple_formal_tmp_var (tree t)
> - {
> - ? if (TREE_CODE (t) == SSA_NAME)
> - ? ? return true;
> -
> - ? return TREE_CODE (t) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (t);
> - }
> -
> - /* Returns true if T is a GIMPLE formal temporary register variable. ?*/
> -
> - bool
> - is_gimple_formal_tmp_reg (tree t)
> - {
> - ? /* The intent of this is to get hold of a value that won't change.
> - ? ? ?An SSA_NAME qualifies no matter if its of a user variable or not. ?*/
> - ? if (TREE_CODE (t) == SSA_NAME)
> - ? ? return true;
> -
> - ? /* We don't know the lifetime characteristics of user variables. ?*/
> - ? if (!is_gimple_formal_tmp_var (t))
> - ? ? return false;
> -
> - ? /* Finally, it must be capable of being placed in a register. ?*/
> - ? return is_gimple_reg (t);
> - }
> -
> ?/* Return true if T is a GIMPLE variable whose address is not needed. ?*/
>
> ?bool
> --- 2904,2913 ----
> *************** is_gimple_asm_val (tree t)
> *** 3006,3011 ****
> --- 2954,2961 ----
> ?bool
> ?is_gimple_min_lval (tree t)
> ?{
> + ? if (!(t = CONST_CAST_TREE (strip_invariant_refs (t))))
> + ? ? return false;
> ? ?return (is_gimple_id (t) || TREE_CODE (t) == INDIRECT_REF);
> ?}
>
> Index: gcc/gimple.h
> ===================================================================
> *** gcc/gimple.h ? ? ? ?(revision 142487)
> --- gcc/gimple.h ? ? ? ?(working copy)
> *************** extern bool is_gimple_stmt (tree);
> *** 857,866 ****
> ?extern bool is_gimple_reg_type (tree);
> ?/* Returns true iff T is a scalar register variable. ?*/
> ?extern bool is_gimple_reg (tree);
> - /* Returns true if T is a GIMPLE temporary variable, false otherwise. ?*/
> - extern bool is_gimple_formal_tmp_var (tree);
> - /* Returns true if T is a GIMPLE temporary register variable. ?*/
> - extern bool is_gimple_formal_tmp_reg (tree);
> ?/* Returns true iff T is any sort of variable. ?*/
> ?extern bool is_gimple_variable (tree);
> ?/* Returns true iff T is any sort of symbol. ?*/
> --- 857,862 ----
> *************** extern bool is_gimple_asm_val (tree);
> *** 892,898 ****
> ?/* Returns true iff T is a valid rhs for a MODIFY_EXPR where the LHS is a
> ? ? GIMPLE temporary, a renamed user variable, or something else,
> ? ? respectively. ?*/
> - extern bool is_gimple_formal_tmp_rhs (tree);
> ?extern bool is_gimple_reg_rhs (tree);
> ?extern bool is_gimple_mem_rhs (tree);
>
> --- 888,893 ----
> Index: gcc/tree-cfg.c
> ===================================================================
> *** gcc/tree-cfg.c ? ? ?(revision 142487)
> --- gcc/tree-cfg.c ? ? ?(working copy)
> *************** verify_expr (tree *tp, int *walk_subtree
> *** 2871,2876 ****
> --- 2871,2881 ----
> ? ? ? ? ? ?error ("address taken, but ADDRESSABLE bit not set");
> ? ? ? ? ? ?return x;
> ? ? ? ? ?}
> + ? ? ? if (DECL_GIMPLE_REG_P (x))
> + ? ? ? ? {
> + ? ? ? ? ? error ("DECL_GIMPLE_REG_P set on a variable with address taken");
> + ? ? ? ? ? return x;
> + ? ? ? ? }
>
> ? ? ? ?break;
> ? ? ? ?}
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]