summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-strlen.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-strlen.c')
-rw-r--r--gcc/tree-ssa-strlen.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index c0f9ccd5642..5c21b92ec68 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -1952,6 +1952,28 @@ strlen_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
int count_vdef = 100;
do_invalidate (dombb, phi, visited, &count_vdef);
BITMAP_FREE (visited);
+ if (count_vdef == 0)
+ {
+ /* If there were too many vdefs in between immediate
+ dominator and current bb, invalidate everything.
+ If stridx_to_strinfo has been unshared, we need
+ to free it, otherwise just set it to NULL. */
+ if (!strinfo_shared ())
+ {
+ unsigned int i;
+ strinfo si;
+
+ for (i = 1;
+ vec_safe_iterate (stridx_to_strinfo, i, &si);
+ ++i)
+ {
+ free_strinfo (si);
+ (*stridx_to_strinfo)[i] = NULL;
+ }
+ }
+ else
+ stridx_to_strinfo = NULL;
+ }
break;
}
}
@@ -2065,22 +2087,40 @@ gate_strlen (void)
return flag_optimize_strlen != 0;
}
-struct gimple_opt_pass pass_strlen =
+namespace {
+
+const pass_data pass_data_strlen =
{
- {
- GIMPLE_PASS,
- "strlen", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_strlen, /* gate */
- tree_ssa_strlen, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_STRLEN, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "strlen", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_STRLEN, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_strlen : public gimple_opt_pass
+{
+public:
+ pass_strlen(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_strlen, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_strlen (); }
+ unsigned int execute () { return tree_ssa_strlen (); }
+
+}; // class pass_strlen
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_strlen (gcc::context *ctxt)
+{
+ return new pass_strlen (ctxt);
+}