From: Jan Hubicka <hubicka@ucw.cz>
To: Jan Hubicka <hubicka@ucw.cz>
Cc: Richard Guenther <rguenther@suse.de>, gcc-patches@gcc.gnu.org
Subject: Re: PR middle-end/44813 (ICE in Mozilla build in ptr_deref_may_alias_decl_p)
Date: Mon, 05 Jul 2010 16:18:00 -0000 [thread overview]
Message-ID: <20100705161839.GA14621@atrey.karlin.mff.cuni.cz> (raw)
In-Reply-To: <20100705102818.GD29130@kam.mff.cuni.cz>
Hi,
here is updated patch, with Richard's reduced testcase that solves some furhter
problems.
In particular adding the tester down that ipa-split produce new SSA name
for return value and sets as definining statement the call (that is wrong
for DECL_BY_REFERENCE)> I also cleaned up the code a bit there.
Also ipa-ssa-ccp considers RESULT_DECL as undefined that leads to misoptimization
after fixing the first problem on libstdc++ vector testcase.
Bootstrapped/regtested x86_64-linux, OK?
* tree-ssa-uninit.c (ssa_undefined_value_p): Result decl is defined
for functions passed by reference.
* tree.c (needs_to_live_in_memory): RESULT_DECL don't need to live
in memory when passed by reference.
* tree-ssa-ccp.c (get_default_value): Only VAR_DECL is undefined at
beggining.
* ipa-split.c (split_function): Cleanup way return value is passed;
handle SSA DECL_BY_REFERENCE retvals.
* tree-ssa.c (verify_def): Verify that RESULT_DECL is read only when
DECL_BY_REFERENCE is set.
* tree-inline.c (remap_gimple_stmt): Handle SSA DECL_BY_REFERENCE
returns.
* tree-ssa-structalias.c (get_constraint_for_ssa_var, get_fi_for_callee,
find_what_p_points_to): Handle RESULT_DECL.
* testsuite/g++.dg/torture/pr44813.C: New testcase.
Index: tree-ssa-uninit.c
===================================================================
*** tree-ssa-uninit.c (revision 161826)
--- tree-ssa-uninit.c (working copy)
*************** ssa_undefined_value_p (tree t)
*** 92,97 ****
--- 92,103 ----
if (TREE_CODE (var) == PARM_DECL)
return false;
+ /* When returning by reference the return address is actually a hidden
+ parameter. */
+ if (TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL
+ && DECL_BY_REFERENCE (SSA_NAME_VAR (t)))
+ return false;
+
/* Hard register variables get their initial value from the ether. */
if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
return false;
Index: tree.c
===================================================================
*** tree.c (revision 161826)
--- tree.c (working copy)
*************** needs_to_live_in_memory (const_tree t)
*** 9750,9755 ****
--- 9750,9756 ----
return (TREE_ADDRESSABLE (t)
|| is_global_var (t)
|| (TREE_CODE (t) == RESULT_DECL
+ && !DECL_BY_REFERENCE (t)
&& aggregate_value_p (t, current_function_decl)));
}
Index: testsuite/g++.dg/torture/pr44813.C
===================================================================
*** testsuite/g++.dg/torture/pr44813.C (revision 0)
--- testsuite/g++.dg/torture/pr44813.C (revision 0)
***************
*** 0 ****
--- 1,60 ----
+ typedef unsigned int PRUint32;
+ typedef int PRInt32;
+ typedef unsigned long PRUint64;
+ typedef int PRIntn;
+ typedef PRIntn PRBool;
+ struct nsRect {
+ nsRect(const nsRect& aRect) { }
+ };
+ enum nsCompatibility { eCompatibility_NavQuirks = 3 };
+ class gfxContext;
+ typedef PRUint64 nsFrameState;
+ class nsPresContext {
+ public:
+ nsCompatibility CompatibilityMode() const { }
+ };
+ class nsStyleContext {
+ public:
+ PRBool HasTextDecorations() const;
+ };
+ class nsIFrame {
+ public:
+ nsPresContext* PresContext() const;
+ nsStyleContext* GetStyleContext() const;
+ nsFrameState GetStateBits() const;
+ nsRect GetOverflowRect() const;
+ };
+ class nsFrame : public nsIFrame { };
+ class nsLineList_iterator { };
+ class nsLineList {
+ public:
+ typedef nsLineList_iterator iterator;
+ };
+ class gfxSkipCharsIterator { };
+ class gfxTextRun {
+ public:
+ class PropertyProvider { };
+ };
+ class nsTextFrame : public nsFrame
+ {
+ virtual nsRect ComputeTightBounds(gfxContext* aContext) const;
+ gfxSkipCharsIterator EnsureTextRun(gfxContext* aReferenceContext = 0L,
+ nsIFrame* aLineContainer = 0L,
+ const nsLineList::iterator* aLine = 0L,
+ PRUint32* aFlowEndInTextRun = 0L);
+ };
+ class PropertyProvider : public gfxTextRun::PropertyProvider
+ {
+ public:
+ PropertyProvider(nsTextFrame* aFrame, const gfxSkipCharsIterator& aStart);
+ PRInt32 mLength[64];
+ };
+ nsRect nsTextFrame::ComputeTightBounds(gfxContext* aContext) const
+ {
+ if ((GetStyleContext()->HasTextDecorations()
+ && eCompatibility_NavQuirks == PresContext()->CompatibilityMode())
+ || (GetStateBits() & (nsFrameState(1) << (23))))
+ return GetOverflowRect();
+ gfxSkipCharsIterator iter = const_cast<nsTextFrame*>(this)->EnsureTextRun();
+ PropertyProvider provider(const_cast<nsTextFrame*>(this), iter);
+ }
Index: tree-ssa-ccp.c
===================================================================
*** tree-ssa-ccp.c (revision 161826)
--- tree-ssa-ccp.c (working copy)
*************** get_default_value (tree var)
*** 300,306 ****
before being initialized. If VAR is a local variable, we
can assume initially that it is UNDEFINED, otherwise we must
consider it VARYING. */
! if (is_gimple_reg (sym) && TREE_CODE (sym) != PARM_DECL)
val.lattice_val = UNDEFINED;
else
val.lattice_val = VARYING;
--- 300,307 ----
before being initialized. If VAR is a local variable, we
can assume initially that it is UNDEFINED, otherwise we must
consider it VARYING. */
! if (is_gimple_reg (sym)
! && TREE_CODE (sym) == VAR_DECL)
val.lattice_val = UNDEFINED;
else
val.lattice_val = VARYING;
Index: ipa-split.c
===================================================================
*** ipa-split.c (revision 161826)
--- ipa-split.c (working copy)
*************** split_function (struct split_point *spli
*** 967,997 ****
return_bb == EXIT_BLOCK_PTR ? 0 : EDGE_FALLTHRU);
e->count = call_bb->count;
e->probability = REG_BR_PROB_BASE;
if (return_bb != EXIT_BLOCK_PTR)
{
real_retval = retval = find_retval (return_bb);
if (real_retval
&& !is_gimple_min_invariant (retval)
&& (TREE_CODE (retval) != SSA_NAME
! || !SSA_NAME_IS_DEFAULT_DEF (retval)))
{
gimple_stmt_iterator psi;
! /* See if there is PHI defining return value. */
! for (psi = gsi_start_phis (return_bb);
! !gsi_end_p (psi); gsi_next (&psi))
! if (is_gimple_reg (gimple_phi_result (gsi_stmt (psi))))
! break;
!
! /* When we have PHI, update PHI. When there is no PHI,
! update the return statement itself. */
! if (TREE_CODE (retval) == SSA_NAME)
{
retval = make_ssa_name (SSA_NAME_VAR (retval), call);
if (TREE_CODE (retval) == SSA_NAME
&& !gsi_end_p (psi))
add_phi_arg (gsi_stmt (psi), retval, e, UNKNOWN_LOCATION);
! else if (TREE_CODE (retval) == SSA_NAME)
{
gimple_stmt_iterator bsi;
for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi);
--- 967,1013 ----
return_bb == EXIT_BLOCK_PTR ? 0 : EDGE_FALLTHRU);
e->count = call_bb->count;
e->probability = REG_BR_PROB_BASE;
+
+ /* If there is return basic block, see what value we need to store
+ return value into and put call just before it. */
if (return_bb != EXIT_BLOCK_PTR)
{
real_retval = retval = find_retval (return_bb);
+
+ /* See if return value is computed by split part;
+ function might just return its argument, invariant or undefined
+ value. In this case we don't need to do any updating. */
if (real_retval
&& !is_gimple_min_invariant (retval)
&& (TREE_CODE (retval) != SSA_NAME
! || (!SSA_NAME_IS_DEFAULT_DEF (retval)
! || DECL_BY_REFERENCE
! (DECL_RESULT (current_function_decl)))))
{
gimple_stmt_iterator psi;
! /* See if we need new SSA_NAME for the result.
! When DECL_BY_REFERENCE is true, retval is actually pointer to
! return value and it is constant in whole function. */
! if (TREE_CODE (retval) == SSA_NAME
! && !DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
{
retval = make_ssa_name (SSA_NAME_VAR (retval), call);
+
+ /* See if there is PHI defining return value. */
+ for (psi = gsi_start_phis (return_bb);
+ !gsi_end_p (psi); gsi_next (&psi))
+ if (is_gimple_reg (gimple_phi_result (gsi_stmt (psi))))
+ break;
+
+ /* When there is PHI, just update its value. */
if (TREE_CODE (retval) == SSA_NAME
&& !gsi_end_p (psi))
add_phi_arg (gsi_stmt (psi), retval, e, UNKNOWN_LOCATION);
! /* Otherwise update the return BB itself.
! find_return_bb allows at most one assignment to return value,
! so update first statement. */
! else
{
gimple_stmt_iterator bsi;
for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi);
*************** split_function (struct split_point *spli
*** 1016,1021 ****
--- 1032,1040 ----
}
gsi_insert_after (&gsi, call, GSI_NEW_STMT);
}
+ /* We don't use return block (there is either no return in function or
+ multiple of them). So create new basic block with return statement.
+ */
else
{
gimple ret;
*************** split_function (struct split_point *spli
*** 1030,1036 ****
&& !DECL_BY_REFERENCE (retval))
retval = create_tmp_reg (TREE_TYPE (retval), NULL);
if (is_gimple_reg (retval))
! retval = make_ssa_name (retval, call);
if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
gimple_call_set_lhs (call, build_simple_mem_ref (retval));
else
--- 1049,1076 ----
&& !DECL_BY_REFERENCE (retval))
retval = create_tmp_reg (TREE_TYPE (retval), NULL);
if (is_gimple_reg (retval))
! {
! /* When returning by reference, there is only one SSA name
! assigned to RESULT_DECL (that is pointer to return value).
! Look it up or create new one if it is missing. */
! if (DECL_BY_REFERENCE (retval))
! {
! tree retval_name;
! if ((retval_name = gimple_default_def (cfun, retval))
! != NULL)
! retval = retval_name;
! else
! {
! retval_name = make_ssa_name (retval,
! gimple_build_nop ());
! set_default_def (retval, retval_name);
! retval = retval_name;
! }
! }
! /* Otherwise produce new SSA name for return value. */
! else
! retval = make_ssa_name (retval, call);
! }
if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
gimple_call_set_lhs (call, build_simple_mem_ref (retval));
else
Index: tree-ssa.c
===================================================================
*** tree-ssa.c (revision 161826)
--- tree-ssa.c (working copy)
*************** verify_def (basic_block bb, basic_block
*** 638,643 ****
--- 638,650 ----
if (verify_ssa_name (ssa_name, is_virtual))
goto err;
+ if (TREE_CODE (SSA_NAME_VAR (ssa_name)) == RESULT_DECL
+ && DECL_BY_REFERENCE (SSA_NAME_VAR (ssa_name)))
+ {
+ error ("RESULT_DECL should be read only when DECL_BY_REFERENCE is set.");
+ goto err;
+ }
+
if (definition_block[SSA_NAME_VERSION (ssa_name)])
{
error ("SSA_NAME created in two different blocks %i and %i",
Index: tree-inline.c
===================================================================
*** tree-inline.c (revision 161826)
--- tree-inline.c (working copy)
*************** remap_gimple_stmt (gimple stmt, copy_bod
*** 1236,1242 ****
If RETVAL is just the result decl, the result decl has
already been set (e.g. a recent "foo (&result_decl, ...)");
just toss the entire GIMPLE_RETURN. */
! if (retval && TREE_CODE (retval) != RESULT_DECL)
{
copy = gimple_build_assign (id->retvar, retval);
/* id->retvar is already substituted. Skip it on later remapping. */
--- 1237,1246 ----
If RETVAL is just the result decl, the result decl has
already been set (e.g. a recent "foo (&result_decl, ...)");
just toss the entire GIMPLE_RETURN. */
! if (retval
! && (TREE_CODE (retval) != RESULT_DECL
! && (TREE_CODE (retval) != SSA_NAME
! || TREE_CODE (SSA_NAME_VAR (retval)) != RESULT_DECL)))
{
copy = gimple_build_assign (id->retvar, retval);
/* id->retvar is already substituted. Skip it on later remapping. */
Index: tree-ssa-structalias.c
===================================================================
*** tree-ssa-structalias.c (revision 161826)
--- tree-ssa-structalias.c (working copy)
*************** get_constraint_for_ssa_var (tree t, VEC(
*** 2836,2842 ****
/* For parameters, get at the points-to set for the actual parm
decl. */
if (TREE_CODE (t) == SSA_NAME
! && TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
&& SSA_NAME_IS_DEFAULT_DEF (t))
{
get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
--- 2836,2844 ----
/* For parameters, get at the points-to set for the actual parm
decl. */
if (TREE_CODE (t) == SSA_NAME
! && (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
! || (TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL
! && DECL_BY_REFERENCE (SSA_NAME_VAR (t))))
&& SSA_NAME_IS_DEFAULT_DEF (t))
{
get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
*************** get_fi_for_callee (gimple call)
*** 3982,3988 ****
if (TREE_CODE (decl) == SSA_NAME)
{
if (TREE_CODE (decl) == SSA_NAME
! && TREE_CODE (SSA_NAME_VAR (decl)) == PARM_DECL
&& SSA_NAME_IS_DEFAULT_DEF (decl))
decl = SSA_NAME_VAR (decl);
return get_vi_for_tree (decl);
--- 3984,3992 ----
if (TREE_CODE (decl) == SSA_NAME)
{
if (TREE_CODE (decl) == SSA_NAME
! && (TREE_CODE (SSA_NAME_VAR (decl)) == PARM_DECL
! || (TREE_CODE (SSA_NAME_VAR (decl)) == RESULT_DECL
! && DECL_BY_REFERENCE (SSA_NAME_VAR (decl))))
&& SSA_NAME_IS_DEFAULT_DEF (decl))
decl = SSA_NAME_VAR (decl);
return get_vi_for_tree (decl);
*************** find_what_p_points_to (tree p)
*** 5751,5757 ****
/* For parameters, get at the points-to set for the actual parm
decl. */
if (TREE_CODE (p) == SSA_NAME
! && TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
&& SSA_NAME_IS_DEFAULT_DEF (p))
lookup_p = SSA_NAME_VAR (p);
--- 5755,5763 ----
/* For parameters, get at the points-to set for the actual parm
decl. */
if (TREE_CODE (p) == SSA_NAME
! && (TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
! || (TREE_CODE (SSA_NAME_VAR (p)) == RESULT_DECL
! && DECL_BY_REFERENCE (SSA_NAME_VAR (p))))
&& SSA_NAME_IS_DEFAULT_DEF (p))
lookup_p = SSA_NAME_VAR (p);
next prev parent reply other threads:[~2010-07-05 16:18 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-04 22:42 Jan Hubicka
2010-07-05 9:43 ` Richard Guenther
2010-07-05 10:28 ` Jan Hubicka
2010-07-05 16:18 ` Jan Hubicka [this message]
2010-07-06 9:20 ` Richard Guenther
2011-01-16 20:09 ` H.J. Lu
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=20100705161839.GA14621@atrey.karlin.mff.cuni.cz \
--to=hubicka@ucw.cz \
--cc=gcc-patches@gcc.gnu.org \
--cc=rguenther@suse.de \
/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).