+2015-11-16 Tom de Vries <tom@codesourcery.com>
+
+ * gdbhooks.py (class PassNames): Handle extra arg NEXT_PASS argument.
+ * gen-pass-instances.awk (handle_line): Same.
+ * pass_manager.h (class pass_manager): Define and undefine
+ NEXT_PASS_WITH_ARG.
+ * passes.c (opt_pass::set_pass_param): New function.
+ (pass_manager::pass_manager): Define and undefine NEXT_PASS_WITH_ARG.
+ * passes.def: Add extra arg to NEXT_PASS (pass_vrp).
+ * tree-pass.h (gimple_opt::set_pass_param): Declare.
+ * tree-vrp.c (vrp_finalize, execute_vrp): Add and handle
+ warn_array_bounds_p parameter.
+ (pass_vrp::pass_vrp): Initialize warn_array_bounds_p.
+ (pass_vrp::set_pass_param): New function.
+ (pass_vrp::execute): Add warn_array_bounds_p arg to execute_vrp call.
+ (pass_vrp::warn_array_bounds_p): New private member.
+
2015-11-16 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sparc.c (sparc_emit_probe_stack_range): Adjust.
self.names = []
with open(os.path.join(srcdir, 'passes.def')) as f:
for line in f:
- m = re.match('\s*NEXT_PASS \((.+)\);', line)
+ m = re.match('\s*NEXT_PASS \(([^,]+).*\);', line)
if m:
self.names.append(m.group(1))
len_of_args = len_of_call - (len_of_start + len_of_close);
args_start_at = call_starts_at + len_of_start;
args_str = substr(line, args_start_at, len_of_args);
+ split(args_str, args, ",");
- # Set pass_name argument
- pass_name = args_str;
+ # Set pass_name argument, an optional with_arg argument
+ pass_name = args[1];
+ with_arg = args[2];
- # Find call expression prefix (until and including called function)
- len_of_prefix = args_start_at - 1 - len_of_open;
+ # Find call expression prefix
+ len_of_prefix = call_starts_at - 1;
prefix = substr(line, 1, len_of_prefix);
# Find call expression postfix
pass_num = pass_counts[pass_name];
# Print call expression with extra pass_num argument
- printf "%s(%s, %s)%s\n", prefix, pass_name, pass_num, postfix;
+ printf "%s", prefix;
+ if (with_arg)
+ {
+ printf "NEXT_PASS_WITH_ARG";
+ }
+ else
+ {
+ printf "NEXT_PASS";
+ }
+ printf " (";
+ printf "%s", pass_name;
+ printf ", %s", pass_num;
+ if (with_arg)
+ {
+ printf ", %s", with_arg;
+ }
+ printf ")%s\n", postfix;
}
{ handle_line() }
#define PUSH_INSERT_PASSES_WITHIN(PASS)
#define POP_INSERT_PASSES()
#define NEXT_PASS(PASS, NUM) opt_pass *PASS ## _ ## NUM
+#define NEXT_PASS_WITH_ARG(PASS, NUM, ARG) NEXT_PASS (PASS, NUM)
#define TERMINATE_PASS_LIST()
#include "pass-instances.def"
#undef PUSH_INSERT_PASSES_WITHIN
#undef POP_INSERT_PASSES
#undef NEXT_PASS
+#undef NEXT_PASS_WITH_ARG
#undef TERMINATE_PASS_LIST
}; // class pass_manager
internal_error ("pass %s does not support cloning", name);
}
+void
+opt_pass::set_pass_param (unsigned int, bool)
+{
+ internal_error ("pass %s needs a set_pass_param implementation to handle the"
+ " extra argument in NEXT_PASS", name);
+}
+
bool
opt_pass::gate (function *)
{
p = next_pass_1 (p, PASS ## _ ## NUM, PASS ## _1); \
} while (0)
+#define NEXT_PASS_WITH_ARG(PASS, NUM, ARG) \
+ do { \
+ NEXT_PASS (PASS, NUM); \
+ PASS ## _ ## NUM->set_pass_param (0, ARG); \
+ } while (0)
+
#define TERMINATE_PASS_LIST() \
*p = NULL;
#undef PUSH_INSERT_PASSES_WITHIN
#undef POP_INSERT_PASSES
#undef NEXT_PASS
+#undef NEXT_PASS_WITH_ARG
#undef TERMINATE_PASS_LIST
/* Register the passes with the tree dump code. */
NEXT_PASS (pass_return_slot);
NEXT_PASS (pass_fre);
NEXT_PASS (pass_merge_phi);
- NEXT_PASS (pass_vrp);
+ NEXT_PASS (pass_vrp, true /* warn_array_bounds_p */);
NEXT_PASS (pass_chkp_opt);
NEXT_PASS (pass_dce);
NEXT_PASS (pass_stdarg);
NEXT_PASS (pass_tracer);
NEXT_PASS (pass_dominator);
NEXT_PASS (pass_strlen);
- NEXT_PASS (pass_vrp);
+ NEXT_PASS (pass_vrp, false /* warn_array_bounds_p */);
/* The only const/copy propagation opportunities left after
DOM and VRP should be due to degenerate PHI nodes. So rather than
run the full propagators, run a specialized pass which
The default implementation prints an error message and aborts. */
virtual opt_pass *clone ();
+ virtual void set_pass_param (unsigned int, bool);
/* This pass and all sub-passes are executed only if the function returns
true. The default implementation returns true. */
/* Traverse all the blocks folding conditionals with known ranges. */
static void
-vrp_finalize (void)
+vrp_finalize (bool warn_array_bounds_p)
{
size_t i;
substitute_and_fold (op_with_constant_singleton_value_range,
vrp_fold_stmt, false);
- if (warn_array_bounds && first_pass_instance)
+ if (warn_array_bounds && warn_array_bounds_p)
check_all_array_refs ();
/* We must identify jump threading opportunities before we release
probabilities to aid branch prediction. */
static unsigned int
-execute_vrp (void)
+execute_vrp (bool warn_array_bounds_p)
{
int i;
edge e;
vrp_initialize ();
ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
- vrp_finalize ();
+ vrp_finalize (warn_array_bounds_p);
free_numbers_of_iterations_estimates (cfun);
{
public:
pass_vrp (gcc::context *ctxt)
- : gimple_opt_pass (pass_data_vrp, ctxt)
+ : gimple_opt_pass (pass_data_vrp, ctxt), warn_array_bounds_p (false)
{}
/* opt_pass methods: */
opt_pass * clone () { return new pass_vrp (m_ctxt); }
+ void set_pass_param (unsigned int n, bool param)
+ {
+ gcc_assert (n == 0);
+ warn_array_bounds_p = param;
+ }
virtual bool gate (function *) { return flag_tree_vrp != 0; }
- virtual unsigned int execute (function *) { return execute_vrp (); }
+ virtual unsigned int execute (function *)
+ { return execute_vrp (warn_array_bounds_p); }
+ private:
+ bool warn_array_bounds_p;
}; // class pass_vrp
} // anon namespace