#define RANGE_FOR_UNROLL(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 4)
#define RANGE_FOR_INIT_STMT(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 5)
#define RANGE_FOR_IVDEP(NODE) TREE_LANG_FLAG_6 (RANGE_FOR_STMT_CHECK (NODE))
+#define RANGE_FOR_NOVECTOR(NODE) TREE_LANG_FLAG_5 (RANGE_FOR_STMT_CHECK (NODE))
/* STMT_EXPR accessor. */
#define STMT_EXPR_STMT(NODE) TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0)
/* In parser.cc */
extern tree cp_convert_range_for (tree, tree, tree, tree, unsigned int, bool,
- unsigned short);
+ unsigned short, bool);
extern void cp_convert_omp_range_for (tree &, vec<tree, va_gc> *, tree &,
tree &, tree &, tree &, tree &, tree &);
extern void cp_finish_omp_range_for (tree, tree);
extern void finish_else_clause (tree);
extern void finish_if_stmt (tree);
extern tree begin_while_stmt (void);
-extern void finish_while_stmt_cond (tree, tree, bool, unsigned short);
+extern void finish_while_stmt_cond (tree, tree, bool, unsigned short,
+ bool);
extern void finish_while_stmt (tree);
extern tree begin_do_stmt (void);
extern void finish_do_body (tree);
-extern void finish_do_stmt (tree, tree, bool, unsigned short);
+extern void finish_do_stmt (tree, tree, bool, unsigned short,
+ bool);
extern tree finish_return_stmt (tree);
extern tree begin_for_scope (tree *);
extern tree begin_for_stmt (tree, tree);
extern void finish_init_stmt (tree);
-extern void finish_for_cond (tree, tree, bool, unsigned short);
+extern void finish_for_cond (tree, tree, bool, unsigned short,
+ bool);
extern void finish_for_expr (tree, tree);
extern void finish_for_stmt (tree);
extern tree begin_range_for_stmt (tree, tree);
static tree cp_parser_condition
(cp_parser *);
static tree cp_parser_iteration_statement
- (cp_parser *, bool *, bool, unsigned short);
+ (cp_parser *, bool *, bool, unsigned short, bool);
static bool cp_parser_init_statement
(cp_parser *, tree *decl);
static tree cp_parser_for
- (cp_parser *, bool, unsigned short);
+ (cp_parser *, bool, unsigned short, bool);
static tree cp_parser_c_for
- (cp_parser *, tree, tree, bool, unsigned short);
+ (cp_parser *, tree, tree, bool, unsigned short, bool);
static tree cp_parser_range_for
- (cp_parser *, tree, tree, tree, bool, unsigned short, bool);
+ (cp_parser *, tree, tree, tree, bool, unsigned short, bool, bool);
static void do_range_for_auto_deduction
(tree, tree, tree, unsigned int);
static tree cp_parser_perform_range_for_lookup
case RID_DO:
case RID_FOR:
std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
- statement = cp_parser_iteration_statement (parser, if_p, false, 0);
+ statement = cp_parser_iteration_statement (parser, if_p, false, 0,
+ false);
break;
case RID_BREAK:
not included. */
static tree
-cp_parser_for (cp_parser *parser, bool ivdep, unsigned short unroll)
+cp_parser_for (cp_parser *parser, bool ivdep, unsigned short unroll,
+ bool novector)
{
tree init, scope, decl;
bool is_range_for;
if (is_range_for)
return cp_parser_range_for (parser, scope, init, decl, ivdep, unroll,
- false);
+ novector, false);
else
- return cp_parser_c_for (parser, scope, init, ivdep, unroll);
+ return cp_parser_c_for (parser, scope, init, ivdep, unroll, novector);
}
static tree
cp_parser_c_for (cp_parser *parser, tree scope, tree init, bool ivdep,
- unsigned short unroll)
+ unsigned short unroll, bool novector)
{
/* Normal for loop */
tree condition = NULL_TREE;
"%<GCC unroll%> pragma");
condition = error_mark_node;
}
- finish_for_cond (condition, stmt, ivdep, unroll);
+ finish_for_cond (condition, stmt, ivdep, unroll, novector);
/* Look for the `;'. */
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
static tree
cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl,
- bool ivdep, unsigned short unroll, bool is_omp)
+ bool ivdep, unsigned short unroll, bool novector,
+ bool is_omp)
{
tree stmt, range_expr;
auto_vec <cxx_binding *, 16> bindings;
RANGE_FOR_IVDEP (stmt) = 1;
if (unroll)
RANGE_FOR_UNROLL (stmt) = build_int_cst (integer_type_node, unroll);
+ if (novector)
+ RANGE_FOR_NOVECTOR (stmt) = 1;
finish_range_for_decl (stmt, range_decl, range_expr);
if (!type_dependent_expression_p (range_expr)
/* do_auto_deduction doesn't mess with template init-lists. */
stmt = begin_for_stmt (scope, init);
stmt = cp_convert_range_for (stmt, range_decl, range_expr,
decomp_first_name, decomp_cnt, ivdep,
- unroll);
+ unroll, novector);
}
return stmt;
}
tree
cp_convert_range_for (tree statement, tree range_decl, tree range_expr,
tree decomp_first_name, unsigned int decomp_cnt,
- bool ivdep, unsigned short unroll)
+ bool ivdep, unsigned short unroll, bool novector)
{
tree begin, end;
tree iter_type, begin_expr, end_expr;
begin, ERROR_MARK,
end, ERROR_MARK,
NULL_TREE, NULL, tf_warning_or_error);
- finish_for_cond (condition, statement, ivdep, unroll);
+ finish_for_cond (condition, statement, ivdep, unroll, novector);
/* The new increment expression. */
expression = finish_unary_op_expr (input_location,
static tree
cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep,
- unsigned short unroll)
+ unsigned short unroll, bool novector)
{
cp_token *token;
enum rid keyword;
parens.require_open (parser);
/* Parse the condition. */
condition = cp_parser_condition (parser);
- finish_while_stmt_cond (condition, statement, ivdep, unroll);
+ finish_while_stmt_cond (condition, statement, ivdep, unroll, novector);
/* Look for the `)'. */
parens.require_close (parser);
/* Parse the dependent statement. */
/* Parse the expression. */
expression = cp_parser_expression (parser);
/* We're done with the do-statement. */
- finish_do_stmt (expression, statement, ivdep, unroll);
+ finish_do_stmt (expression, statement, ivdep, unroll, novector);
/* Look for the `)'. */
parens.require_close (parser);
/* Look for the `;'. */
matching_parens parens;
parens.require_open (parser);
- statement = cp_parser_for (parser, ivdep, unroll);
+ statement = cp_parser_for (parser, ivdep, unroll, novector);
/* Look for the `)'. */
parens.require_close (parser);
cp_parser_require (parser, CPP_COLON, RT_COLON);
init = cp_parser_range_for (parser, NULL_TREE, NULL_TREE, decl,
- false, 0, true);
+ false, 0, false, true);
cp_convert_omp_range_for (this_pre_body, for_block, decl,
orig_decl, init, orig_init,
return unroll;
}
+/* Parse a pragma GCC novector. */
+
+static bool
+cp_parser_pragma_novector (cp_parser *parser, cp_token *pragma_tok)
+{
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return true;
+}
+
/* Normal parsing of a pragma token. Here we can (and must) use the
regular lexer. */
break;
case PRAGMA_IVDEP:
+ case PRAGMA_UNROLL:
+ case PRAGMA_NOVECTOR:
{
- if (context == pragma_external)
+ bool ivdep;
+ unsigned short unroll = 0;
+ bool novector = false;
+ const char *pragma_str;
+
+ switch (id)
{
- error_at (pragma_tok->location,
- "%<#pragma GCC ivdep%> must be inside a function");
+ case PRAGMA_IVDEP:
+ pragma_str = "ivdep";
break;
- }
- const bool ivdep = cp_parser_pragma_ivdep (parser, pragma_tok);
- unsigned short unroll;
- cp_token *tok = cp_lexer_peek_token (the_parser->lexer);
- if (tok->type == CPP_PRAGMA
- && cp_parser_pragma_kind (tok) == PRAGMA_UNROLL)
- {
- tok = cp_lexer_consume_token (parser->lexer);
- unroll = cp_parser_pragma_unroll (parser, tok);
- tok = cp_lexer_peek_token (the_parser->lexer);
- }
- else
- unroll = 0;
- if (tok->type != CPP_KEYWORD
- || (tok->keyword != RID_FOR
- && tok->keyword != RID_WHILE
- && tok->keyword != RID_DO))
- {
- cp_parser_error (parser, "for, while or do statement expected");
- return false;
- }
- cp_parser_iteration_statement (parser, if_p, ivdep, unroll);
- return true;
- }
+ case PRAGMA_UNROLL:
+ pragma_str = "unroll";
+ break;
+ case PRAGMA_NOVECTOR:
+ pragma_str = "novector";
+ break;
+ default:
+ gcc_unreachable ();
+ }
- case PRAGMA_UNROLL:
- {
if (context == pragma_external)
{
error_at (pragma_tok->location,
- "%<#pragma GCC unroll%> must be inside a function");
+ "%<#pragma GCC %s%> must be inside a function",
+ pragma_str);
break;
}
- const unsigned short unroll
- = cp_parser_pragma_unroll (parser, pragma_tok);
- bool ivdep;
- cp_token *tok = cp_lexer_peek_token (the_parser->lexer);
- if (tok->type == CPP_PRAGMA
- && cp_parser_pragma_kind (tok) == PRAGMA_IVDEP)
+
+ cp_token *tok = pragma_tok;
+ bool has_more = true;
+ do
{
- tok = cp_lexer_consume_token (parser->lexer);
- ivdep = cp_parser_pragma_ivdep (parser, tok);
+ switch (cp_parser_pragma_kind (tok))
+ {
+ case PRAGMA_IVDEP:
+ {
+ if (tok != pragma_tok)
+ tok = cp_lexer_consume_token (parser->lexer);
+ ivdep = cp_parser_pragma_ivdep (parser, tok);
+ break;
+ }
+ case PRAGMA_UNROLL:
+ {
+ if (tok != pragma_tok)
+ tok = cp_lexer_consume_token (parser->lexer);
+ unroll = cp_parser_pragma_unroll (parser, tok);
+ break;
+ }
+ case PRAGMA_NOVECTOR:
+ {
+ if (tok != pragma_tok)
+ tok = cp_lexer_consume_token (parser->lexer);
+ novector = cp_parser_pragma_novector (parser, tok);
+ break;
+ }
+ default:
+ has_more = false;
+ break;
+ }
tok = cp_lexer_peek_token (the_parser->lexer);
+ has_more = has_more && tok->type == CPP_PRAGMA;
}
- else
- ivdep = false;
+ while (has_more);
+
if (tok->type != CPP_KEYWORD
|| (tok->keyword != RID_FOR
&& tok->keyword != RID_WHILE
cp_parser_error (parser, "for, while or do statement expected");
return false;
}
- cp_parser_iteration_statement (parser, if_p, ivdep, unroll);
+ cp_parser_iteration_statement (parser, if_p, ivdep, unroll, novector);
return true;
}
void
finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep,
- unsigned short unroll)
+ unsigned short unroll, bool novector)
{
cond = maybe_convert_cond (cond);
finish_cond (&WHILE_COND (while_stmt), cond);
annot_expr_unroll_kind),
build_int_cst (integer_type_node,
unroll));
+ if (novector && cond != error_mark_node)
+ WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR,
+ TREE_TYPE (WHILE_COND (while_stmt)),
+ WHILE_COND (while_stmt),
+ build_int_cst (integer_type_node,
+ annot_expr_no_vector_kind),
+ integer_zero_node);
simplify_loop_decl_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt));
}
COND is as indicated. */
void
-finish_do_stmt (tree cond, tree do_stmt, bool ivdep, unsigned short unroll)
+finish_do_stmt (tree cond, tree do_stmt, bool ivdep, unsigned short unroll,
+ bool novector)
{
cond = maybe_convert_cond (cond);
end_maybe_infinite_loop (cond);
cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
build_int_cst (integer_type_node, annot_expr_unroll_kind),
build_int_cst (integer_type_node, unroll));
+ if (novector && cond != error_mark_node)
+ cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
+ build_int_cst (integer_type_node, annot_expr_no_vector_kind),
+ integer_zero_node);
DO_COND (do_stmt) = cond;
}
FOR_STMT. */
void
-finish_for_cond (tree cond, tree for_stmt, bool ivdep, unsigned short unroll)
+finish_for_cond (tree cond, tree for_stmt, bool ivdep, unsigned short unroll, bool novector)
{
cond = maybe_convert_cond (cond);
finish_cond (&FOR_COND (for_stmt), cond);
annot_expr_unroll_kind),
build_int_cst (integer_type_node,
unroll));
+ if (novector && cond != error_mark_node)
+ FOR_COND (for_stmt) = build3 (ANNOTATE_EXPR,
+ TREE_TYPE (FOR_COND (for_stmt)),
+ FOR_COND (for_stmt),
+ build_int_cst (integer_type_node,
+ annot_expr_no_vector_kind),
+ integer_zero_node);
simplify_loop_decl_cond (&FOR_COND (for_stmt), FOR_BODY (for_stmt));
}