From 478167be6297adb9774abfea589b6b1d0a7f227e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 8 Oct 2016 14:04:37 +0200 Subject: [PATCH] gen-pass-instances.awk: Rewritten. * gen-pass-instances.awk: Rewritten. * Makefile.in (pass-instances.def): Depend on $(PASSES_EXTRA), pass $(PASSES_EXTRA) after passes.def to the script. * config/i386/t-i386 (PASSES_EXTRA): Add i386-passes.def. * config/i386/i386-passes.def: New file. * config/i386/i386-protos.h (make_pass_insert_vzeroupper, make_pass_stv): Declare. * config/i386/i386.c (pass_stv::pass_stv): Initialize timode_p to false. (pass_stv::gate): Depending on timode_p member require TARGET_64BIT or !TARGET_64BIT. (pass_stv::clone, pass_stv::set_pass_param): New methods. (pass_stv::timode_p): New non-static data member. (ix86_option_override): Don't register passes here. From-SVN: r240887 --- gcc/ChangeLog | 15 +++ gcc/Makefile.in | 5 +- gcc/config/i386/i386-protos.h | 6 + gcc/config/i386/i386.c | 41 +++--- gcc/config/i386/t-i386 | 1 + gcc/gen-pass-instances.awk | 232 ++++++++++++++++++++++++++-------- 6 files changed, 219 insertions(+), 81 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fa748f35aa5..1685c7f95aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,20 @@ 2016-10-08 Jakub Jelinek + * gen-pass-instances.awk: Rewritten. + * Makefile.in (pass-instances.def): Depend on $(PASSES_EXTRA), pass + $(PASSES_EXTRA) after passes.def to the script. + * config/i386/t-i386 (PASSES_EXTRA): Add i386-passes.def. + * config/i386/i386-passes.def: New file. + * config/i386/i386-protos.h (make_pass_insert_vzeroupper, + make_pass_stv): Declare. + * config/i386/i386.c (pass_stv::pass_stv): Initialize timode_p to + false. + (pass_stv::gate): Depending on timode_p member require TARGET_64BIT + or !TARGET_64BIT. + (pass_stv::clone, pass_stv::set_pass_param): New methods. + (pass_stv::timode_p): New non-static data member. + (ix86_option_override): Don't register passes here. + * doc/invoke.texi: Document accepting Else, fallthrough. * doc/invoke.texi (-Wimplicit-fallthrough): Document FALLTHRU comment diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 15c48bcd7e5..705b574bb8e 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2158,9 +2158,10 @@ s-bversion: BASE-VER CFLAGS-toplev.o += -DTARGET_NAME=\"$(target_noncanonical)\" -pass-instances.def: $(srcdir)/passes.def $(srcdir)/gen-pass-instances.awk +pass-instances.def: $(srcdir)/passes.def $(PASSES_EXTRA) \ + $(srcdir)/gen-pass-instances.awk $(AWK) -f $(srcdir)/gen-pass-instances.awk \ - $(srcdir)/passes.def > pass-instances.def + $(srcdir)/passes.def $(PASSES_EXTRA) > pass-instances.def $(out_object_file): $(out_file) $(COMPILE) $< diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 81301612ee0..8eeb0728e96 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -338,3 +338,9 @@ struct ix86_first_cycle_multipass_data_ const addr_space_t ADDR_SPACE_SEG_FS = 1; const addr_space_t ADDR_SPACE_SEG_GS = 2; + +namespace gcc { class context; } +class rtl_opt_pass; + +extern rtl_opt_pass *make_pass_insert_vzeroupper (gcc::context *); +extern rtl_opt_pass *make_pass_stv (gcc::context *); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 027e84d7556..f6946112c6b 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4105,13 +4105,15 @@ class pass_stv : public rtl_opt_pass { public: pass_stv (gcc::context *ctxt) - : rtl_opt_pass (pass_data_stv, ctxt) + : rtl_opt_pass (pass_data_stv, ctxt), + timode_p (false) {} /* opt_pass methods: */ virtual bool gate (function *) { - return TARGET_STV && TARGET_SSE2 && optimize > 1; + return (timode_p == !!TARGET_64BIT + && TARGET_STV && TARGET_SSE2 && optimize > 1); } virtual unsigned int execute (function *) @@ -4119,6 +4121,19 @@ public: return convert_scalars_to_vector (); } + opt_pass *clone () + { + return new pass_stv (m_ctxt); + } + + void set_pass_param (unsigned int n, bool param) + { + gcc_assert (n == 0); + timode_p = param; + } + +private: + bool timode_p; }; // class pass_stv } // anon namespace @@ -6150,29 +6165,7 @@ ix86_option_override_internal (bool main_args_p, static void ix86_option_override (void) { - opt_pass *pass_insert_vzeroupper = make_pass_insert_vzeroupper (g); - struct register_pass_info insert_vzeroupper_info - = { pass_insert_vzeroupper, "reload", - 1, PASS_POS_INSERT_AFTER - }; - opt_pass *pass_stv = make_pass_stv (g); - struct register_pass_info stv_info_dimode - = { pass_stv, "combine", - 1, PASS_POS_INSERT_AFTER - }; - /* Run the 64-bit STV pass before the CSE pass so that CONST0_RTX and - CONSTM1_RTX generated by the STV pass can be CSEed. */ - struct register_pass_info stv_info_timode - = { pass_stv, "cse2", - 1, PASS_POS_INSERT_BEFORE - }; - ix86_option_override_internal (true, &global_options, &global_options_set); - - - /* This needs to be done at start up. It's convenient to do it here. */ - register_pass (&insert_vzeroupper_info); - register_pass (TARGET_64BIT ? &stv_info_timode : &stv_info_dimode); } /* Implement the TARGET_OFFLOAD_OPTIONS hook. */ diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386 index 9e27a0f890e..c435c1f053d 100644 --- a/gcc/config/i386/t-i386 +++ b/gcc/config/i386/t-i386 @@ -18,6 +18,7 @@ OPTIONS_H_EXTRA += $(srcdir)/config/i386/stringop.def TM_H += $(srcdir)/config/i386/x86-tune.def +PASSES_EXTRA += $(srcdir)/config/i386/i386-passes.def i386-c.o: $(srcdir)/config/i386/i386-c.c $(COMPILE) $< diff --git a/gcc/gen-pass-instances.awk b/gcc/gen-pass-instances.awk index bc82ee94873..6f7794eb402 100644 --- a/gcc/gen-pass-instances.awk +++ b/gcc/gen-pass-instances.awk @@ -17,6 +17,8 @@ # This Awk script takes passes.def and writes pass-instances.def, # counting the instances of each kind of pass, adding an instance number # to everywhere that NEXT_PASS is used. +# Also handle INSERT_PASS_AFTER, INSERT_PASS_BEFORE and REPLACE_PASS +# directives. # # For example, the single-instanced pass: # NEXT_PASS (pass_warn_unused_result); @@ -30,81 +32,201 @@ # through: # NEXT_PASS (pass_copy_prop, 8); # (currently there are 8 instances of that pass) +# +# INSERT_PASS_AFTER (pass_copy_prop, 1, pass_stv); +# will insert +# NEXT_PASS (pass_stv, 1); +# immediately after the NEXT_PASS (pass_copy_prop, 1) line, +# similarly INSERT_PASS_BEFORE inserts immediately before that line. +# REPLACE_PASS (pass_copy_prop, 1, pass_stv, true); +# will replace NEXT_PASS (pass_copy_prop, 1) line with +# NEXT_PASS (pass_stv, 1, true); +# line and renumber all higher pass_copy_prop instances if any. # Usage: awk -f gen-pass-instances.awk passes.def BEGIN { - print "/* This file is auto-generated by gen-pass-instances.awk"; - print " from passes.def. */"; + print "/* This file is auto-generated by gen-pass-instances.awk"; + print " from passes.def. */"; + lineno = 1; } -function handle_line() +function parse_line(line, fnname, len_of_call, len_of_start, + len_of_open, len_of_close, + len_of_args, args_start_at, + args_str, len_of_prefix, + call_starts_at, + postfix_starts_at) { - line = $0; - - # Find call expression. - call_starts_at = match(line, /NEXT_PASS \(.+\)/); - if (call_starts_at == 0) - { - print line; - return; - } + # Find call expression. + call_starts_at = match(line, fnname " \\(.+\\)"); + if (call_starts_at == 0) + return 0; + + # Length of the call expression. + len_of_call = RLENGTH; + + len_of_start = length(fnname " ("); + len_of_open = length("("); + len_of_close = length(")"); + + # Find arguments + 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, ","); + + # Find call expression prefix + len_of_prefix = call_starts_at - 1; + prefix = substr(line, 1, len_of_prefix); + + # Find call expression postfix + postfix_starts_at = call_starts_at + len_of_call; + postfix = substr(line, postfix_starts_at); + return 1; +} - # Length of the call expression. - len_of_call = RLENGTH; +function adjust_linenos(above, increment, p, i) +{ + for (p in pass_lines) + if (pass_lines[p] >= above) + pass_lines[p] += pass_lines[p]; + if (increment > 0) + for (i = lineno - 1; i >= above; i--) + lines[i + increment] = lines[i]; + else + for (i = above; i < lineno; i++) + lines[i + increment] = lines[i]; + lineno += increment; +} - len_of_start = length("NEXT_PASS ("); - len_of_open = length("("); - len_of_close = length(")"); +function insert_remove_pass(line, fnname) +{ + parse_line($0, fnname); + pass_name = args[1]; + if (pass_name == "PASS") + return 1; + pass_num = args[2] + 0; + new_line = prefix "NEXT_PASS (" args[3]; + if (args[4]) + new_line = new_line ", " args[4]; + new_line = new_line ")" postfix; + if (!pass_lines[pass_name, pass_num]) + { + print "ERROR: Can't locate instance of the pass mentioned in " fnname; + return 1; + } + return 0; +} - # Find arguments - 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, ","); +function insert_pass(line, fnname, after, num) +{ + if (insert_remove_pass(line, fnname)) + return; + num = pass_lines[pass_name, pass_num]; + adjust_linenos(num + after, 1); + pass_name = args[3]; + # Set pass_counts + if (args[3] in pass_counts) + pass_counts[pass_name]++; + else + pass_counts[pass_name] = 1; + + pass_lines[pass_name, pass_counts[pass_name]] = num + after; + lines[num + after] = new_line; +} - # Set pass_name argument, an optional with_arg argument - pass_name = args[1]; - with_arg = args[2]; +function replace_pass(line, fnname, num, i) +{ + if (insert_remove_pass(line, "REPLACE_PASS")) + return; + num = pass_lines[pass_name, pass_num]; + for (i = pass_counts[pass_name]; i > pass_num; i--) + pass_lines[pass_name, i - 1] = pass_lines[pass_name, i]; + delete pass_lines[pass_name, pass_counts[pass_name]]; + if (pass_counts[pass_name] == 1) + delete pass_counts[pass_name]; + else + pass_counts[pass_name]--; + + pass_name = args[3]; + # Set pass_counts + if (args[3] in pass_counts) + pass_counts[pass_name]++; + else + pass_counts[pass_name] = 1; + + pass_lines[pass_name, pass_counts[pass_name]] = num; + lines[num] = new_line; +} - # Find call expression prefix - len_of_prefix = call_starts_at - 1; - prefix = substr(line, 1, len_of_prefix); +/INSERT_PASS_AFTER \(.+\)/ { + insert_pass($0, "INSERT_PASS_AFTER", 1); + next; +} - # Find call expression postfix - postfix_starts_at = call_starts_at + len_of_call; - postfix = substr(line, postfix_starts_at); +/INSERT_PASS_BEFORE \(.+\)/ { + insert_pass($0, "INSERT_PASS_BEFORE", 0); + next; +} - # Set pass_counts - if (pass_name in pass_counts) - pass_counts[pass_name]++; - else - pass_counts[pass_name] = 1; +/REPLACE_PASS \(.+\)/ { + replace_pass($0, "REPLACE_PASS"); + next; +} - pass_num = pass_counts[pass_name]; +{ + ret = parse_line($0, "NEXT_PASS"); + if (ret) + { + pass_name = args[1]; + + # Set pass_counts + if (pass_name in pass_counts) + pass_counts[pass_name]++; + else + pass_counts[pass_name] = 1; + + pass_lines[pass_name, pass_counts[pass_name]] = lineno; + } + lines[lineno++] = $0; +} - # Print call expression with extra pass_num argument - printf "%s", prefix; - if (with_arg) +END { + delete pass_counts; + for (i = 1; i < lineno; i++) + { + ret = parse_line(lines[i], "NEXT_PASS"); + if (ret) { - printf "NEXT_PASS_WITH_ARG"; + # Set pass_name argument, an optional with_arg argument + pass_name = args[1]; + with_arg = args[2]; + + # Set pass_counts + if (pass_name in pass_counts) + pass_counts[pass_name]++; + else + pass_counts[pass_name] = 1; + + pass_num = pass_counts[pass_name]; + + # Print call expression with extra pass_num argument + printf "%s", prefix; + if (with_arg) + printf "NEXT_PASS_WITH_ARG"; + else + printf "NEXT_PASS"; + printf " (%s, %s", pass_name, pass_num; + if (with_arg) + printf ", %s", with_arg; + printf ")%s\n", postfix; } - else - { - printf "NEXT_PASS"; - } - printf " ("; - printf "%s", pass_name; - printf ", %s", pass_num; - if (with_arg) - { - printf ", %s", with_arg; - } - printf ")%s\n", postfix; + else + print lines[i]; + } } -{ handle_line() } - # Local Variables: # mode:awk # c-basic-offset:8 -- 2.30.2