From patchwork Mon Jun 24 22:23:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iyer, Balaji V" X-Patchwork-Id: 253981 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 2D3992C0095 for ; Tue, 25 Jun 2013 08:24:05 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:mime-version; q=dns; s=default; b=lxV32+UNLA0Q/0fb WHNy0DvU4ab/h5+C1jXQd4IhcqznOBuNjKv9zYoCJcyBpRXlkenPUphrYaAS1jRs wWVKKuHfVvGta4y+dzGiSwnKZ1EVsvva80Lfd2bBK8WXeJ30JqS8ZoPlV5jIjKIx XXcEEG4Ydu/sqEBRbrabuP5ZrCg= 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:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:mime-version; s=default; bh=76xcDw+nATT2LZ44mDwxG1 TiBHM=; b=JdKnx313tm8KBeTVO6WvF+VJJoB8NtHncCdm1YB27hxAKePlNRtB/P y9VItpWJf8wvWi50m4ic9W0wJ+egU3XYlZPKoviWe1XesPEqfS/kdUo1/iSjckiZ 4aCJYrNqaQWIDrdxSqgdSlGRxjtTXdFeJxgkdiOyuL5uwGZiu56Cs= Received: (qmail 11064 invoked by alias); 24 Jun 2013 22:23:56 -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 11051 invoked by uid 89); 24 Jun 2013 22:23:56 -0000 X-Spam-SWARE-Status: No, score=-7.2 required=5.0 tests=AWL, BAYES_00, KHOP_THREADED, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RP_MATCHES_RCVD, SPF_PASS, TW_EG, TW_TM autolearn=ham version=3.3.1 Received: from mga02.intel.com (HELO mga02.intel.com) (134.134.136.20) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 24 Jun 2013 22:23:50 +0000 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 24 Jun 2013 15:23:47 -0700 X-ExtLoop1: 1 Received: from fmsmsx106.amr.corp.intel.com ([10.19.9.37]) by orsmga002.jf.intel.com with ESMTP; 24 Jun 2013 15:23:33 -0700 Received: from fmsmsx114.amr.corp.intel.com (10.18.116.8) by FMSMSX106.amr.corp.intel.com (10.19.9.37) with Microsoft SMTP Server (TLS) id 14.3.123.3; Mon, 24 Jun 2013 15:23:32 -0700 Received: from fmsmsx101.amr.corp.intel.com ([169.254.1.114]) by FMSMSX114.amr.corp.intel.com ([169.254.6.109]) with mapi id 14.03.0123.003; Mon, 24 Jun 2013 15:23:32 -0700 From: "Iyer, Balaji V" To: Jason Merrill , Richard Henderson CC: Aldy Hernandez , "gcc-patches@gcc.gnu.org" Subject: RE: [PATCH] Cilk Plus Array Notation for C++ Date: Mon, 24 Jun 2013 22:23:31 +0000 Message-ID: References: <51B8A2FA.2020404@redhat.com> <51B9EF1D.9060505@redhat.com> <51B9F0EA.50709@redhat.com> <51BF4222.3050107@redhat.com> <51C0F06E.3080507@redhat.com> <51C341D2.8020707@redhat.com> <51C5CEC9.8050309@redhat.com> In-Reply-To: <51C5CEC9.8050309@redhat.com> MIME-Version: 1.0 X-Virus-Found: No Hi Jason, Please see below for my responses to your questions. I am also attaching a fixed patch (diffed with trunk's head) and Changelog entries. Thanks, Balaji V. Iyer. > -----Original Message----- > From: Jason Merrill [mailto:jason@redhat.com] > Sent: Saturday, June 22, 2013 12:20 PM > To: Iyer, Balaji V; Richard Henderson > Cc: Aldy Hernandez; gcc-patches@gcc.gnu.org > Subject: Re: [PATCH] Cilk Plus Array Notation for C++ > > Hmm, seems like I should have sent this yesterday even though I hadn't made it > through the whole patch. But I suppose it doesn't hurt to fix it after checkin. > > On 06/20/2013 07:39 PM, Iyer, Balaji V wrote: > > diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog old mode > > 100644 new mode 100755 index a0f195b..fb70520 Binary files > > a/gcc/c-family/ChangeLog and b/gcc/c-family/ChangeLog differ > > Why are you marking lots of files as executable? I think the reason why this is happening is that I use emacs on my windows machine and it is doing some conversion. Is there a way to tell emacs not to do this? > > In the future please filter out ChangeLogs entirely from diffs. I use > > filterdiff -x '*/ChangeLog' | sed -e '/^diff.*ChangeLog/{N;d}' > > for my own patches. OK. I generally don't include the changelog entries, but the last one was a mistake. I will make sure it doesn't happen again. > > > + if (flag_enable_cilkplus > > + && (contains_array_notation_expr (expr) > > + || contains_array_notation_expr (fn))) > > Looking at "fn" here doesn't make sense; it's only used for diagnostics. Fixed! > > > + /* If we are using array notations, we fix them up at a later stage > > + and we will do these checks then. */ > > + ; > > And please don't mess with the overload resolution code directly to handle this > case differently. Fixed! Removed the code. It was an artifact of a previous implementation. Things works fine even without it. > > This seems to be a general problem with the patch; you are special-casing array > notation all through the compiler rather than making it work with the existing > mechanisms. > > In this case, an ARRAY_NOTATION_REF should have a type that participates > normally with conversions. Yep, it is done that way. > > >> + /* If the function call is builtin array notation function then no need > >> + to do any type conversion. */ > > And here, instead of changing build_over_call, you can use the existing > magic_varargs_p mechanism. Fixed! > > > +/* This function parses Cilk Plus array notations. The starting index is > > + passed in INIT_INDEX and the array name is passed in ARRAY_VALUE. If the > > + INIT_INDEX is NULL, then we have special case were the entire > > +array is > > "where" Fixed! > > > + accessed (e.g. A[:]). The return value of this function is a tree node > > + called VALUE_TREE of type ARRAY_NOTATION_REF. If some error > > + occurred it > > Drop "called VALUE_TREE"; the function comment shouldn't talk about local > variables. Fixed! > > > + cp_token *token = NULL; > > + tree start_index = NULL_TREE, length_index = NULL_TREE, stride = > > + NULL_TREE; tree value_tree, type, array_type, array_type_domain; > > + double_int x; bool saved_colon_corrects_to_scope_p = > > + parser->colon_corrects_to_scope_p; > > Now that the compiler is built as C++, variables should be defined at the point of > first use, rather than at the top of the function. > Fixed! > > + if (TREE_CODE (array_type) == RECORD_TYPE > > + || TREE_CODE (array_type) == POINTER_TYPE) > > + { > > + error_at (loc, "start-index and length fields necessary for " > > + "using array notations in pointers or > > + records"); > > I think this should handle all non-array types, rather than just pointers and > classes. > > Let's say "notation" rather than "notations" in all diagnostics. I think I have fixed them all. > > > + error_at (loc, "array notations cannot be used with" > > + " function pointer arrays"); > > I don't see this restriction in any of the documentation. What's the rationale? > Sorry, that was a mistake on my part. I have fixed it. > > + error_at (loc, "start-index and length fields necessary for " > > + "using array notations in dimensionless > > + arrays"); > > Let's say "...with array of unknown bound" Fixed! > > > + start_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, > > + start_index); > > Use cp_fold_convert rather than fold_build1. Fixed! > > > + x = TREE_INT_CST (TYPE_MAXVAL (array_type_domain)); > > + x.low++; > > + length_index = double_int_to_tree (integer_type_node, x); > > This assumes a constant length array. Use size_binop instead. Fixed! > > > + stride = build_int_cst (integer_type_node, 1); > > + stride = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, > > + stride); > > Build the constant in ptrdiff_type_node rather than build it in integer_type_node > and then convert. Fixed! > > > + /* Disable correcting single colon correcting to scope. */ > > + parser->colon_corrects_to_scope_p = false; > > + stride = cp_parser_expression (parser, false, NULL); > > + parser->colon_corrects_to_scope_p = > > + saved_colon_corrects_to_scope_p; > > Why do you do this for the stride? We've already seen both array-notation > colons at this point. > I removed it. > > + /* We fold all 3 of the values to make things easier when we transform > > + them later. */ > > Why is this better than folding at transformation time? Fixed! We are already folding before transformation. > > > + /* If we are here, then we have something like this: > > + ARRAY[:] > > + */ > > The */ should go at the end of the last line in all comments. Fixed! > > > - if (for_offsetof) > > - index = cp_parser_constant_expression (parser, false, NULL); > ... > > else > > { > > - if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) > ... > > + if (for_offsetof) > > + index = cp_parser_constant_expression (parser, false, NULL); > > + else > > Please try to avoid re-indenting code when possible, to make history annotation > simpler. > OK. > Actually, to reduce the amount of changes to non-AN code, let's put the AN case > third, after the offset and {} cases, so you get something like > > else if (flag_enable_cilkplus) > { > tree an = cp_parser_array_notation (loc, parser, &index, > postfix_expression); > if (an) > return an; > /* Otherwise, cp_parser_array_notation set 'index'. */ > } > else > index = cp_parser_expression (parser, /*cast_p=*/false, NULL); > > this way the change is just a few added lines, and everything else is in > cp_parser_array_notation. If I do it this way, then I don't think I will be able to handle a normal array reference when cilk plus is enabled. One thing I could do is to assume that people won't use array notations in braced list. I had it like this a while back but I made the change to make sure I have covered more cases. Please let me know if that is OK and I will fix it. > > > + if (flag_enable_cilkplus && contains_array_notation_expr > (compound_stmt)) > > + compound_stmt = expand_array_notation_exprs (compound_stmt); > ... > > + /* Transform all array notations to the equivalent array refs and > > + loop. */ if (flag_enable_cilkplus && contains_array_notation_expr (body)) > > + body = expand_array_notation_exprs (body); > ... > > + /* Expand all array notation expressions here. */ if > > + (flag_enable_cilkplus && current_function_decl > > + && contains_array_notation_expr (DECL_SAVED_TREE > (current_function_decl))) > > + DECL_SAVED_TREE (current_function_decl) = > > + expand_array_notation_exprs (DECL_SAVED_TREE > > + (current_function_decl)); > > Let's do the transformation in cp_genericize rather than in these places. > > Perhaps moving the expansion to gimplification time would also help with > sharing code between C and C++, since you don't have to worry about templates > at that point. I moved the array notation expansion to cp_generize_tree function. I have also removed the expansion in pt.c > > > + if (flag_enable_cilkplus > > + && contains_array_notation_expr (condition)) > > + { > > + error_at (EXPR_LOCATION (condition), > > + "array notations cannot be used as a condition for " > > + "switch statement"); > > + statement = error_mark_node; > > + } > [etc] > > I'd prefer to give diagnostics about uses that don't make sense at > transformation time, rather than parsing time. Fixed! > > > + if (flag_enable_cilkplus > > + && cp_lexer_next_token_is (parser->lexer, CPP_COLON)) > > + { > > + bounds = error_mark_node; > > + error_at (cp_lexer_peek_token (parser->lexer)->location, > > + "array notations cannot be used in declaration"); > > + cp_lexer_consume_token (parser->lexer); > > + } > > I'm concerned about this causing trouble with tentative parsing, and I think that > people are unlikely to try to write a declaration using array notation, so let's > leave out the changes to cp_parser_direct_declarator. Ok. I have removed it. > > > @@ -15758,6 +15772,9 @@ type_unification_real (tree tparms, > > + if (flag_enable_cilkplus && TREE_CODE (arg) == ARRAY_NOTATION_REF) > > + return 1; > > Again, an ARRAY_NOTATION_REF should have a type like any other expression; > we don't need to prevent it from participating in type deduction. Yep. This is fixed also. > > > @@ -8073,6 +8089,7 @@ cxx_eval_constant_expression (const > > constexpr_call *call, tree t, > > + case ARRAY_NOTATION_REF: > > @@ -8884,6 +8901,7 @@ potential_constant_expression_1 (tree t, bool > > want_rval, tsubst_flags_t flags) > > + case ARRAY_NOTATION_REF: > > cxx_eval_array_reference doesn't know how to deal with > ARRAY_NOTATION_REF, so let's not add it to cxx_eval_constant_expression, > and return false for it from potential_constant_expression_1. Fixed as you suggested. > > > + if (flag_enable_cilkplus > > + && is_cilkplus_reduce_builtin (fndecl) != BUILT_IN_NONE) > > + nargs = (*params)->length (); > > + else > > + nargs = convert_arguments (parm_types, params, fndecl, > LOOKUP_NORMAL, > > + complain); > > Another change that should be replaced by addition to magic_varargs_p, though > it looks like convert_arguments needs to be updated to use magic_varargs_p > rather than checking specifically for BUILT_IN_CONSTANT_P. I looked into this. But, magic_varargs_p is static to call.c. Should I make it non-static? After making it non-static I was planning to do something like this: if (magic_varargs_p (fndecl) Nargs = (*params)->length (); else nargs = convert_arguments (...) Is that OK with you? > > > + for (size_t ii = 0; ii < size; ii++) > > + for (size_t jj = 0; jj < rank; jj++) > > + { > > + (*node)[ii].safe_push (init); > > + array_exprs[ii].safe_push (NULL_TREE); > > + } > > Why not use safe_grow_cleared for the sub-vecs as well? Fixed! > > > + while (ii_tree) > > + if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF) > > Wrap the sub-statement of the 'while' in { }. > Fixed! > > + else if (TREE_CODE (ii_tree) == VAR_DECL > > + || TREE_CODE (ii_tree) == CALL_EXPR > > + || TREE_CODE (ii_tree) == PARM_DECL) > > + break; > > + else > > + gcc_unreachable (); > e > There are lots of other ways to gt an expression of array type, why are only > these allowed? > Sorry, it was a mistake as well. The main point of that loop was to allow array refs intermingling with array notations. > > + if (TREE_CODE ((*list)[ii]) == ARRAY_NOTATION_REF) > > + for (size_t jj = 0; jj < rank; jj++) > > + if (TREE_CODE (array_exprs[ii][jj]) == ARRAY_NOTATION_REF) > > How could the array_exprs element be anything other than an > ARRAY_NOTATION_REF? That's all you put in when you were building it. > Fixed! > By the way, why are you breaking out the elements of the > ARRAY_NOTATION_REF into a cilkplus_an_parts rather than using the _REF > directly? > I use the different parts of array notations for error checking and to create the outer for-loop. Also, to create the ARRAY_REF I need the induction variable. > > + if (TREE_CODE ((*list)[ii]) == CALL_EXPR > > + && TREE_CODE (CALL_EXPR_FN ((*list)[ii])) == ADDR_EXPR > > + && is_sec_implicit_index_fn (CALL_EXPR_FN ((*list)[ii]))) > > Why check for ADDR_EXPR here? Better for is_sec_implicit_index_fn to return > false if its argument isn't what's desired. Fixed! > > > + if (idx < (int) rank && idx >= 0) > > + vec_safe_push (array_operand, an_loop_info[idx].var); > > + else if (idx == -1) > > + /* In this case, the returning function would have emitted an > > + error thus it is not necessary to do so again. */ > > + return NULL; > > Reorder these cases so you don't need to check idx >= 0. Fixed! > > > + same dimension and one the same side of the equal sign. The Array > > + notation > > "on the same side" Fixed! (Sorry for the stupid mistake). > > > + l_node = int_cst_value (list[ii][jj].length); > > + l_length = int_cst_value (length); > > + if (absu_hwi (l_length) != absu_hwi (l_node)) > > Use tree_int_cst_equal instead. Fixed! > > > + for (jj = 0; jj < y; jj++) > > + { > > + length = NULL_TREE; > > + for (ii = 0; ii < x; ii++) > > Why did you switch the outer/inner iteration variables for this loop compared to > others? The y axis represents the rank and x-axis represents the expressions in the polynomial. So, for-each rank I go through all the expressions to make sure the lengths are the same. > > > + /* We set the length node as the current node just in case it turns > > + out to be an integer. */ > > + length = list[ii][jj].length; > > How could it "turn out" to be an integer? We just checked, and it isn't one. > We have not checked list[ii][jj].length is an integer. I agree that I should clarify the comment. I have fixed that. > > + var = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node); > > + finish_expr_stmt (build_x_modify_expr (loc, var, NOP_EXPR, > > + *value, cry)); > > This should use get_temp_regvar. > > We shouldn't need to pass tsubst_flags_t around, since we will never be > expanding array notation in SFINAE context. Fixed! By the way, what is SFINAE? > > > + /* If stride and start are of same type and the induction var > > + is not, convert induction variable to stride's type. */ > > + if (TREE_TYPE (start) == TREE_TYPE (stride) > > + && TREE_TYPE (stride) != TREE_TYPE (var)) > > This seems impossible, since 'var' is created to have the same type as 'start'. As you suggested further in the email, I have made var of type ptrdiff_type, so I think I should keep this. > > > + /* If we reach here, then the stride and start are of > > + different types, and so it doesn't really matter what > > + the induction variable type is, convert everything to > > + integer. The reason why we pick an integer > > + instead of something like size_t is because the stride > > + and length can be + or -. */ > > Maybe the induction variable should always be ptrdiff_type_node. Yep. Fixed! > > Jason COPY- PASTING your last responde from thread (http://gcc.gnu.org/ml/gcc-patches/2013-06/msg01385.html) below: > A few more comments: > > > + if (processing_template_decl || !TREE_TYPE (t)) > > + new_var = build_min_nt_loc (EXPR_LOCATION (t), VAR_DECL, > NULL_TREE, > > + NULL_TREE); > > Again, we shouldn't be trying to expand array notation during template parsing. Fixed! > > And replace_invariant_exprs should also use get_temp_regvar, as should most > of the places you create temporary variables. Fixed! > > > + /* We need to do this because we are "faking" the builtin function types, > > + so the compiler does a bunch of typecasts and this will get rid of > > + all that! */ > > Again, magic_varargs_p can avoid any gratuitous type conversions. > Please see my comment above about magic_varargs_p. > > + case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO: > > + case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO: > > + case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO: > > + case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO: > > + new_var_type = integer_type_node; > > I would expect boolean_type_node. Yep. Fixed! > > > + an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, > > + TREE_TYPE (an_info[0][ii].start)); > > Here you can use create_temporary_var. > Fixed! > > + an_loop_info[ii].ind_init = build_x_modify_expr > > + (location, an_loop_info[ii].var, NOP_EXPR, > > + build_zero_cst (TREE_TYPE (an_loop_info[ii].var)), > > + tf_warning_or_error); > > Here and in other calls to build_x_modify_expr for initialization, use INIT_EXPR > rather than NOP_EXPR. > Fixed! > > + *new_var = create_tmp_var (new_var_type, NULL); > > create_tmp_var is part of gimplification; it might be appropriate to use it when > you move lowering to happen later in the compilation, but it seems wrong in the > current code. Removed and replaced it with create_temporary_var. > > > + code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? > EQ_EXPR > > + : NE_EXPR; > > A ?: expression split across multiple lines should have parens around it. > Fixed! > > + /* If both are scalar, then the only reason why we will get this far is if > > + there is some array notations inside it and was using a builtin array > > + notation functions. If so, we have already broken those guys up and now > > + a simple build_x_modify_expr would do. */ if (lhs_rank == 0 && > > + rhs_rank == 0) > > + { > > + if (found_builtin_fn) > > + { > > + new_modify_expr = build_x_modify_expr (location, lhs, > > + modifycode, rhs, complain); > > + finish_expr_stmt (new_modify_expr); > > + pop_stmt_list (an_init); > > + return an_init; > > + } > > + else > > + { > > + pop_stmt_list (an_init); > > + return NULL_TREE; > > + } > > + } > > The comment makes it sound like the else should be gcc_unreachable. > Yes, I added gcc_unreachable there. > > + if (location == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (rhs)) > > + location = EXPR_LOCATION (rhs); > > This is redundant with code a few lines above. Fixed! > > > + append_to_statement_list_force (lhs_an_loop_info[ii].ind_init, > > + &init_list); > > Why do you need _force? > No reason. Just wanted to make sure it surely gets in. I have removed it. > Jason gcc/ChangeLog 2013-06-24 Balaji V. Iyer * builtins.def: Fixed the function type of CILKPLUS_BUILTIN. gcc/c/ChangeLog 2013-06-24 Balaji V. Iyer * c-parser.c (c_parser_array_notation): Removed rejection of array notations in an array of function pointers. gcc/c-family/ChangeLog 2013-06-24 Balaji V. Iyer * array-notation-common.c (length_mismatch_in_expr_p): Collapsed two if-statements and compared the trees directly using tree_int_cst_equal. (find_rank): Checked for array notations in function name to handle array notations in function pointers. (extract_array_notation_exprs): Likewise. (cilkplus_extract_an_triplets): Removed restriction of array notations having just VAR, PARM DECL or CALL exprs. (replace_array_notations): Likewise. (cilkplus_extract_an_triplets): Replaced safe_push with safe_grow_cleared. Also removed an unnecessary check to see if the node is of type ARRAY_NOTATION_REF. (fix_sec_implicit_args): Removed an unnecessary check for ADDR_EXPR. Also switched two if-statements to remove an unnecessary comparison. gcc/cp/ChangeLog 2013-06-24 Balaji V. Iyer * parser.c (cp_parser_array_notation): Removed rejection array notation of type function pointers. Used cp_fold_convert instead of fold_build1. Moved variable that saves colon corrects variable into the if-statement. (cp_parser_compound_statement): Removed expansion of array notations. (cp_parser_ctor_initializer_opt_and_function_body): Likewise. (cp_parser_function_definition_after_declarator): Likewise. (cp_parser_selection_statement): Removed error reporting. (cp_parser_iteration_statement): Likewise. (cp_parser_direct_declarator): Removed error checking/reporting if array notations are used in the declarator. * pt.c (instantiate_decl): Likewise. (type_unification_real): Removed a check for ARRAY_NOTATION_REF. (cxx_eval_constant_expression): Removed ARRAY_NOTATION_REF case. (potential_constant_expression_1): Returned false for ARRAY_NOTATION_REF case. * cp-gimplify.c (cp_genericize): Added expansion of array notation expressions here. * cp-array-notation.c (cp_length_mismatch_in_expr_p): Combined two if statements into one and compared integers using tree_int_cst_equal. (make_triplet_val_inv): Removed loc and cry parameters. Also, replaced build_decls with get_temp_regvar. (replace_invariant_var): Replaced build_decl and build_min_nt_loc with get_temp_regvar. (expand_an_in_modify_expr): Ditto. Replaced body of redundant else with gcc_unreachable. Removed few unwanted checks. Made induction variable type as ptrdiff_type. Removed loc and complain arguments passed into make_triplet_val_inv. Replaced all modify expression's code from NOP EXPR to INIT EXPR. Replaced all forceful appending into stmt. list with the non-forceful one. (expand_reduce_builtin): All changes mentioned in above function expand_an_in_modify_expr. Made the new variable type of SEC_REDUCE_ANY/ALL_{NON}ZERO intrinsic functions as bool. (expand_array_notation_exprs): Removed SWITCH_EXPR case. Moved all the error reporting from parser to this function. (cilkplus_an_triplet_types_ok_p): Removed rejection of array notation in function pointers. * call.c (convert_like_real): Removed a check for array notation expression in a function. (build_over_call): Likewise. (magic_varargs_p): Added a check for builtin array notation function. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f45983..d81f7ce 100644 Binary files a/gcc/ChangeLog and b/gcc/ChangeLog differ diff --git a/gcc/builtins.def b/gcc/builtins.def index 91879a6..9b55b1f 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -158,9 +158,9 @@ along with GCC; see the file COPYING3. If not see (flag_asan || flag_tsan)) #undef DEF_CILKPLUS_BUILTIN -#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ - DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - false, false, true, ATTRS, false, flag_enable_cilkplus) +#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_FN_INT_VAR, BT_LAST, \ + false, false, false, ATTRS, false, flag_enable_cilkplus) /* Define an attribute list for math functions that are normally "impure" because some of them may write into global memory for diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 03269e9..53f35d4 100644 Binary files a/gcc/c-family/ChangeLog and b/gcc/c-family/ChangeLog differ diff --git a/gcc/c-family/array-notation-common.c b/gcc/c-family/array-notation-common.c index 0e2a431..ae96941 100644 --- a/gcc/c-family/array-notation-common.c +++ b/gcc/c-family/array-notation-common.c @@ -86,7 +86,6 @@ length_mismatch_in_expr_p (location_t loc, tree **list, size_t x, size_t y) { size_t ii, jj; tree start = NULL_TREE; - HOST_WIDE_INT l_start, l_node; for (jj = 0; jj < y; jj++) { start = NULL_TREE; @@ -99,15 +98,11 @@ length_mismatch_in_expr_p (location_t loc, tree **list, size_t x, size_t y) /* If start is a INTEGER, and list[ii][jj] is an integer then check if they are equal. If they are not equal then return true. */ - if (TREE_CODE (list[ii][jj]) == INTEGER_CST) - { - l_node = int_cst_value (list[ii][jj]); - l_start = int_cst_value (start); - if (absu_hwi (l_start) != absu_hwi (l_node)) - { - error_at (loc, "length mismatch in expression"); - return true; - } + if (TREE_CODE (list[ii][jj]) == INTEGER_CST + && !tree_int_cst_equal (list[ii][jj], start)) + { + error_at (loc, "length mismatch in expression"); + return true; } } else @@ -269,6 +264,8 @@ find_rank (location_t loc, tree orig_expr, tree expr, bool ignore_builtin_fn, /* If it is a built-in function, then we know it returns a scalar. */ return true; + if (!find_rank (loc, orig_expr, func_name, ignore_builtin_fn, rank)) + return false; FOR_EACH_CALL_EXPR_ARG (arg, iter, expr) { if (!find_rank (loc, orig_expr, arg, ignore_builtin_fn, rank)) @@ -356,6 +353,9 @@ extract_array_notation_exprs (tree node, bool ignore_builtin_fn, vec_safe_push (*array_list, node); return; } + /* This will extract array notations in function pointers. */ + extract_array_notation_exprs (CALL_EXPR_FN (node), ignore_builtin_fn, + array_list); FOR_EACH_CALL_EXPR_ARG (arg, iter, node) extract_array_notation_exprs (arg, ignore_builtin_fn, array_list); } @@ -431,6 +431,9 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn, } return; } + /* Fixes array notations in array notations in function pointers. */ + replace_array_notations (&CALL_EXPR_FN (*orig), ignore_builtin_fn, list, + array_operand); ii = 0; FOR_EACH_CALL_EXPR_ARG (arg, iter, *orig) { @@ -573,53 +576,49 @@ cilkplus_extract_an_triplets (vec *list, size_t size, size_t rank, vec > *node) { vec > array_exprs = vNULL; - struct cilkplus_an_parts init = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, - false }; + node->safe_grow_cleared (size); array_exprs.safe_grow_cleared (size); - for (size_t ii = 0; ii < size; ii++) - for (size_t jj = 0; jj < rank; jj++) + + if (rank > 0) + for (size_t ii = 0; ii < size; ii++) { - (*node)[ii].safe_push (init); - array_exprs[ii].safe_push (NULL_TREE); + (*node)[ii].safe_grow_cleared (rank); + array_exprs[ii].safe_grow_cleared (rank); } - for (size_t ii = 0; ii < size; ii++) { size_t jj = 0; tree ii_tree = (*list)[ii]; while (ii_tree) - if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF) - { - array_exprs[ii][jj] = ii_tree; - jj++; - ii_tree = ARRAY_NOTATION_ARRAY (ii_tree); - } - else if (TREE_CODE (ii_tree) == ARRAY_REF) - ii_tree = TREE_OPERAND (ii_tree, 0); - else if (TREE_CODE (ii_tree) == VAR_DECL - || TREE_CODE (ii_tree) == CALL_EXPR - || TREE_CODE (ii_tree) == PARM_DECL) - break; - else - gcc_unreachable (); + { + if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF) + { + array_exprs[ii][jj] = ii_tree; + jj++; + ii_tree = ARRAY_NOTATION_ARRAY (ii_tree); + } + else if (TREE_CODE (ii_tree) == ARRAY_REF) + ii_tree = TREE_OPERAND (ii_tree, 0); + else + break; + } } for (size_t ii = 0; ii < size; ii++) if (TREE_CODE ((*list)[ii]) == ARRAY_NOTATION_REF) for (size_t jj = 0; jj < rank; jj++) - if (TREE_CODE (array_exprs[ii][jj]) == ARRAY_NOTATION_REF) - { - tree ii_tree = array_exprs[ii][jj]; - (*node)[ii][jj].is_vector = true; - (*node)[ii][jj].value = ARRAY_NOTATION_ARRAY (ii_tree); - (*node)[ii][jj].start = ARRAY_NOTATION_START (ii_tree); - (*node)[ii][jj].length = - fold_build1 (CONVERT_EXPR, integer_type_node, - ARRAY_NOTATION_LENGTH (ii_tree)); - (*node)[ii][jj].stride = - fold_build1 (CONVERT_EXPR, integer_type_node, - ARRAY_NOTATION_STRIDE (ii_tree)); - } + { + tree ii_tree = array_exprs[ii][jj]; + (*node)[ii][jj].is_vector = true; + (*node)[ii][jj].value = ARRAY_NOTATION_ARRAY (ii_tree); + (*node)[ii][jj].start = ARRAY_NOTATION_START (ii_tree); + (*node)[ii][jj].length = + fold_build1 (CONVERT_EXPR, integer_type_node, + ARRAY_NOTATION_LENGTH (ii_tree)); + (*node)[ii][jj].stride = + fold_build1 (CONVERT_EXPR, integer_type_node, + ARRAY_NOTATION_STRIDE (ii_tree)); + } } /* Replaces all the __sec_implicit_arg functions in LIST with the induction @@ -635,16 +634,15 @@ fix_sec_implicit_args (location_t loc, vec *list, vec *array_operand = NULL; for (size_t ii = 0; ii < vec_safe_length (list); ii++) if (TREE_CODE ((*list)[ii]) == CALL_EXPR - && TREE_CODE (CALL_EXPR_FN ((*list)[ii])) == ADDR_EXPR && is_sec_implicit_index_fn (CALL_EXPR_FN ((*list)[ii]))) { int idx = extract_sec_implicit_index_arg (loc, (*list)[ii]); - if (idx < (int) rank && idx >= 0) - vec_safe_push (array_operand, an_loop_info[idx].var); - else if (idx == -1) + if (idx < 0) /* In this case, the returning function would have emitted an error thus it is not necessary to do so again. */ return NULL; + else if (idx < (int) rank) + vec_safe_push (array_operand, an_loop_info[idx].var); else { error_at (loc, "__sec_implicit_index argument %d must be " diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 05766ca..53bfe88 100644 Binary files a/gcc/c/ChangeLog and b/gcc/c/ChangeLog differ diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index d6a500e..c7846ce 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -11053,24 +11053,6 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } - if (TREE_CODE (array_type) == ARRAY_TYPE) - { - tree subtype = TREE_TYPE (array_type); - while (subtype && TREE_CODE (subtype) == POINTER_TYPE) - { - /* Now this could be a function pointer. Find them and - give out an error. */ - subtype = TREE_TYPE (subtype); - if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE) - { - error_at (loc, "array notations cannot be used with " - "function pointer arrays"); - c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, - NULL); - return error_mark_node; - } - } - } array_type_domain = TYPE_DOMAIN (array_type); if (!array_type_domain) @@ -11114,27 +11096,6 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } - if (TREE_CODE (array_type) == ARRAY_TYPE - || TREE_CODE (array_type) == POINTER_TYPE) - { - tree subtype = TREE_TYPE (array_type); - while (subtype - && (TREE_CODE (subtype) == POINTER_TYPE - || TREE_CODE (subtype) == ARRAY_TYPE)) - { - /* Now this could be a function pointer. Find them and - give out an error. */ - subtype = TREE_TYPE (subtype); - if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE) - { - error_at (loc, "array notations cannot be used with " - "function pointer arrays"); - c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, - NULL); - return error_mark_node; - } - } - } c_parser_consume_token (parser); /* consume the ':' */ end_index = c_parser_expression (parser).value; if (!end_index || end_index == error_mark_node) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 55ed6a5..9d570b2 100644 Binary files a/gcc/cp/ChangeLog and b/gcc/cp/ChangeLog differ diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 6817bfc..0350da8 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5857,16 +5857,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, else if (t->kind == ck_identity) break; } - - if (flag_enable_cilkplus - && (contains_array_notation_expr (expr) - || contains_array_notation_expr (fn))) - /* If we are using array notations, we fix them up at a later stage - and we will do these checks then. */ - ; - else if (permerror (loc, "invalid conversion from %qT to %qT", - TREE_TYPE (expr), totype) - && fn) + if (permerror (loc, "invalid conversion from %qT to %qT", + TREE_TYPE (expr), totype) + && fn) inform (DECL_SOURCE_LOCATION (fn), "initializing argument %P of %qD", argnum, fn); @@ -6518,6 +6511,9 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain) static bool magic_varargs_p (tree fn) { + if (flag_enable_cilkplus && is_cilkplus_reduce_builtin (fn) != BUILT_IN_NONE) + return true; + if (DECL_BUILT_IN (fn)) switch (DECL_FUNCTION_CODE (fn)) { @@ -6895,21 +6891,13 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) " (you can disable this with -fno-deduce-init-list)"); } } + val = convert_like_with_context (conv, arg, fn, i - is_method, + conversion_warning + ? complain + : complain & (~tf_warning)); - /* If the function call is builtin array notation function then no need - to do any type conversion. */ - if (flag_enable_cilkplus - && is_cilkplus_reduce_builtin (fn) != BUILT_IN_NONE) - val = arg; - else - { - val = convert_like_with_context (conv, arg, fn, i - is_method, - conversion_warning - ? complain - : complain & (~tf_warning)); - - val = convert_for_arg_passing (type, val, complain); - } + val = convert_for_arg_passing (type, val, complain); + if (val == error_mark_node) return error_mark_node; else diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c index 92272b3..1209cb3 100644 --- a/gcc/cp/cp-array-notation.c +++ b/gcc/cp/cp-array-notation.c @@ -59,7 +59,6 @@ #include "diagnostic.h" #include "tree-iterator.h" #include "vec.h" -#include "gimple.h" /* Creates a FOR_STMT with INIT, COND, INCR and BODY as the initializer, condition, increment expression and the loop-body, respectively. */ @@ -79,7 +78,7 @@ create_an_loop (tree init, tree cond, tree incr, tree body) } /* Returns true if there is a length mismatch among exprssions that are at the - same dimension and one the same side of the equal sign. The Array notation + same dimension and on the same side of the equal sign. The Array notation lengths (LIST->LENGTH) is passed in as a 2D vector of trees. */ static bool @@ -87,14 +86,13 @@ cp_length_mismatch_in_expr_p (location_t loc, vec >list) { size_t ii, jj; tree length = NULL_TREE; - HOST_WIDE_INT l_length, l_node; size_t x = list.length (); - size_t y = list[0].length (); - + size_t y = list[0].length (); + for (jj = 0; jj < y; jj++) { - length = NULL_TREE; + length = NULL_TREE; for (ii = 0; ii < x; ii++) { if (!length) @@ -104,20 +102,16 @@ cp_length_mismatch_in_expr_p (location_t loc, vec >list) /* If length is a INTEGER, and list[ii][jj] is an integer then check if they are equal. If they are not equal then return true. */ - if (TREE_CODE (list[ii][jj].length) == INTEGER_CST) - { - l_node = int_cst_value (list[ii][jj].length); - l_length = int_cst_value (length); - if (absu_hwi (l_length) != absu_hwi (l_node)) - { - error_at (loc, "length mismatch in expression"); - return true; - } + if (TREE_CODE (list[ii][jj].length) == INTEGER_CST + && !tree_int_cst_equal (list[ii][jj].length, length)) + { + error_at (loc, "length mismatch in expression"); + return true; } } else - /* We set the length node as the current node just in case it turns - out to be an integer. */ + /* We set the list[ii][jj].length as the current node just in case + it turns out to be an integer. */ length = list[ii][jj].length; } } @@ -128,17 +122,12 @@ cp_length_mismatch_in_expr_p (location_t loc, vec >list) a variable to make it loop invariant for array notations. */ static inline void -make_triplet_val_inv (location_t loc, tree *value, tsubst_flags_t cry) +make_triplet_val_inv (tree *value) { - tree var; if (TREE_CODE (*value) != INTEGER_CST && TREE_CODE (*value) != PARM_DECL && TREE_CODE (*value) != VAR_DECL) - { - var = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node); - finish_expr_stmt (build_x_modify_expr (loc, var, NOP_EXPR, *value, cry)); - *value = var; - } + *value = get_temp_regvar (integer_type_node, *value); } /* Returns a vector of size RANK that contains an ARRAY_REF. This vector is @@ -238,7 +227,7 @@ replace_invariant_exprs (tree *node) { size_t ix = 0; tree node_list = NULL_TREE; - tree t = NULL_TREE, new_var = NULL_TREE, new_node; + tree t = NULL_TREE, new_var = NULL_TREE; struct inv_list data; data.list_values = NULL; @@ -250,17 +239,8 @@ replace_invariant_exprs (tree *node) { node_list = push_stmt_list (); for (ix = 0; vec_safe_iterate (data.list_values, ix, &t); ix++) - { - if (processing_template_decl || !TREE_TYPE (t)) - new_var = build_min_nt_loc (EXPR_LOCATION (t), VAR_DECL, NULL_TREE, - NULL_TREE); - else - new_var = build_decl (EXPR_LOCATION (t), VAR_DECL, NULL_TREE, - TREE_TYPE (t)); - gcc_assert (new_var != NULL_TREE && new_var != error_mark_node); - new_node = build_x_modify_expr (EXPR_LOCATION (t), new_var, NOP_EXPR, - t, tf_warning_or_error); - finish_expr_stmt (new_node); + { + new_var = get_temp_regvar (TREE_TYPE (t), t); vec_safe_push (data.replacement, new_var); } cp_walk_tree (node, replace_inv_trees, (void *) &data, NULL); @@ -281,7 +261,6 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) tree new_var_type = NULL_TREE, func_parm, new_yes_expr, new_no_expr; tree array_ind_value = NULL_TREE, new_no_ind, new_yes_ind, new_no_list; tree new_yes_list, new_cond_expr, new_expr = NULL_TREE; - tree new_var_init = NULL_TREE, new_exp_init = NULL_TREE; vec *array_list = NULL, *array_operand = NULL; size_t list_size = 0, rank = 0, ii = 0; tree body, an_init, loop_with_init = alloc_stmt_list (); @@ -351,7 +330,7 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO: case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO: case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO: - new_var_type = integer_type_node; + new_var_type = boolean_type_node; break; case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND: case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND: @@ -380,24 +359,30 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) if (TREE_CODE ((*array_list)[ii]) == ARRAY_NOTATION_REF) { tree anode = (*array_list)[ii]; - make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode), - tf_warning_or_error); - make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode), - tf_warning_or_error); - make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode), - tf_warning_or_error); + make_triplet_val_inv (&ARRAY_NOTATION_START (anode)); + make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode)); + make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode)); } cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info); for (ii = 0; ii < rank; ii++) { - an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - TREE_TYPE (an_info[0][ii].start)); - an_loop_info[ii].ind_init = build_x_modify_expr - (location, an_loop_info[ii].var, NOP_EXPR, - build_zero_cst (TREE_TYPE (an_loop_info[ii].var)), - tf_warning_or_error); + tree typ = ptrdiff_type_node; + + /* In this place, we are using get_temp_regvar instead of + create_temporary_var if an_type is SEC_REDUCE_MAX/MIN_IND because + the array_ind_value depends on this value being initalized to 0. */ + if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND + || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND) + an_loop_info[ii].var = get_temp_regvar (typ, build_zero_cst (typ)); + else + { + an_loop_info[ii].var = create_temporary_var (typ); + add_decl_expr (an_loop_info[ii].var); + } + an_loop_info[ii].ind_init = + build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR, + build_zero_cst (typ), tf_warning_or_error); } - array_operand = create_array_refs (location, an_info, an_loop_info, list_size, rank); replace_array_notations (&func_parm, true, array_list, array_operand); @@ -406,26 +391,9 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) TREE_TYPE (func_parm) = TREE_TYPE ((*array_list)[0]); create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error); - if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING) - { - if (processing_template_decl) - *new_var = build_decl (location, VAR_DECL, NULL_TREE, new_var_type); - else - *new_var = create_tmp_var (new_var_type, NULL); - } - else - /* We do not require a new variable for mutating. The "identity value" - itself is the variable. */ - *new_var = NULL_TREE; - if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND - || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND) - { - array_ind_value = create_tmp_var (TREE_TYPE (func_parm), NULL); - gcc_assert (array_ind_value && (array_ind_value != error_mark_node)); - DECL_INITIAL (array_ind_value) = NULL_TREE; - pushdecl (array_ind_value); - } + || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND) + array_ind_value = get_temp_regvar (TREE_TYPE (func_parm), func_parm); array_op0 = (*array_operand)[0]; switch (an_type) @@ -440,35 +408,36 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) break; case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO: case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO: - code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? EQ_EXPR - : NE_EXPR; + code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? EQ_EXPR + : NE_EXPR); init = build_zero_cst (new_var_type); cond_init = build_one_cst (new_var_type); comp_node = build_zero_cst (TREE_TYPE (func_parm)); break; case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO: case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO: - code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO) ? NE_EXPR - : EQ_EXPR; + code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO) ? NE_EXPR + : EQ_EXPR); init = build_one_cst (new_var_type); cond_init = build_zero_cst (new_var_type); comp_node = build_zero_cst (TREE_TYPE (func_parm)); break; case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX: code = MAX_EXPR; - init = TYPE_MIN_VALUE (new_var_type) ? TYPE_MIN_VALUE (new_var_type) - : func_parm; + init = (TYPE_MIN_VALUE (new_var_type) ? TYPE_MIN_VALUE (new_var_type) + : func_parm); break; case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN: code = MIN_EXPR; - init = TYPE_MAX_VALUE (new_var_type) ? TYPE_MAX_VALUE (new_var_type) - : func_parm; + init = (TYPE_MAX_VALUE (new_var_type) ? TYPE_MAX_VALUE (new_var_type) + : func_parm); break; case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND: case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND: - code = an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND ? LE_EXPR - : GE_EXPR; + code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND ? LE_EXPR + : GE_EXPR); init = an_loop_info[0].var; + break; case BUILT_IN_CILKPLUS_SEC_REDUCE: init = identity_value; break; @@ -479,9 +448,11 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) gcc_unreachable (); } - if (init) - new_var_init = build_x_modify_expr (location, *new_var, NOP_EXPR, init, - tf_warning_or_error); + if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING) + *new_var = get_temp_regvar (new_var_type, init); + else + *new_var = NULL_TREE; + switch (an_type) { case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD: @@ -516,8 +487,6 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) break; case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND: case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND: - new_exp_init = build_x_modify_expr (location, array_ind_value, NOP_EXPR, - func_parm, tf_warning_or_error); new_yes_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR, func_parm, tf_warning_or_error); new_no_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR, @@ -567,21 +536,8 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) default: gcc_unreachable (); } - - /* The reason we are putting initial variable twice is because the - new exp init below depends on this value being initialized. */ - for (ii = 0; ii < rank; ii++) - finish_expr_stmt (an_loop_info[ii].ind_init); - - if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING) - finish_expr_stmt (new_var_init); - - if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND - || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND) - finish_expr_stmt (new_exp_init); - an_init = pop_stmt_list (an_init); - append_to_statement_list_force (an_init, &loop_with_init); + append_to_statement_list (an_init, &loop_with_init); body = new_expr; for (ii = 0; ii < rank; ii++) @@ -591,7 +547,7 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) an_loop_info[ii].incr, body); body = pop_stmt_list (new_loop); } - append_to_statement_list_force (body, &loop_with_init); + append_to_statement_list (body, &loop_with_init); an_info.release (); an_loop_info.release (); @@ -680,10 +636,7 @@ expand_an_in_modify_expr (location_t location, tree lhs, return an_init; } else - { - pop_stmt_list (an_init); - return NULL_TREE; - } + gcc_unreachable (); } /* If for some reason location is not set, then find if LHS or RHS has @@ -705,8 +658,6 @@ expand_an_in_modify_expr (location_t location, tree lhs, if (lhs_rank == 0 && rhs_rank != 0) { - if (location == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (rhs)) - location = EXPR_LOCATION (rhs); error_at (location, "%qD cannot be scalar when %qD is not", lhs, rhs); return error_mark_node; } @@ -721,17 +672,17 @@ expand_an_in_modify_expr (location_t location, tree lhs, for (ii = 0; ii < lhs_list_size; ii++) { tree anode = (*lhs_list)[ii]; - make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode), complain); - make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode), complain); - make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode), complain); + make_triplet_val_inv (&ARRAY_NOTATION_START (anode)); + make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode)); + make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode)); } for (ii = 0; ii < rhs_list_size; ii++) if ((*rhs_list)[ii] && TREE_CODE ((*rhs_list)[ii]) == ARRAY_NOTATION_REF) { tree aa = (*rhs_list)[ii]; - make_triplet_val_inv (location, &ARRAY_NOTATION_START (aa), complain); - make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (aa), complain); - make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (aa), complain); + make_triplet_val_inv (&ARRAY_NOTATION_START (aa)); + make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (aa)); + make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (aa)); } lhs_an_loop_info.safe_grow_cleared (lhs_rank); @@ -751,10 +702,10 @@ expand_an_in_modify_expr (location_t location, tree lhs, pop_stmt_list (an_init); return error_mark_node; } - tree rhs_len = (rhs_list_size > 0 && rhs_rank > 0) ? - rhs_an_info[0][0].length : NULL_TREE; - tree lhs_len = (lhs_list_size > 0 && lhs_rank > 0) ? - lhs_an_info[0][0].length : NULL_TREE; + tree rhs_len = ((rhs_list_size > 0 && rhs_rank > 0) ? + rhs_an_info[0][0].length : NULL_TREE); + tree lhs_len = ((lhs_list_size > 0 && lhs_rank > 0) ? + lhs_an_info[0][0].length : NULL_TREE); if (lhs_list_size > 0 && rhs_list_size > 0 && lhs_rank > 0 && rhs_rank > 0 && TREE_CODE (lhs_len) == INTEGER_CST && rhs_len && TREE_CODE (rhs_len) == INTEGER_CST) @@ -768,14 +719,16 @@ expand_an_in_modify_expr (location_t location, tree lhs, return error_mark_node; } } - for (ii = 0; ii < lhs_rank; ii++) - if (lhs_an_info[0][ii].start && TREE_TYPE (lhs_an_info[0][ii].start)) - lhs_an_loop_info[ii].var = - build_decl (location, VAR_DECL, NULL_TREE, - TREE_TYPE (lhs_an_info[0][ii].start)); - else - lhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - integer_type_node); + for (ii = 0; ii < lhs_rank; ii++) + { + tree typ = ptrdiff_type_node; + lhs_an_loop_info[ii].var = create_temporary_var (typ); + add_decl_expr (lhs_an_loop_info[ii].var); + lhs_an_loop_info[ii].ind_init = build_x_modify_expr + (location, lhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ), + complain); + } + if (rhs_list_size > 0) { rhs_array_operand = fix_sec_implicit_args (location, rhs_list, @@ -789,24 +742,15 @@ expand_an_in_modify_expr (location_t location, tree lhs, rhs_list = NULL; extract_array_notation_exprs (rhs, true, &rhs_list); rhs_list_size = vec_safe_length (rhs_list); - - for (ii = 0; ii < lhs_rank; ii++) - if (lhs_an_info[0][ii].is_vector) - { - lhs_an_loop_info[ii].ind_init = build_x_modify_expr - (location, lhs_an_loop_info[ii].var, NOP_EXPR, - build_zero_cst (TREE_TYPE (lhs_an_loop_info[ii].var)), complain); - } + for (ii = 0; ii < rhs_rank; ii++) { - /* When we have a polynomial, we assume that the indices are of type - integer. */ - rhs_an_loop_info[ii].var = - build_decl (location, VAR_DECL, NULL_TREE, - TREE_TYPE (rhs_an_info[0][ii].start)); + tree typ = ptrdiff_type_node; + rhs_an_loop_info[ii].var = create_temporary_var (typ); + add_decl_expr (rhs_an_loop_info[ii].var); rhs_an_loop_info[ii].ind_init = build_x_modify_expr - (location, rhs_an_loop_info[ii].var, NOP_EXPR, - build_zero_cst (TREE_TYPE (rhs_an_loop_info[ii].var)), complain); + (location, rhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ), + complain); } if (lhs_rank) @@ -860,7 +804,7 @@ expand_an_in_modify_expr (location_t location, tree lhs, gcc_unreachable (); an_init = pop_stmt_list (an_init); - append_to_statement_list_force (an_init, &loop_with_init); + append_to_statement_list (an_init, &loop_with_init); body = array_expr; for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++) { @@ -870,17 +814,13 @@ expand_an_in_modify_expr (location_t location, tree lhs, if (lhs_rank) { - append_to_statement_list_force (lhs_an_loop_info[ii].ind_init, - &init_list); - append_to_statement_list_force (lhs_an_loop_info[ii].incr, - &incr_list); + append_to_statement_list (lhs_an_loop_info[ii].ind_init, &init_list); + append_to_statement_list (lhs_an_loop_info[ii].incr, &incr_list); } if (rhs_rank) { - append_to_statement_list_force (rhs_an_loop_info[ii].ind_init, - &init_list); - append_to_statement_list_force (rhs_an_loop_info[ii].incr, - &incr_list); + append_to_statement_list (rhs_an_loop_info[ii].ind_init, &init_list); + append_to_statement_list (rhs_an_loop_info[ii].incr, &incr_list); } create_an_loop (init_list, cond_expr[ii], incr_list, body); body = pop_stmt_list (new_loop); @@ -913,7 +853,6 @@ cp_expand_cond_array_notations (tree orig_stmt) tree an_init, body, stmt = NULL_TREE; tree builtin_loop, new_var = NULL_TREE; tree loop_with_init = alloc_stmt_list (); - tsubst_flags_t complain = tf_warning_or_error; location_t location = UNKNOWN_LOCATION; vec > an_info = vNULL; vec an_loop_info = vNULL; @@ -995,11 +934,11 @@ cp_expand_cond_array_notations (tree orig_stmt) vec_safe_push (new_var_list, new_var); replace_array_notations (&orig_stmt, false, sub_list, new_var_list); - append_to_statement_list_force (builtin_loop, &stmt); + append_to_statement_list (builtin_loop, &stmt); } } } - append_to_statement_list_force (orig_stmt, &stmt); + append_to_statement_list (orig_stmt, &stmt); rank = 0; array_list = NULL; if (!find_rank (EXPR_LOCATION (stmt), stmt, stmt, true, &rank)) @@ -1023,37 +962,28 @@ cp_expand_cond_array_notations (tree orig_stmt) for (ii = 0; ii < list_size; ii++) { tree anode = (*array_list)[ii]; - make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode), complain); - make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode), complain); - make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode), complain); + make_triplet_val_inv (&ARRAY_NOTATION_START (anode)); + make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode)); + make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode)); } cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info); - for (ii = 0; ii < rank; ii++) - if (TREE_TYPE (an_info[0][ii].start) - && TREE_CODE (TREE_TYPE (an_info[0][ii].start)) != TEMPLATE_TYPE_PARM) - { - an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - TREE_TYPE (an_info[0][ii].start)); - an_loop_info[ii].ind_init = build_x_modify_expr - (location, an_loop_info[ii].var, NOP_EXPR, - build_zero_cst (TREE_TYPE (an_loop_info[ii].var)), - tf_warning_or_error); - } - else - { - an_loop_info[ii].var = build_min_nt_loc (location, VAR_DECL, - NULL_TREE, NULL_TREE); - an_loop_info[ii].ind_init = - build_x_modify_expr (location, an_loop_info[ii].var, NOP_EXPR, - integer_zero_node, tf_warning_or_error); - } + + for (ii = 0; ii < rank; ii++) + { + tree typ = ptrdiff_type_node; + an_loop_info[ii].var = create_temporary_var (typ); + add_decl_expr (an_loop_info[ii].var); + an_loop_info[ii].ind_init = + build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR, + build_zero_cst (typ), tf_warning_or_error); + } array_operand = create_array_refs (location, an_info, an_loop_info, list_size, rank); replace_array_notations (&stmt, true, array_list, array_operand); create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error); an_init = pop_stmt_list (an_init); - append_to_statement_list_force (an_init, &loop_with_init); + append_to_statement_list (an_init, &loop_with_init); body = stmt; for (ii = 0; ii < rank; ii++) @@ -1063,7 +993,7 @@ cp_expand_cond_array_notations (tree orig_stmt) an_loop_info[ii].incr, body); body = pop_stmt_list (new_loop); } - append_to_statement_list_force (body, &loop_with_init); + append_to_statement_list (body, &loop_with_init); an_info.release (); an_loop_info.release (); @@ -1108,14 +1038,14 @@ expand_unary_array_notation_exprs (tree orig_stmt) { vec *sub_list = NULL, *new_var_list = NULL; stmt = alloc_stmt_list (); - append_to_statement_list_force (builtin_loop, &stmt); + append_to_statement_list (builtin_loop, &stmt); vec_safe_push (sub_list, list_node); vec_safe_push (new_var_list, new_var); replace_array_notations (&orig_stmt, false, sub_list, new_var_list); } } if (stmt != NULL_TREE) - append_to_statement_list_force (finish_expr_stmt (orig_stmt), &stmt); + append_to_statement_list (finish_expr_stmt (orig_stmt), &stmt); else stmt = orig_stmt; rank = 0; @@ -1135,22 +1065,19 @@ expand_unary_array_notation_exprs (tree orig_stmt) for (ii = 0; ii < list_size; ii++) { tree array_node = (*array_list)[ii]; - make_triplet_val_inv (location, &ARRAY_NOTATION_START (array_node), - tf_warning_or_error); - make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (array_node), - tf_warning_or_error); - make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (array_node), - tf_warning_or_error); + make_triplet_val_inv (&ARRAY_NOTATION_START (array_node)); + make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (array_node)); + make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (array_node)); } cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info); for (ii = 0; ii < rank; ii++) { - an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - TREE_TYPE (an_info[0][ii].start)); + tree typ = ptrdiff_type_node; + an_loop_info[ii].var = create_temporary_var (typ); + add_decl_expr (an_loop_info[ii].var); an_loop_info[ii].ind_init = build_x_modify_expr - (location, an_loop_info[ii].var, NOP_EXPR, - build_zero_cst (TREE_TYPE (an_loop_info[ii].var)), + (location, an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ), tf_warning_or_error); } array_operand = create_array_refs (location, an_info, an_loop_info, @@ -1159,7 +1086,7 @@ expand_unary_array_notation_exprs (tree orig_stmt) create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error); an_init = pop_stmt_list (an_init); - append_to_statement_list_force (an_init, &loop_with_init); + append_to_statement_list (an_init, &loop_with_init); body = stmt; for (ii = 0; ii < rank; ii++) @@ -1169,7 +1096,7 @@ expand_unary_array_notation_exprs (tree orig_stmt) an_loop_info[ii].incr, body); body = pop_stmt_list (new_loop); } - append_to_statement_list_force (body, &loop_with_init); + append_to_statement_list (body, &loop_with_init); an_info.release (); an_loop_info.release (); @@ -1190,16 +1117,18 @@ expand_return_expr (tree expr) return expr; location_t loc = EXPR_LOCATION (expr); - new_mod_list = alloc_stmt_list (); + new_mod_list = push_stmt_list (); retval_expr = TREE_OPERAND (expr, 0); - new_var = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE (retval_expr)); + new_var = get_temp_regvar (TREE_TYPE (retval_expr), + build_zero_cst (TREE_TYPE (retval_expr))); new_mod = expand_an_in_modify_expr (loc, new_var, NOP_EXPR, - TREE_OPERAND (retval_expr, 1), - tf_warning_or_error); + TREE_OPERAND (retval_expr, 1), + tf_warning_or_error); TREE_OPERAND (retval_expr, 1) = new_var; TREE_OPERAND (expr, 0) = retval_expr; - append_to_statement_list_force (new_mod, &new_mod_list); - append_to_statement_list_force (expr, &new_mod_list); + add_stmt (new_mod); + add_stmt (expr); + new_mod_list = pop_stmt_list (new_mod_list); return new_mod_list; } @@ -1336,19 +1265,21 @@ expand_array_notation_exprs (tree t) else t = expand_array_notation_exprs (t); return t; - - case SWITCH_EXPR: - t = cp_expand_cond_array_notations (t); - if (TREE_CODE (t) == SWITCH_EXPR) - SWITCH_BODY (t) = expand_array_notation_exprs (SWITCH_BODY (t)); - else - t = expand_array_notation_exprs (t); - return t; - case FOR_STMT: + case FOR_STMT: + if (contains_array_notation_expr (FOR_COND (t))) + { + error_at (EXPR_LOCATION (FOR_COND (t)), + "array notation cannot be used in a condition for " + "a for-loop"); + return error_mark_node; + } /* FIXME: Add a check for CILK_FOR_STMT here when we add Cilk tasking keywords. */ if (TREE_CODE (t) == FOR_STMT) - FOR_BODY (t) = expand_array_notation_exprs (FOR_BODY (t)); + { + FOR_BODY (t) = expand_array_notation_exprs (FOR_BODY (t)); + FOR_EXPR (t) = expand_array_notation_exprs (FOR_EXPR (t)); + } else t = expand_array_notation_exprs (t); return t; @@ -1368,6 +1299,13 @@ expand_array_notation_exprs (tree t) t = expand_array_notation_exprs (t); return t; case SWITCH_STMT: + if (contains_array_notation_expr (SWITCH_STMT_COND (t))) + { + error_at (EXPR_LOCATION (SWITCH_STMT_COND (t)), + "array notation cannot be used as a condition for " + "switch statement"); + return error_mark_node; + } t = cp_expand_cond_array_notations (t); /* If the above function added some extra instructions above the original switch statement, then we can't assume it is still SWITCH_STMT so we @@ -1382,6 +1320,14 @@ expand_array_notation_exprs (tree t) t = expand_array_notation_exprs (t); return t; case WHILE_STMT: + if (contains_array_notation_expr (WHILE_COND (t))) + { + if (EXPR_LOCATION (WHILE_COND (t)) != UNKNOWN_LOCATION) + loc = EXPR_LOCATION (WHILE_COND (t)); + error_at (loc, "array notation cannot be used as a condition for " + "while statement"); + return error_mark_node; + } t = cp_expand_cond_array_notations (t); /* If the above function added some extra instructions above the original while statement, then we can't assume it is still WHILE_STMTso we @@ -1395,6 +1341,13 @@ expand_array_notation_exprs (tree t) t = expand_array_notation_exprs (t); return t; case DO_STMT: + if (contains_array_notation_expr (DO_COND (t))) + { + error_at (EXPR_LOCATION (DO_COND (t)), + "array notation cannot be used as a condition for a " + "do-while statement"); + return error_mark_node; + } t = cp_expand_cond_array_notations (t); /* If the above function added some extra instructions above the original do-while statement, then we can't assume it is still DO_STMT so we @@ -1508,20 +1461,9 @@ cilkplus_an_triplet_types_ok_p (location_t loc, tree start_index, tree length, } if (!TREE_CODE (type) == FUNCTION_TYPE) { - error_at (loc, "array notations cannot be used with function type"); + error_at (loc, "array notation cannot be used with function type"); return false; } - while (type && (TREE_CODE (type) == POINTER_TYPE - || TREE_CODE (type) == ARRAY_TYPE)) - { - type = TREE_TYPE (type); - if (type && TREE_CODE (type) == FUNCTION_TYPE) - { - error_at (loc, "array notations cannot be used with function pointer" - " arrays"); - return false; - } - } if (!find_rank (loc, start_index, start_index, false, &start_rank) || !find_rank (loc, length, length, false, &length_rank) || !find_rank (loc, stride, stride, false, &stride_rank)) diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 38ef878..590d857 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -1207,6 +1207,12 @@ cp_genericize (tree fndecl) if (DECL_CLONED_FUNCTION_P (fndecl)) return; + /* Expand all the array notations here. */ + if (flag_enable_cilkplus + && contains_array_notation_expr (DECL_SAVED_TREE (fndecl))) + DECL_SAVED_TREE (fndecl) = + expand_array_notation_exprs (DECL_SAVED_TREE (fndecl)); + /* We do want to see every occurrence of the parms, so we can't just use walk_tree's hash functionality. */ cp_genericize_tree (&DECL_SAVED_TREE (fndecl)); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index f3bc27a..bb5a13d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6062,10 +6062,10 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* This function parses Cilk Plus array notations. The starting index is passed in INIT_INDEX and the array name is passed in ARRAY_VALUE. If the - INIT_INDEX is NULL, then we have special case were the entire array is + INIT_INDEX is NULL, then we have special case where the entire array is accessed (e.g. A[:]). The return value of this function is a tree node - called VALUE_TREE of type ARRAY_NOTATION_REF. If some error occurred it - returns error_mark_node. */ + of type ARRAY_NOTATION_REF. If some error occurred it returns + error_mark_node. */ static tree cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, @@ -6074,8 +6074,6 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, cp_token *token = NULL; tree start_index = NULL_TREE, length_index = NULL_TREE, stride = NULL_TREE; tree value_tree, type, array_type, array_type_domain; - double_int x; - bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; if (!array_value || array_value == error_mark_node) { @@ -6117,44 +6115,24 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, || TREE_CODE (array_type) == POINTER_TYPE) { error_at (loc, "start-index and length fields necessary for " - "using array notations in pointers or records"); + "using array notation in pointers or records"); cp_parser_skip_to_end_of_statement (parser); return error_mark_node; } - if (TREE_CODE (array_type) == ARRAY_TYPE) - { - tree subtype = TREE_TYPE (array_type); - while (subtype && TREE_CODE (subtype) == POINTER_TYPE) - { - /* This could be a function ptr. If so, then emit error. */ - subtype = TREE_TYPE (subtype); - if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE) - { - error_at (loc, "array notations cannot be used with" - " function pointer arrays"); - cp_parser_skip_to_end_of_statement (parser); - return error_mark_node; - } - } - } array_type_domain = TYPE_DOMAIN (array_type); if (!array_type_domain) { error_at (loc, "start-index and length fields necessary for " - "using array notations in dimensionless arrays"); + "using array notation with array of unknown bound"); cp_parser_skip_to_end_of_statement (parser); return error_mark_node; } start_index = TYPE_MINVAL (array_type_domain); - start_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, - start_index); - x = TREE_INT_CST (TYPE_MAXVAL (array_type_domain)); - x.low++; - length_index = double_int_to_tree (integer_type_node, x); - length_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, - length_index); - stride = build_int_cst (integer_type_node, 1); - stride = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, stride); + start_index = cp_fold_convert (ptrdiff_type_node, start_index); + length_index = size_binop + (PLUS_EXPR, TYPE_MAXVAL (array_type_domain), size_one_node); + length_index = cp_fold_convert (ptrdiff_type_node, length_index); + stride = build_int_cst (ptrdiff_type_node, 1); } else if (init_index != error_mark_node) { @@ -6165,12 +6143,12 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, start_index = init_index; cp_lexer_consume_token (parser->lexer); - saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; + bool saved_colon_corrects_to_scope_p = + parser->colon_corrects_to_scope_p; /* The ':' is used in array notation. Thus compiler cannot do scope correction automatically. */ parser->colon_corrects_to_scope_p = false; length_index = cp_parser_expression (parser, false, NULL); - parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; if (!length_index || length_index == error_mark_node) cp_parser_skip_to_end_of_statement (parser); @@ -6180,7 +6158,6 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; /* Disable correcting single colon correcting to scope. */ - parser->colon_corrects_to_scope_p = false; stride = cp_parser_expression (parser, false, NULL); parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; @@ -6211,13 +6188,7 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, return error_mark_node; } cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); - - /* We fold all 3 of the values to make things easier when we transform - them later. */ - start_index = fold (start_index); - length_index = fold (length_index); - stride = fold (stride); - + value_tree = build_array_notation_ref (input_location, array_value, start_index, length_index, stride, type); @@ -6248,8 +6219,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, if (flag_enable_cilkplus && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON) /* If we are here, then we have something like this: - ARRAY[:] - */ + ARRAY[:] */ postfix_expression = cp_parser_array_notation (loc, parser, NULL_TREE, postfix_expression); else @@ -6259,8 +6229,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, 2. ARRAY[EXPR : EXPR] -- Array notation expr with default stride of 1. 3. ARRAY[EXPR : EXPR : EXPR] -- Array Notation with userdefined stride. - 4. Array[Braced List] -- This is handled by braced list. - */ + 4. Array[Braced List] -- This is handled by braced list. */ /* Parse the index expression. */ /* ??? For offsetof, there is a question of what to allow here. If @@ -6288,7 +6257,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, { error_at (cp_lexer_peek_token (parser->lexer)->location, "braced list index is not allowed with array " - "notations"); + "notation"); index = error_mark_node; } } @@ -9550,9 +9519,6 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr, finish_compound_stmt (compound_stmt); /* Consume the `}'. */ cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); - - if (flag_enable_cilkplus && contains_array_notation_expr (compound_stmt)) - compound_stmt = expand_array_notation_exprs (compound_stmt); return compound_stmt; } @@ -9745,14 +9711,6 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p) /* Now we're all done with the switch-statement. */ finish_switch_stmt (statement); - if (flag_enable_cilkplus - && contains_array_notation_expr (condition)) - { - error_at (EXPR_LOCATION (condition), - "array notations cannot be used as a condition for " - "switch statement"); - statement = error_mark_node; - } } return statement; @@ -10310,12 +10268,6 @@ cp_parser_iteration_statement (cp_parser* parser) parser->in_statement = in_statement; /* We're done with the while-statement. */ finish_while_stmt (statement); - if (flag_enable_cilkplus && contains_array_notation_expr (condition)) - { - error_at (EXPR_LOCATION (condition), "array notations cannot be " - "used as a condition for while statement"); - statement = error_mark_node; - } } break; @@ -10342,15 +10294,6 @@ cp_parser_iteration_statement (cp_parser* parser) cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Look for the `;'. */ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); - if (flag_enable_cilkplus - && contains_array_notation_expr (DO_COND (statement))) - { - error_at (EXPR_LOCATION (DO_COND (statement)), - "array notations cannot be used as a condition for a " - "do-while statement"); - statement = error_mark_node; - } - } break; @@ -10367,19 +10310,10 @@ cp_parser_iteration_statement (cp_parser* parser) /* Parse the body of the for-statement. */ parser->in_statement = IN_ITERATION_STMT; cp_parser_already_scoped_statement (parser); - parser->in_statement = in_statement; + parser->in_statement = in_statement; - if (flag_enable_cilkplus - && contains_array_notation_expr (FOR_COND (statement))) - { - error_at (EXPR_LOCATION (FOR_COND (statement)), - "array notations cannot be used in a condition for a " - "for-loop"); - statement = error_mark_node; - } - else - /* We're done with the for-statement. */ - finish_for_stmt (statement); + /* We're done with the for-statement. */ + finish_for_stmt (statement); } break; @@ -16953,54 +16887,30 @@ cp_parser_direct_declarator (cp_parser* parser, if (token->type != CPP_CLOSE_SQUARE) { bool non_constant_p; - - if (flag_enable_cilkplus - && cp_lexer_next_token_is (parser->lexer, CPP_COLON)) + bounds + = cp_parser_constant_expression (parser, + /*allow_non_constant=*/true, + &non_constant_p); + if (!non_constant_p) + /* OK */; + else if (error_operand_p (bounds)) + /* Already gave an error. */; + else if (!parser->in_function_body + || current_binding_level->kind == sk_function_parms) { + /* Normally, the array bound must be an integral constant + expression. However, as an extension, we allow VLAs + in function scopes as long as they aren't part of a + parameter declaration. */ + cp_parser_error (parser, + "array bound is not an integer constant"); bounds = error_mark_node; - error_at (cp_lexer_peek_token (parser->lexer)->location, - "array notations cannot be used in declaration"); - cp_lexer_consume_token (parser->lexer); } - else + else if (processing_template_decl) { - bounds - = cp_parser_constant_expression (parser, - /*allow_non_constant=*/true, - &non_constant_p); - if (!non_constant_p) - /* OK */; - else if (error_operand_p (bounds)) - /* Already gave an error. */; - else if (!parser->in_function_body - || current_binding_level->kind == sk_function_parms) - { - /* Normally, the array bound must be an integral constant - expression. However, as an extension, we allow VLAs - in function scopes as long as they aren't part of a - parameter declaration. */ - cp_parser_error (parser, - "array bound is not an integer constant"); - bounds = error_mark_node; - } - else if (processing_template_decl) - { - /* Remember this wasn't a constant-expression. */ - bounds = build_nop (TREE_TYPE (bounds), bounds); - TREE_SIDE_EFFECTS (bounds) = 1; - } - if (flag_enable_cilkplus - && cp_lexer_next_token_is (parser->lexer, CPP_COLON)) - { - location_t loc = - cp_lexer_peek_token (parser->lexer)->location; - while (cp_lexer_next_token_is_not (parser->lexer, - CPP_CLOSE_SQUARE)) - cp_lexer_consume_token (parser->lexer); - error_at (loc, "array notations cannot be used in " - "declaration"); - bounds = error_mark_node; - } + /* Remember this wasn't a constant-expression. */ + bounds = build_nop (TREE_TYPE (bounds), bounds); + TREE_SIDE_EFFECTS (bounds) = 1; } } else @@ -18372,10 +18282,6 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser, if (check_body_p) check_constexpr_ctor_body (last, list); - /* Transform all array notations to the equivalent array refs and loop. */ - if (flag_enable_cilkplus && contains_array_notation_expr (body)) - body = expand_array_notation_exprs (body); - /* Finish the function body. */ finish_function_body (body); @@ -22355,12 +22261,6 @@ cp_parser_function_definition_after_declarator (cp_parser* parser, finish_lambda_scope (); - /* Expand all array notation expressions here. */ - if (flag_enable_cilkplus && current_function_decl - && contains_array_notation_expr (DECL_SAVED_TREE (current_function_decl))) - DECL_SAVED_TREE (current_function_decl) = - expand_array_notation_exprs (DECL_SAVED_TREE (current_function_decl)); - /* Finish the function. */ fn = finish_function ((ctor_initializer_p ? 1 : 0) | (inline_p ? 2 : 0)); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 667e37f..5dafdcd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -15739,9 +15739,6 @@ type_unification_real (tree tparms, arg = args[ia]; ++ia; - if (flag_enable_cilkplus && TREE_CODE (arg) == ARRAY_NOTATION_REF) - return 1; - if (unify_one_argument (tparms, targs, parm, arg, subr, strict, flags, explain_p)) return 1; @@ -19143,11 +19140,6 @@ instantiate_decl (tree d, int defer_ok, pointer_map_destroy (local_specializations); local_specializations = saved_local_specializations; - /* We expand all the array notation expressions here. */ - if (flag_enable_cilkplus - && contains_array_notation_expr (DECL_SAVED_TREE (d))) - DECL_SAVED_TREE (d) = expand_array_notation_exprs (DECL_SAVED_TREE (d)); - /* Finish the function. */ d = finish_function (0); expand_or_defer_fn (d); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0a460a4..db81b44 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8089,7 +8089,6 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t, non_constant_p, overflow_p); break; - case ARRAY_NOTATION_REF: case ARRAY_REF: r = cxx_eval_array_reference (call, t, allow_non_constant, addr, non_constant_p, overflow_p); @@ -8901,7 +8900,6 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) want_rval = true; /* Fall through. */ case ARRAY_REF: - case ARRAY_NOTATION_REF: case ARRAY_RANGE_REF: case MEMBER_REF: case DOTSTAR_EXPR: @@ -8912,6 +8910,9 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) return false; return true; + case ARRAY_NOTATION_REF: + return false; + case FMA_EXPR: case VEC_PERM_EXPR: for (i = 0; i < 3; ++i) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9940868..5594687 100644 Binary files a/gcc/testsuite/ChangeLog and b/gcc/testsuite/ChangeLog differ diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c index 68c8859..4b54f4d 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c @@ -1,3 +1,4 @@ +/* { dg-do compile { target c } } */ /* { dg-options "-fcilkplus" } */ int main(void) diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c index 69aaa52..690e89a 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c @@ -5,6 +5,6 @@ extern int *b; void foo() { - a[:] = 5; // { dg-error "start-index and length fields necessary for using array notations in dimensionless arrays" } - b[:] = 5; // { dg-error "start-index and length fields necessary for using array notations in pointers" } + a[:] = 5; // { dg-error "start-index and length fields necessary for using array notation" } + b[:] = 5; // { dg-error "start-index and length fields necessary for using" } } diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c index 024a158..fa6d900 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c @@ -1,3 +1,4 @@ +/* { dg-do compile } */ /* { dg-options "-fcilkplus" } */ typedef int (*foo)(int); @@ -10,11 +11,11 @@ int main(void) foo ***func_array_ptr; int argc = 5; - array[:] = func_array[:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */ - func_array[0:5](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */ - func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */ - array2[0:5][:] = func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */ - func_array_ptr[0:5][0:4][0:argc:2](argc); /* { dg-error "array notations cannot be used with function pointer arrays" } */ + array[:] = func_array[:](10); + func_array[0:5](10); + func_array2[0:5][:](10); + array2[0:5][:] = func_array2[0:5][:](10); + func_array_ptr[0:5][0:4][0:argc:2](argc); return 0; } diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c index 14421d9..814786b 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c @@ -6,7 +6,7 @@ int main (void) int array[10], array2[10][10]; int x, ii, jj ; - switch (array[:]) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */ + switch (array[:]) { /* { dg-error "cannot be used as a condition for switch statement" } */ case 1: x = 5; break; @@ -17,7 +17,7 @@ int main (void) x = 9; } - switch (array2[:][:]) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */ + switch (array2[:][:]) { /* { dg-error "cannot be used as a condition for switch statement" } */ case 1: x = 5; break; @@ -28,7 +28,7 @@ int main (void) x = 9; } - switch (array[:] + x) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */ + switch (array[:] + x) { /* { dg-error "cannot be used as a condition for switch statement" } */ case 1: x = 5; break; @@ -39,7 +39,7 @@ int main (void) x = 9; } - switch (array2[:][1:x:4] + x) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */ + switch (array2[:][1:x:4] + x) { /* { dg-error "cannot be used as a condition for switch statement" } */ case 1: x = 5; break; @@ -50,36 +50,36 @@ int main (void) x = 9; } - for (ii = 0; ii < array[:]; ii++) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */ + for (ii = 0; ii < array[:]; ii++) /* { dg-error "cannot be used in a condition for a for-loop" } */ { x = 2; } - for (ii = 0; ii < array2[:][:]; ii++) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */ + for (ii = 0; ii < array2[:][:]; ii++) /* { dg-error "cannot be used in a condition for a for-loop" } */ { x = 3; } - for (; array2[:][:] < 2;) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */ + for (; array2[:][:] < 2;) /* { dg-error "cannot be used in a condition for a for-loop" } */ x = 4; - while (array2[:][:]) /* { dg-error "array notations cannot be used as a condition for while statement" } */ + while (array2[:][:]) /* { dg-error "cannot be used as a condition for while statement" } */ x = 3; - while (array[1:1:1]) /* { dg-error "array notations cannot be used as a condition for while statement" } */ + while (array[1:1:1]) /* { dg-error "cannot be used as a condition for while statement" } */ x = 1; - while (ii != array2[1:x:3][1:2:1]) /* { dg-error "array notations cannot be used as a condition for while statement" } */ + while (ii != array2[1:x:3][1:2:1]) /* { dg-error "cannot be used as a condition for while statement" } */ x = 2; - do { /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c } } */ + do { /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c } } */ x = 3; - } while (ii != array2[:][:]); /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c++ } } */ + } while (ii != array2[:][:]); /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c++ } } */ - do { /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c } } */ + do { /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c } } */ x = 2; - } while (ii != (x + array2[:][1:x:2]) + 2); /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c++ } } */ + } while (ii != (x + array2[:][1:x:2]) + 2); /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c++ } } */ do { x += 3; diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c index b5e37ce..eb3c1f1 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c @@ -10,6 +10,7 @@ int main (void) int array[10][10], array2[10]; array[:][:] = array[:]; /* { dg-error "rank mismatch between" } */ + /* { dg-error "invalid conversion" "" { target c++ } 12 } */ x = array2[:]; /* { dg-error "cannot be scalar when" } */