re PR tree-optimization/80032 (C++ excessive stack usage (no stack reuse))
2017-03-21 Richard Biener <rguenther@suse.de> PR tree-optimization/80032 * gimplify.c (gimple_push_cleanup): Add force_uncond parameter, if set force the cleanup to happen unconditionally. (gimplify_target_expr): Push inserted clobbers with force_uncond to avoid them being removed by control-dependent DCE. * g++.dg/opt/pr80032.C: New testcase. From-SVN: r246314
This commit is contained in:
parent
da2ce5f993
commit
e650ea2a5e
|
@ -1,3 +1,11 @@
|
|||
2017-03-21 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/80032
|
||||
* gimplify.c (gimple_push_cleanup): Add force_uncond parameter,
|
||||
if set force the cleanup to happen unconditionally.
|
||||
(gimplify_target_expr): Push inserted clobbers with force_uncond
|
||||
to avoid them being removed by control-dependent DCE.
|
||||
|
||||
2017-03-21 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/80122
|
||||
|
|
|
@ -6288,10 +6288,13 @@ gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
|
|||
|
||||
/* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
|
||||
is the cleanup action required. EH_ONLY is true if the cleanup should
|
||||
only be executed if an exception is thrown, not on normal exit. */
|
||||
only be executed if an exception is thrown, not on normal exit.
|
||||
If FORCE_UNCOND is true perform the cleanup unconditionally; this is
|
||||
only valid for clobbers. */
|
||||
|
||||
static void
|
||||
gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p)
|
||||
gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
|
||||
bool force_uncond = false)
|
||||
{
|
||||
gimple *wce;
|
||||
gimple_seq cleanup_stmts = NULL;
|
||||
|
@ -6301,7 +6304,7 @@ gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p)
|
|||
if (seen_error ())
|
||||
return;
|
||||
|
||||
if (gimple_conditional_context ())
|
||||
if (gimple_conditional_context () && ! force_uncond)
|
||||
{
|
||||
/* If we're in a conditional context, this is more complex. We only
|
||||
want to run the cleanup if we actually ran the initialization that
|
||||
|
@ -6426,11 +6429,7 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
|
|||
NULL);
|
||||
TREE_THIS_VOLATILE (clobber) = true;
|
||||
clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
|
||||
if (cleanup)
|
||||
cleanup = build2 (COMPOUND_EXPR, void_type_node, cleanup,
|
||||
clobber);
|
||||
else
|
||||
cleanup = clobber;
|
||||
gimple_push_cleanup (temp, clobber, false, pre_p, true);
|
||||
}
|
||||
if (asan_poisoned_variables && dbg_cnt (asan_use_after_scope))
|
||||
{
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2017-03-21 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/80032
|
||||
* g++.dg/opt/pr80032.C: New testcase.
|
||||
|
||||
2017-03-21 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/80122
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
// PR tree-optimization/80032
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "-O2" }
|
||||
// If DCE removes too many CLOBBERs then stack usage goes through the
|
||||
// roof as stack slots can no longer be shared.
|
||||
// { dg-additional-options "-Wstack-usage=200" { target x86_64-*-* i?86-*-* } }
|
||||
|
||||
typedef unsigned a;
|
||||
namespace test {
|
||||
enum b { c };
|
||||
class ADataContainer;
|
||||
class BitMask;
|
||||
namespace api {
|
||||
enum DataStore { candidate };
|
||||
}
|
||||
using d = api::DataStore;
|
||||
namespace db {
|
||||
class e;
|
||||
class f;
|
||||
class g;
|
||||
class ManagedObjectConst {
|
||||
public:
|
||||
ManagedObjectConst(const ManagedObjectConst &);
|
||||
bool isFieldDefault(a, d) const;
|
||||
ADataContainer &getFieldDefault(a, d) const;
|
||||
g *h;
|
||||
e *i;
|
||||
f *j;
|
||||
};
|
||||
struct FieldInfo {
|
||||
FieldInfo(ManagedObjectConst, a, d);
|
||||
ManagedObjectConst k;
|
||||
};
|
||||
b compare(const FieldInfo &, const ADataContainer &);
|
||||
class ManagedObject : public ManagedObjectConst {};
|
||||
}
|
||||
using namespace db;
|
||||
void FN(ManagedObject &k, const BitMask &) {
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
if (!k.isFieldDefault(8, d::candidate) &&
|
||||
!compare(FieldInfo(k, 11, d::candidate),
|
||||
k.getFieldDefault(11, d::candidate)) == c)
|
||||
return;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue