From patchwork Mon Apr 14 14:45:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 338979 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 D663D1400BE for ; Tue, 15 Apr 2014 00:47:54 +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:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=DI+izp8VfQutH/ON fuLI/Mfl3BApEVQ2LXlOmnZnOUoQeI/7s50aI0n9wstqzoCXQ8QgXegc272TYSeT tUgngcsGuqgS2Gvb6X1ToSZaHe6LMTWyOaB6VMNQQDh8pJ3JVDUqlu+Sv4W0H8SI YpngCOoYdDIDDjEqgpfPk9PJen8= 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:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=BM/7gLOoImbt7ux3RkGbTB 3rLjI=; b=rHno/WQwwHmGxy4auw6QjTIAYKIDY/UBFsgobKmC4I4GxoSrsml4PS JNTUhD8rwQnAcueaEhXJBRKBH6UD2kM9duOpzlTwhJgn19laWz8ISb+PEr2suYJC CrOhqdG2kwIO0BCfF4pOkKQcR/bORQ8uFHvWhT/WJNZpRfElhX0kw= Received: (qmail 6695 invoked by alias); 14 Apr 2014 14:47:44 -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 6579 invoked by uid 89); 14 Apr 2014 14:47:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 14 Apr 2014 14:47:39 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 9774327201ED for ; Mon, 14 Apr 2014 16:47:36 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZUjkupProbN7 for ; Mon, 14 Apr 2014 16:47:36 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 5950027200A7 for ; Mon, 14 Apr 2014 16:47:36 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Add support for pragma Loop_Optimize ([No_]Vector) Date: Mon, 14 Apr 2014 16:45:06 +0200 Message-ID: <1411548.4VpsVizfpc@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.29-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 Hi, this adds support for 2 optimization hints pertaining to loops in Ada, namely Loop_Optimize (No_Vector) and Loop_Optimize (Vector), by reusing the Ivdep approach in the middle-end (ANNOTATE_EXPR node) and directly setting the dont_vectorize and force_vectorize bits of the 'loop' structure. Tested on x86_64-suse-linux, OK for the mainline? 2014-04-14 Eric Botcazou * cfgloop.h (struct loop): Move force_vectorize down. * gimplify.c (gimple_boolify) : Handle new kinds. (gimplify_expr) : Minor tweak. * lto-streamer-in.c (input_cfg): Read dont_vectorize field. * lto-streamer-out.c (output_cfg): Write dont_vectorize field. * tree-cfg.c (replace_loop_annotate): Revamp and handle new kinds. * tree-core.h (enum annot_expr_kind): Add new kind values. * tree-inline.c (copy_loops): Copy dont_vectorize field and reorder. * tree-pretty-print.c (dump_generic_node) : Handle new kinds. * tree.def (ANNOTATE_EXPR): Tweak comment. ada/ * gcc-interface/trans.c (gnat_gimplify_stmt): Propagate loop hints. 2014-04-14 Eric Botcazou * gnat.dg/vect12.ad[sb]: New test. * gnat.dg/vect13.ad[sb]: Likewise. Index: tree-pretty-print.c =================================================================== --- tree-pretty-print.c (revision 209334) +++ tree-pretty-print.c (working copy) @@ -2105,13 +2105,21 @@ dump_generic_node (pretty_printer *buffe case ANNOTATE_EXPR: pp_string (buffer, "ANNOTATE_EXPR <"); + dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (node, 1))) { case annot_expr_ivdep_kind: - pp_string (buffer, "ivdep, "); + pp_string (buffer, ", ivdep"); + break; + case annot_expr_no_vector_kind: + pp_string (buffer, ", no-vector"); break; + case annot_expr_vector_kind: + pp_string (buffer, ", vector"); + break; + default: + gcc_unreachable (); } - dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); pp_greater (buffer); break; Index: lto-streamer-out.c =================================================================== --- lto-streamer-out.c (revision 209362) +++ lto-streamer-out.c (working copy) @@ -1693,6 +1693,7 @@ output_cfg (struct output_block *ob, str /* Write OMP SIMD related info. */ streamer_write_hwi (ob, loop->safelen); + streamer_write_hwi (ob, loop->dont_vectorize); streamer_write_hwi (ob, loop->force_vectorize); stream_write_tree (ob, loop->simduid, true); } Index: ada/gcc-interface/trans.c =================================================================== --- ada/gcc-interface/trans.c (revision 209375) +++ ada/gcc-interface/trans.c (working copy) @@ -7761,6 +7761,15 @@ gnat_gimplify_stmt (tree *stmt_p) build_int_cst (integer_type_node, annot_expr_ivdep_kind)); + if (LOOP_STMT_NO_VECTOR (stmt)) + gnu_cond = build2 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond, + build_int_cst (integer_type_node, + annot_expr_no_vector_kind)); + if (LOOP_STMT_VECTOR (stmt)) + gnu_cond = build2 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond, + build_int_cst (integer_type_node, + annot_expr_vector_kind)); + gnu_cond = build3 (COND_EXPR, void_type_node, gnu_cond, NULL_TREE, build1 (GOTO_EXPR, void_type_node, gnu_end_label)); Index: lto-streamer-in.c =================================================================== --- lto-streamer-in.c (revision 209362) +++ lto-streamer-in.c (working copy) @@ -718,6 +718,7 @@ input_cfg (struct lto_input_block *ib, s /* Read OMP SIMD related info. */ loop->safelen = streamer_read_hwi (ib); + loop->dont_vectorize = streamer_read_hwi (ib); loop->force_vectorize = streamer_read_hwi (ib); loop->simduid = stream_read_tree (ib, data_in); Index: gimplify.c =================================================================== --- gimplify.c (revision 209334) +++ gimplify.c (working copy) @@ -2813,15 +2813,18 @@ gimple_boolify (tree expr) return expr; case ANNOTATE_EXPR: - if ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)) - == annot_expr_ivdep_kind) + switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1))) { + case annot_expr_ivdep_kind: + case annot_expr_no_vector_kind: + case annot_expr_vector_kind: TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); if (TREE_CODE (type) != BOOLEAN_TYPE) TREE_TYPE (expr) = boolean_type_node; return expr; + default: + gcc_unreachable (); } - /* FALLTHRU */ default: if (COMPARISON_CLASS_P (expr)) @@ -7528,7 +7531,7 @@ gimplify_expr (tree *expr_p, gimple_seq case ANNOTATE_EXPR: { tree cond = TREE_OPERAND (*expr_p, 0); - tree id = TREE_OPERAND (*expr_p, 1); + tree kind = TREE_OPERAND (*expr_p, 1); tree type = TREE_TYPE (cond); if (!INTEGRAL_TYPE_P (type)) { @@ -7538,8 +7541,8 @@ gimplify_expr (tree *expr_p, gimple_seq } tree tmp = create_tmp_var (type, NULL); gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p)); - gimple call = gimple_build_call_internal (IFN_ANNOTATE, 2, - cond, id); + gimple call + = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, kind); gimple_call_set_lhs (call, tmp); gimplify_seq_add_stmt (pre_p, call); *expr_p = tmp; Index: tree.def =================================================================== --- tree.def (revision 209334) +++ tree.def (working copy) @@ -1280,7 +1280,7 @@ DEFTREECODE (TARGET_OPTION_NODE, "target /* ANNOTATE_EXPR. Operand 0 is the expression to be annotated. - Operand 1 is the annotation id. */ + Operand 1 is the annotation kind. */ DEFTREECODE (ANNOTATE_EXPR, "annotate_expr", tcc_expression, 2) /* Cilk spawn statement Index: tree-inline.c =================================================================== --- tree-inline.c (revision 209362) +++ tree-inline.c (working copy) @@ -2349,17 +2349,18 @@ copy_loops (copy_body_data *id, place_new_loop (cfun, dest_loop); flow_loop_tree_node_add (dest_parent, dest_loop); - if (src_loop->simduid) - { - dest_loop->simduid = remap_decl (src_loop->simduid, id); - cfun->has_simduid_loops = true; - } + dest_loop->safelen = src_loop->safelen; + dest_loop->dont_vectorize = src_loop->dont_vectorize; if (src_loop->force_vectorize) { dest_loop->force_vectorize = true; cfun->has_force_vectorize_loops = true; } - dest_loop->safelen = src_loop->safelen; + if (src_loop->simduid) + { + dest_loop->simduid = remap_decl (src_loop->simduid, id); + cfun->has_simduid_loops = true; + } /* Recurse. */ copy_loops (id, dest_loop, src_loop); Index: cfgloop.h =================================================================== --- cfgloop.h (revision 209362) +++ cfgloop.h (working copy) @@ -173,12 +173,12 @@ struct GTY ((chain_next ("%h.next"))) lo of the loop can be safely evaluated concurrently. */ int safelen; - /* True if we should try harder to vectorize this loop. */ - bool force_vectorize; - /* True if this loop should never be vectorized. */ bool dont_vectorize; + /* True if we should try harder to vectorize this loop. */ + bool force_vectorize; + /* For SIMD loops, this is a unique identifier of the loop, referenced by IFN_GOMP_SIMD_VF, IFN_GOMP_SIMD_LANE and IFN_GOMP_SIMD_LAST_LANE builtins. */ Index: tree-core.h =================================================================== --- tree-core.h (revision 209334) +++ tree-core.h (working copy) @@ -657,7 +657,10 @@ enum tree_node_kind { }; enum annot_expr_kind { - annot_expr_ivdep_kind + annot_expr_ivdep_kind, + annot_expr_no_vector_kind, + annot_expr_vector_kind, + annot_expr_kind_last }; Index: tree-cfg.c =================================================================== --- tree-cfg.c (revision 209362) +++ tree-cfg.c (working copy) @@ -250,9 +250,9 @@ build_gimple_cfg (gimple_seq seq) } -/* Search for ANNOTATE call with annot_expr_ivdep_kind; if found, remove - it and set loop->safelen to INT_MAX. We assume that the annotation - comes immediately before the condition. */ +/* Look for ANNOTATE calls with loop annotation kind; if found, remove + them and propagate the information to the loop. We assume that the + annotations come immediately before the condition of the loop. */ static void replace_loop_annotate () @@ -266,50 +266,62 @@ replace_loop_annotate () { gsi = gsi_last_bb (loop->header); stmt = gsi_stmt (gsi); - if (stmt && gimple_code (stmt) == GIMPLE_COND) + if (!(stmt && gimple_code (stmt) == GIMPLE_COND)) + continue; + for (gsi_prev_nondebug (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi)) { - gsi_prev_nondebug (&gsi); - if (gsi_end_p (gsi)) - continue; stmt = gsi_stmt (gsi); if (gimple_code (stmt) != GIMPLE_CALL) - continue; + break; if (!gimple_call_internal_p (stmt) - || gimple_call_internal_fn (stmt) != IFN_ANNOTATE) - continue; - if ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)) - != annot_expr_ivdep_kind) - continue; + || gimple_call_internal_fn (stmt) != IFN_ANNOTATE) + break; + switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1))) + { + case annot_expr_ivdep_kind: + loop->safelen = INT_MAX; + break; + case annot_expr_no_vector_kind: + loop->dont_vectorize = true; + break; + case annot_expr_vector_kind: + loop->force_vectorize = true; + cfun->has_force_vectorize_loops = true; + break; + default: + gcc_unreachable (); + } stmt = gimple_build_assign (gimple_call_lhs (stmt), gimple_call_arg (stmt, 0)); gsi_replace (&gsi, stmt, true); - loop->safelen = INT_MAX; } } - /* Remove IFN_ANNOTATE. Safeguard for the case loop->latch == NULL. */ + /* Remove IFN_ANNOTATE. Safeguard for the case loop->latch == NULL. */ FOR_EACH_BB_FN (bb, cfun) { - gsi = gsi_last_bb (bb); - stmt = gsi_stmt (gsi); - if (stmt && gimple_code (stmt) == GIMPLE_COND) - gsi_prev_nondebug (&gsi); - if (gsi_end_p (gsi)) - continue; - stmt = gsi_stmt (gsi); - if (gimple_code (stmt) != GIMPLE_CALL) - continue; - if (!gimple_call_internal_p (stmt) - || gimple_call_internal_fn (stmt) != IFN_ANNOTATE) - continue; - if ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)) - != annot_expr_ivdep_kind) - continue; - warning_at (gimple_location (stmt), 0, "ignoring % " - "annotation"); - stmt = gimple_build_assign (gimple_call_lhs (stmt), - gimple_call_arg (stmt, 0)); - gsi_replace (&gsi, stmt, true); + for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi)) + { + stmt = gsi_stmt (gsi); + if (gimple_code (stmt) != GIMPLE_CALL) + break; + if (!gimple_call_internal_p (stmt) + || gimple_call_internal_fn (stmt) != IFN_ANNOTATE) + break; + switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1))) + { + case annot_expr_ivdep_kind: + case annot_expr_no_vector_kind: + case annot_expr_vector_kind: + break; + default: + gcc_unreachable (); + } + warning_at (gimple_location (stmt), 0, "ignoring loop annotation"); + stmt = gimple_build_assign (gimple_call_lhs (stmt), + gimple_call_arg (stmt, 0)); + gsi_replace (&gsi, stmt, true); + } } }