On Fri, Nov 17, 2017 at 11:23 AM, Eric Botcazou <ebotca...@adacore.com> wrote: > Hi, > > this is a cleaned up and updated revision of Mike's latest posted patch > implementing #pragma GCC unroll in the C and C++ compilers. To be honest, > we're not so much interested in the front-end bits as in the middle-end bits, > because the latter would at last make the Ada version of the pragma work, but > the front-end bits are a significant part of the whole thing so it's probably > fair to rescue them as well. > > The C and C++ front-end bits are (almost) verbatim from Mike. The cleanup > comprises making the new 3rd operand of ANNOTATE_EXPR mandatory, so that you > don't have to add guards all over the place, polishing a few rough edges and > eliminating a few preexisting nits in the unrolling code. > > Tested on x86_64-suse-linux, OK for the mainline?
Looking at the middle-end changes. The change to ANNOTATE_EXPR to three operands is approved also for existing frontends (just in case you don't get review). Found the missing possibility of an argument limiting myself... Your changes to the RTL unrolling pass as far as I see enable the optimization in its general form for all loops in a function if cfun->has_unroll, not just for the marked loops. I think that is unintended? I think you want to change copy_loop_info () to copy the flag as well. @@ -1566,7 +1593,7 @@ public: {} /* opt_pass methods: */ - virtual bool gate (function *) { return optimize >= 2; } + virtual bool gate (function *) { return optimize >= 2 || cfun->has_unroll; } virtual unsigned int execute (function *); }; // class pass_complete_unrolli I think this has the same issue as the RTL unroller change. Otherwise the middle-end changes look ok. Thanks, Richard. > > 2017-11-17 Mike Stump <mikest...@comcast.net> > Eric Botcazou <ebotca...@adacore.com> > > ChangeLog: > * doc/extend.texi (Loop-Specific Pragmas): Document pragma GCC unroll. > * doc/generic.texi (ANNOTATE_EXPR): Document 3rd operand. > * cfgloop.h (struct loop): Add unroll field. > * function.h (struct function): Add has_unroll bitfield. > * gimplify.c (gimple_boolify) <ANNOTATE_EXPR>: Deal with unroll kind. > (gimplify_expr) <ANNOTATE_EXPR>: Propagate 3rd operand. > * loop-init.c (pass_loop2::gate): Return true if cfun->has_unroll. > (pass_rtl_unroll_loops::gate): Likewise. > * loop-unroll.c (decide_unrolling): Tweak note message. Skip loops > if loop->unroll==1 and force unrolling loop->unroll > 1. > (decide_unroll_constant_iterations): Use note for consistency and > return early if loop->unroll is set. > (decide_unroll_runtime_iterations): Use note for consistency and take > loop->unroll into account. > (decide_unroll_stupid): Likewise. > * lto-streamer-in.c (input_cfg): Read loop->unroll. > * lto-streamer-out.c (output_cfg): Write loop->unroll. > * tree-cfg.c (replace_loop_annotate_in_block) <annot_expr_unroll_kind> > New. > (replace_loop_annotate) <annot_expr_unroll_kind>: Likewise. > (print_loop): Print loop->unroll if set. > * tree-core.h (enum annot_expr_kind): Add annot_expr_unroll_kind. > * tree-inline.c (copy_loops): Copy unroll and set cfun->has_unroll. > * tree-pretty-print.c (dump_generic_node) <annot_expr_unroll_kind>: > New. > * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Bail out if > loop->unroll is set and smaller than the trip count. Otherwise bypass > entirely the heuristics if loop->unroll is set. Remove dead note. > Fix off-by-one bug in other node. > (try_peel_loop): Bail out if loop->unroll is set. Fix formatting. > (tree_unroll_loops_completely_1): Force unrolling if loop->unroll > is greater than 1. > * tree.def (ANNOTATE_EXPR): Add 3rd operand. > > ada/ChangeLog: > > * gcc-interface/trans.c (gnat_gimplify_stmt) <LOOP_STMT>: Add 3rd > operand to ANNOTATE_EXPR and pass unrolling hints. > > c-family/ChangeLog: > > * c-pragma.c (init_pragma): Register pragma GCC unroll. > * c-pragma.h (enum pragma_kind): Add PRAGMA_UNROLL. > > c/ChangeLog: > > * c-parser.c (c_parser_while_statement): Add unroll parameter and > build ANNOTATE_EXPR if present. Add 3rd operand to ANNOTATE_EXPR. > (c_parser_do_statement): Likewise. > (c_parser_for_statement): Likewise. > (c_parser_statement_after_labels): Adjust calls to above. > (c_parse_pragma_ivdep): New static function. > (c_parser_pragma_unroll): Likewise. > (c_parser_pragma) <PRAGMA_IVDEP>: Add support for pragma Unroll. > <PRAGMA_UNROLL>: New case. > > cp/ChangeLog: > > * constexpr.c (cxx_eval_constant_expression) <ANNOTATE_EXPR>: Remove > assertion on 2nd operand. > (potential_constant_expression_1): Likewise. > * cp-array-notation.c (create_an_loop): Adjut call to finish_for_cond. > * cp-tree.h (cp_convert_range_for): Adjust prototype. > (finish_while_stmt_cond): Likewise. > (finish_do_stmt): Likewise. > (finish_for_cond): Likewise. > * init.c (build_vec_init): Adjut call to finish_for_cond. > * parser.c (cp_parser_statement): Adjust call to > cp_parser_iteration_statement. > (cp_parser_for): Add unroll parameter and pass it in calls to > cp_parser_range_for and cp_parser_c_for. > (cp_parser_c_for): Add unroll parameter and pass it in call to > finish_for_cond. > (cp_parser_range_for): Add unroll parameter and pass it in call to > cp_convert_range_for. > (cp_convert_range_for): Add unroll parameter and pass it in call to > finish_for_cond. > (cp_parser_iteration_statement): Add unroll parameter and pass it in > calls to finish_while_stmt_cond, finish_do_stmt and cp_parser_for. > (cp_parser_pragma_ivdep): New static function. > (cp_parser_pragma_unroll): Likewise. > (cp_parser_pragma) <PRAGMA_IVDEP>: Add support for pragma Unroll. > <PRAGMA_UNROLL>: New case. > * pt.c (tsubst_expr): Adjut calls to finish_for_cond, > cp_convert_range_for, finish_while_stmt_cond and finish_do_stmt. > <ANNOTATE_EXPR>: Propagate 3rd operand. > * semantics.c (finish_while_stmt_cond): Add unroll parameter and > build ANNOTATE_EXPR if present. Add 3rd operand to ANNOTATE_EXPR. > (finish_do_stmt): Likewise. > (finish_for_cond): Likewise. > > fortran/ChangeLog: > > * trans-stmt.c (gfc_trans_forall_loop): Add 3rd operand to > ANNOTATE_EXPR. > > testsuite/ChangeLog: > > * c-c++-common/unroll-1.c: New test. > * c-c++-common/unroll-2.c: Likewise. > * c-c++-common/unroll-3.c: Likewise. > * c-c++-common/unroll-4.c: Likewise. > * gcc.dg/tree-prof/unroll-1.c: Use detailed dump and adjust scan. > * gcc.dg/unroll-2.c (foo): Adjust message. > (foo2): Likewise. > * gcc.dg/unroll-3.c: Adjust scan. > * gcc.dg/unroll-4.c: Likewise. > * gcc.dg/unroll-5.c: Likewise. > * gcc.dg/unroll-7.c: Use detailed dump and adjust scan. > * gnat.dg/unroll1.ad[sb]: New test. > * gnat.dg/unroll2.ad[sb]: Likewise. > > ada/gcc-interface/trans.c | 25 ++- > c-family/c-pragma.c | 4 > c-family/c-pragma.h | 1 > c/c-parser.c | 151 +++++++++++++++---- > cfgloop.h | 5 > cp/constexpr.c | 2 > cp/cp-array-notation.c | 2 > cp/cp-tree.h | 9 - > cp/init.c | 2 > cp/parser.c | 122 ++++++++++++--- > cp/pt.c | 16 +- > cp/semantics.c | 42 ++++- > doc/extend.texi | 12 + > doc/generic.texi | 2 > fortran/trans-stmt.c | 5 > function.h | 5 > gimplify.c | 4 > loop-init.c | 6 > loop-unroll.c | 66 +++++--- > lto-streamer-in.c | 1 > lto-streamer-out.c | 1 > testsuite/c-c++-common/unroll-1.c | 41 +++++ > testsuite/c-c++-common/unroll-2.c | 41 +++++ > testsuite/c-c++-common/unroll-3.c | 20 ++ > testsuite/c-c++-common/unroll-4.c | 29 +++ > testsuite/gcc.dg/tree-prof/unroll-1.c | 4 > testsuite/gcc.dg/unroll-2.c | 4 > testsuite/gcc.dg/unroll-3.c | 2 > testsuite/gcc.dg/unroll-4.c | 2 > testsuite/gcc.dg/unroll-5.c | 2 > testsuite/gcc.dg/unroll-7.c | 4 > testsuite/gnat.dg/unroll1.adb | 27 +++ > testsuite/gnat.dg/unroll1.ads | 9 + > testsuite/gnat.dg/unroll2.adb | 26 +++ > testsuite/gnat.dg/unroll2.ads | 9 + > tree-cfg.c | 8 + > tree-core.h | 1 > tree-inline.c | 5 > tree-pretty-print.c | 4 > tree-ssa-loop-ivcanon.c | 269 ++++++++++++++++++-------------- > tree.def | 5 > 41 files changed, 755 insertions(+), 240 deletions(-) > > -- > Eric Botcazou