From patchwork Mon Mar 21 14:45:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Verbin X-Patchwork-Id: 600157 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qTJZM4cKHz9s5g for ; Tue, 22 Mar 2016 01:47:06 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=gF1OV+52; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=nL+JVSK5YAHUITPmwiK4Aj9vyWr9r4rrrfvlEPtZSTHE0ZnJvG NOZtiSURqhLxj2MavCG2d0NYsBBx4jUJ7Mhh2Rn6ttdDV8/E/YuHHHCcLP5sC/E/ zR0f8u3VIHwKIwqEkw6GjN+MetnmSNt10HWMCaA9+kqe6AZO4AVF/RCCw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=7+9L7mr7x4t6EGEH0CHfI8AuZvA=; b=gF1OV+524BR+XF1fgkoT /EvSSpVpdpWj0CeMmk1wBHQ71ghr2JwQ8vp1EBMVSRlYROZPBa2RBcey83vCO2WB /lnap5lzdimf2cg4znTrQwwXDGECj8FErTehmi6tQXuOHnqoBwhDqTWkGNPYgbHz xJhKeYeGUDipoEymYUu2YCQ= Received: (qmail 11689 invoked by alias); 21 Mar 2016 14:46:58 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 11680 invoked by uid 89); 21 Mar 2016 14:46:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=ax, friend, UD:htm X-HELO: mail-wm0-f50.google.com Received: from mail-wm0-f50.google.com (HELO mail-wm0-f50.google.com) (74.125.82.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Mon, 21 Mar 2016 14:46:47 +0000 Received: by mail-wm0-f50.google.com with SMTP id r129so53574965wmr.1 for ; Mon, 21 Mar 2016 07:46:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=uCx5Z74QunGOEHvJrgGolomBaHNepNoUFH5Ci1b3KjI=; b=XV51l4TN0unbl+hO6EqoDM+2kDBrvxu1ky7+qwp9fCfNP3ZfwiyUJIRv7o6XRd1MTh MWsiFfy63Kh0ANYh7L/2IPYIuiBlq2xZbH809scMM7J0RVhF5A9qTa5GM42QqCiYhJye pvpXBoeSy0n5IMIg53wK2s/NlkL4ofz9b4UUraEEELe8DN+1gUaEMvOg2l2zo3fFOYVv v5KZLJdAye0HhmtrljrcsPXz0FwdUnMO0/6RK23bv9iob1jfqzYNzi0PxZ7haDvoAi0Y r3sm1QPkh7XBollobsOu5qgJRmrpVH0FVD6AD6AWc1A1uAeBdwIwcnB7SdgCXGUCYzKq zMXg== X-Gm-Message-State: AD7BkJL/ijWPgFsLfqykXP91bJpmyoZvoQO8PhXBfIz7bV5mb0PpQpP9ErkkBvvEb7GgFQ== X-Received: by 10.28.73.66 with SMTP id w63mr14900245wma.53.1458571604256; Mon, 21 Mar 2016 07:46:44 -0700 (PDT) Received: from msticlxl57.ims.intel.com (irdmzpr01-ext.ir.intel.com. [192.198.151.36]) by smtp.gmail.com with ESMTPSA id gt7sm25705975wjc.1.2016.03.21.07.46.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Mar 2016 07:46:43 -0700 (PDT) Date: Mon, 21 Mar 2016 17:45:52 +0300 From: Ilya Verbin To: gcc-patches@gcc.gnu.org, Jakub Jelinek Cc: Kirill Yukhin Subject: [PATCH][CilkPlus] Allow parenthesized initialization in for-loops Message-ID: <20160321144552.GA1422@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hi! www.cilkplus.org/sites/default/files/open_specifications/Intel_Cilk_plus_lang_spec_1.2.htm says: In C++, the control variable shall be declared and initialized within the initialization clause of the _Cilk_for loop. The variable shall have automatic storage duration. The variable shall be initialized. Initialization may be explicit, using assignment or constructor syntax, or implicit via a nontrivial default constructor. This patch enables constructor-syntax initialization. Bootstraped and regtested on x86_64-linux. OK for stage1? gcc/cp/ * parser.c (cp_parser_omp_for_loop_init): Allow parenthesized initialization in Cilk Plus for-loops. gcc/testsuite/ * g++.dg/cilk-plus/CK/for2.cc: New test. -- Ilya diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d58b5aa..49b3791 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -33284,54 +33284,68 @@ cp_parser_omp_for_loop_init (cp_parser *parser, if (declarator == cp_error_declarator) cp_parser_skip_to_end_of_statement (parser); - else { tree pushed_scope, auto_node; + bool is_cilk, is_class, next_is_semicol, next_is_eq, next_is_open; decl = start_decl (declarator, &type_specifiers, SD_INITIALIZED, attributes, /*prefix_attributes=*/NULL_TREE, &pushed_scope); + is_class = CLASS_TYPE_P (TREE_TYPE (decl)); auto_node = type_uses_auto (TREE_TYPE (decl)); - if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)) - { - if (cp_lexer_next_token_is (parser->lexer, - CPP_OPEN_PAREN)) - { - if (code != CILK_SIMD && code != CILK_FOR) - error ("parenthesized initialization is not allowed in " - "OpenMP % loop"); - else - error ("parenthesized initialization is " - "not allowed in for-loop"); - } - else - /* Trigger an error. */ - cp_parser_require (parser, CPP_EQ, RT_EQ); + is_cilk = code == CILK_SIMD || code == CILK_FOR; + next_is_semicol + = cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON); + next_is_eq = cp_lexer_next_token_is (parser->lexer, CPP_EQ); + next_is_open = cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN); + if (!is_cilk && next_is_open) + { + error ("parenthesized initialization is not allowed in " + "OpenMP % loop"); + init = error_mark_node; + cp_parser_skip_to_end_of_statement (parser); + } + else if (!is_cilk && !next_is_eq) + { + /* Trigger an error. */ + cp_parser_require (parser, CPP_EQ, RT_EQ); init = error_mark_node; cp_parser_skip_to_end_of_statement (parser); } - else if (CLASS_TYPE_P (TREE_TYPE (decl)) - || type_dependent_expression_p (decl) - || auto_node) + else if (is_cilk && !(next_is_eq || next_is_open || next_is_semicol)) + { + cp_parser_error (parser, "expected %<=%>, %<(%> or %<;%>"); + init = error_mark_node; + cp_parser_skip_to_end_of_statement (parser); + } + else if (is_cilk && !is_class && next_is_open) + { + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + init = cp_parser_assignment_expression (parser); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + goto non_class; + } + else if (is_class || type_dependent_expression_p (decl) || auto_node) { bool is_direct_init, is_non_constant_init; - init = cp_parser_initializer (parser, - &is_direct_init, - &is_non_constant_init); - + if (is_cilk && next_is_semicol) + init = NULL_TREE; + else + init = cp_parser_initializer (parser, + &is_direct_init, + &is_non_constant_init); if (auto_node) { TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl), init, auto_node); - if (!CLASS_TYPE_P (TREE_TYPE (decl)) - && !type_dependent_expression_p (decl)) + if (!is_class && !type_dependent_expression_p (decl)) goto non_class; } @@ -33339,7 +33353,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser, asm_specification, LOOKUP_ONLYCONVERTING); orig_init = init; - if (CLASS_TYPE_P (TREE_TYPE (decl))) + if (is_class) { vec_safe_push (for_block, this_pre_body); init = NULL_TREE; @@ -33350,8 +33364,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser, } else { - /* Consume '='. */ - cp_lexer_consume_token (parser->lexer); + cp_parser_require (parser, CPP_EQ, RT_EQ); init = cp_parser_assignment_expression (parser); non_class: diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/for2.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/for2.cc new file mode 100644 index 0000000..b9e4420 --- /dev/null +++ b/gcc/testsuite/g++.dg/cilk-plus/CK/for2.cc @@ -0,0 +1,46 @@ +/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-options "-fcilkplus" } */ +/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */ + +class control_var +{ +private: + int x; +public: + control_var () { x = 0; }; + control_var (int a) { x = a; }; + int get_x () const { return x; }; + void operator ++ (int) { x++; }; + void operator += (int y) { x += y; }; + bool operator < (const control_var &a) const { return x < a.x; }; + friend int operator - (control_var a, control_var b) { return a.x - b.x; }; +}; + +int +main () +{ + int arr[100]; + + _Cilk_for (control_var i; i < control_var (100); i++) + arr[i.get_x ()] = i.get_x (); + + for (int i = 0; i < 100; i++) + if (arr[i] != i) + __builtin_abort (); + + _Cilk_for (control_var i (50); i < control_var (150); i++) + arr[i.get_x () - 50] = i.get_x (); + + for (int i = 0; i < 100; i++) + if (arr[i] != i + 50) + __builtin_abort (); + + _Cilk_for (int i (100); i < 200; i++) + arr[i - 100] = i; + + for (int i = 0; i < 100; i++) + if (arr[i] != i + 100) + __builtin_abort (); + + return 0; +}