Commit d0bf921f by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/86214 (Strongly increased stack usage)

	PR tree-optimization/86214
	* tree-inline.h (struct copy_body_data): Add
	add_clobbers_to_eh_landing_pads member.
	* tree-inline.c (add_clobbers_to_eh_landing_pad): New function.
	(copy_edges_for_bb): Call it if EH edge destination is <
	id->add_clobbers_to_eh_landing_pads.  Fix a comment typo.
	(expand_call_inline): Set id->add_clobbers_to_eh_landing_pads
	if flag_stack_reuse != SR_NONE and clear it afterwards.

	* g++.dg/opt/pr86214-1.C: New test.
	* g++.dg/opt/pr86214-2.C: New test.

From-SVN: r268067
parent 6616a318
2019-01-18 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/86214
* tree-inline.h (struct copy_body_data): Add
add_clobbers_to_eh_landing_pads member.
* tree-inline.c (add_clobbers_to_eh_landing_pad): New function.
(copy_edges_for_bb): Call it if EH edge destination is <
id->add_clobbers_to_eh_landing_pads. Fix a comment typo.
(expand_call_inline): Set id->add_clobbers_to_eh_landing_pads
if flag_stack_reuse != SR_NONE and clear it afterwards.
2019-01-18 Christophe Lyon <christophe.lyon@linaro.org> 2019-01-18 Christophe Lyon <christophe.lyon@linaro.org>
PR target/85596 PR target/85596
......
2019-01-18 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/86214
* g++.dg/opt/pr86214-1.C: New test.
* g++.dg/opt/pr86214-2.C: New test.
2019-01-18 Christophe Lyon <christophe.lyon@linaro.org> 2019-01-18 Christophe Lyon <christophe.lyon@linaro.org>
* gcc.target/arm/pr77904.c: Add dg-warning for sp clobber. * gcc.target/arm/pr77904.c: Add dg-warning for sp clobber.
......
// PR tree-optimization/86214
// { dg-do compile }
// { dg-options "-O2 -Wstack-usage=15000" }
typedef __SIZE_TYPE__ size_t;
struct A { A (); ~A (); int a; void qux (const char *); };
int bar (char *);
static inline A
foo ()
{
char b[8192];
int x = bar (b);
A s;
if (x > 0 && (size_t) x < sizeof b)
s.qux (b);
return s;
}
void
baz () // { dg-bogus "stack usage is" }
{
A a;
char c[1024];
bar (c);
foo (); foo (); foo (); foo (); foo ();
foo (); foo (); foo (); foo (); foo ();
foo (); foo (); foo (); foo (); foo ();
foo (); foo (); foo (); foo (); foo ();
}
// PR tree-optimization/86214
// { dg-do compile }
// { dg-options "-O2 -Wstack-usage=15000" }
typedef __SIZE_TYPE__ size_t;
struct A { A (); ~A (); int a; void qux (const char *); };
int bar (char *);
static inline __attribute__((always_inline)) A
foo ()
{
char b[8192];
int x = bar (b);
A s;
if (x > 0 && (size_t) x < sizeof b)
s.qux (b);
return s;
}
void
baz () // { dg-bogus "stack usage is" }
{
A a;
foo (); foo (); foo (); foo (); foo ();
foo (); foo (); foo (); foo (); foo ();
foo (); foo (); foo (); foo (); foo ();
foo (); foo (); foo (); foo (); foo ();
}
...@@ -2190,6 +2190,40 @@ update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb, ...@@ -2190,6 +2190,40 @@ update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb,
} }
} }
/* Insert clobbers for automatic variables of inlined ID->src_fn
function at the start of basic block BB. */
static void
add_clobbers_to_eh_landing_pad (basic_block bb, copy_body_data *id)
{
tree var;
unsigned int i;
FOR_EACH_VEC_SAFE_ELT (id->src_cfun->local_decls, i, var)
if (VAR_P (var)
&& !DECL_HARD_REGISTER (var)
&& !TREE_THIS_VOLATILE (var)
&& !DECL_HAS_VALUE_EXPR_P (var)
&& !is_gimple_reg (var)
&& auto_var_in_fn_p (var, id->src_fn))
{
tree *t = id->decl_map->get (var);
if (!t)
continue;
tree new_var = *t;
if (VAR_P (new_var)
&& !DECL_HARD_REGISTER (new_var)
&& !TREE_THIS_VOLATILE (new_var)
&& !DECL_HAS_VALUE_EXPR_P (new_var)
&& !is_gimple_reg (new_var)
&& auto_var_in_fn_p (new_var, id->dst_fn))
{
gimple_stmt_iterator gsi = gsi_after_labels (bb);
tree clobber = build_clobber (TREE_TYPE (new_var));
gimple *clobber_stmt = gimple_build_assign (new_var, clobber);
gsi_insert_before (&gsi, clobber_stmt, GSI_NEW_STMT);
}
}
}
/* Copy edges from BB into its copy constructed earlier, scale profile /* Copy edges from BB into its copy constructed earlier, scale profile
accordingly. Edges will be taken care of later. Assume aux accordingly. Edges will be taken care of later. Assume aux
...@@ -2232,7 +2266,7 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den, ...@@ -2232,7 +2266,7 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den,
if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK) if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK)
return false; return false;
/* When doing function splitting, we must decreate count of the return block /* When doing function splitting, we must decrease count of the return block
which was previously reachable by block we did not copy. */ which was previously reachable by block we did not copy. */
if (single_succ_p (bb) && single_succ_edge (bb)->dest->index == EXIT_BLOCK) if (single_succ_p (bb) && single_succ_edge (bb)->dest->index == EXIT_BLOCK)
FOR_EACH_EDGE (old_edge, ei, bb->preds) FOR_EACH_EDGE (old_edge, ei, bb->preds)
...@@ -2317,8 +2351,16 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den, ...@@ -2317,8 +2351,16 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den,
e->probability = old_edge->probability; e->probability = old_edge->probability;
FOR_EACH_EDGE (e, ei, copy_stmt_bb->succs) FOR_EACH_EDGE (e, ei, copy_stmt_bb->succs)
if ((e->flags & EDGE_EH) && !e->probability.initialized_p ()) if (e->flags & EDGE_EH)
e->probability = profile_probability::never (); {
if (!e->probability.initialized_p ())
e->probability = profile_probability::never ();
if (e->dest->index < id->add_clobbers_to_eh_landing_pads)
{
add_clobbers_to_eh_landing_pad (e->dest, id);
id->add_clobbers_to_eh_landing_pads = 0;
}
}
} }
...@@ -4565,6 +4607,8 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) ...@@ -4565,6 +4607,8 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
id->decl_map = new hash_map<tree, tree>; id->decl_map = new hash_map<tree, tree>;
dst = id->debug_map; dst = id->debug_map;
id->debug_map = NULL; id->debug_map = NULL;
if (flag_stack_reuse != SR_NONE)
id->add_clobbers_to_eh_landing_pads = last_basic_block_for_fn (cfun);
/* Record the function we are about to inline. */ /* Record the function we are about to inline. */
id->src_fn = fn; id->src_fn = fn;
...@@ -4872,6 +4916,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) ...@@ -4872,6 +4916,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
} }
id->assign_stmts.release (); id->assign_stmts.release ();
id->add_clobbers_to_eh_landing_pads = 0;
/* Output the inlining info for this abstract function, since it has been /* Output the inlining info for this abstract function, since it has been
inlined. If we don't do this now, we can lose the information about the inlined. If we don't do this now, we can lose the information about the
......
...@@ -155,6 +155,12 @@ struct copy_body_data ...@@ -155,6 +155,12 @@ struct copy_body_data
/* A list of addressable local variables remapped into the caller /* A list of addressable local variables remapped into the caller
when inlining a call within an OpenMP SIMD-on-SIMT loop. */ when inlining a call within an OpenMP SIMD-on-SIMT loop. */
vec<tree> *dst_simt_vars; vec<tree> *dst_simt_vars;
/* If clobbers for local variables from the inline function
that need to live in memory should be added to EH landing pads
outside of the inlined function, this should be the number
of basic blocks in the caller before inlining. Zero otherwise. */
int add_clobbers_to_eh_landing_pads;
}; };
/* Weights of constructions for estimate_num_insns. */ /* Weights of constructions for estimate_num_insns. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment