From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6736 invoked by alias); 18 Apr 2013 12:53:46 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 6725 invoked by uid 89); 18 Apr 2013 12:53:46 -0000 X-Spam-SWARE-Status: No, score=-5.8 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,TW_TM autolearn=ham version=3.3.1 Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 18 Apr 2013 12:53:45 +0000 Received: from relay1.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 0DB2DA5230 for ; Thu, 18 Apr 2013 14:53:43 +0200 (CEST) Date: Thu, 18 Apr 2013 14:16:00 -0000 From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] More vectorizer TLC Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-SW-Source: 2013-04/txt/msg01091.txt.bz2 While trying to remove some restrictions I came along more TLC opportunities. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2013-04-18 Richard Biener * tree-vect-data-refs.c (vect_analyze_group_access): Properly handle negative step. Remove redundant checks. (vect_create_data_ref_ptr): Avoid ICEs with non-constant steps. * tree-vect-stmts.c (vectorizable_load): Instead of asserting for negative step and grouped loads fail to vectorize. Index: gcc/tree-vect-data-refs.c =================================================================== *** gcc/tree-vect-data-refs.c.orig 2013-04-18 12:17:03.000000000 +0200 --- gcc/tree-vect-data-refs.c 2013-04-18 12:17:14.430103903 +0200 *************** vect_analyze_group_access (struct data_r *** 2024,2030 **** /* For interleaving, GROUPSIZE is STEP counted in elements, i.e., the size of the interleaving group (including gaps). */ ! groupsize = dr_step / type_size; /* Not consecutive access is possible only if it is a part of interleaving. */ if (!GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt))) --- 2024,2030 ---- /* For interleaving, GROUPSIZE is STEP counted in elements, i.e., the size of the interleaving group (including gaps). */ ! groupsize = absu_hwi (dr_step) / type_size; /* Not consecutive access is possible only if it is a part of interleaving. */ if (!GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt))) *************** vect_analyze_group_access (struct data_r *** 2094,2103 **** gimple next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (stmt)); struct data_reference *data_ref = dr; unsigned int count = 1; - tree next_step; tree prev_init = DR_INIT (data_ref); gimple prev = stmt; ! HOST_WIDE_INT diff, count_in_bytes, gaps = 0; while (next) { --- 2094,2103 ---- gimple next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (stmt)); struct data_reference *data_ref = dr; unsigned int count = 1; tree prev_init = DR_INIT (data_ref); gimple prev = stmt; ! HOST_WIDE_INT diff, gaps = 0; ! unsigned HOST_WIDE_INT count_in_bytes; while (next) { *************** vect_analyze_group_access (struct data_r *** 2126,2143 **** } prev = next; ! /* Check that all the accesses have the same STEP. */ ! next_step = DR_STEP (STMT_VINFO_DATA_REF (vinfo_for_stmt (next))); ! if (tree_int_cst_compare (step, next_step)) ! { ! if (dump_enabled_p ()) ! dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ! "not consecutive access in interleaving"); ! return false; ! } - data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next)); /* Check that the distance between two accesses is equal to the type size. Otherwise, we have gaps. */ diff = (TREE_INT_CST_LOW (DR_INIT (data_ref)) --- 2126,2136 ---- } prev = next; + data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next)); ! /* All group members have the same STEP by construction. */ ! gcc_checking_assert (operand_equal_p (DR_STEP (data_ref), step, 0)); /* Check that the distance between two accesses is equal to the type size. Otherwise, we have gaps. */ diff = (TREE_INT_CST_LOW (DR_INIT (data_ref)) *************** vect_analyze_group_access (struct data_r *** 2175,2181 **** /* Check that the size of the interleaving (including gaps) is not greater than STEP. */ ! if (dr_step && dr_step < count_in_bytes + gaps * type_size) { if (dump_enabled_p ()) { --- 2168,2175 ---- /* Check that the size of the interleaving (including gaps) is not greater than STEP. */ ! if (dr_step != 0 ! && absu_hwi (dr_step) < count_in_bytes + gaps * type_size) { if (dump_enabled_p ()) { *************** vect_analyze_group_access (struct data_r *** 2188,2194 **** /* Check that the size of the interleaving is equal to STEP for stores, i.e., that there are no gaps. */ ! if (dr_step && dr_step != count_in_bytes) { if (DR_IS_READ (dr)) { --- 2182,2189 ---- /* Check that the size of the interleaving is equal to STEP for stores, i.e., that there are no gaps. */ ! if (dr_step != 0 ! && absu_hwi (dr_step) != count_in_bytes) { if (DR_IS_READ (dr)) { *************** vect_analyze_group_access (struct data_r *** 2208,2214 **** } /* Check that STEP is a multiple of type size. */ ! if (dr_step && (dr_step % type_size) != 0) { if (dump_enabled_p ()) { --- 2203,2210 ---- } /* Check that STEP is a multiple of type size. */ ! if (dr_step != 0 ! && (dr_step % type_size) != 0) { if (dump_enabled_p ()) { *************** vect_create_data_ref_ptr (gimple stmt, t *** 3520,3526 **** tree aptr; gimple_stmt_iterator incr_gsi; bool insert_after; - bool negative; tree indx_before_incr, indx_after_incr; gimple incr; tree step; --- 3520,3525 ---- *************** vect_create_data_ref_ptr (gimple stmt, t *** 3550,3560 **** else step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info)); ! if (tree_int_cst_compare (step, size_zero_node) == 0) *inv_p = true; else *inv_p = false; - negative = tree_int_cst_compare (step, size_zero_node) < 0; /* Create an expression for the first address accessed by this load in LOOP. */ --- 3549,3558 ---- else step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info)); ! if (integer_zerop (step)) *inv_p = true; else *inv_p = false; /* Create an expression for the first address accessed by this load in LOOP. */ *************** vect_create_data_ref_ptr (gimple stmt, t *** 3693,3710 **** else { /* The step of the aggregate pointer is the type size. */ ! tree step = TYPE_SIZE_UNIT (aggr_type); /* One exception to the above is when the scalar step of the load in LOOP is zero. In this case the step here is also zero. */ if (*inv_p) ! step = size_zero_node; ! else if (negative) ! step = fold_build1 (NEGATE_EXPR, TREE_TYPE (step), step); standard_iv_increment_position (loop, &incr_gsi, &insert_after); create_iv (aggr_ptr_init, ! fold_convert (aggr_ptr_type, step), aggr_ptr, loop, &incr_gsi, insert_after, &indx_before_incr, &indx_after_incr); incr = gsi_stmt (incr_gsi); --- 3691,3708 ---- else { /* The step of the aggregate pointer is the type size. */ ! tree iv_step = TYPE_SIZE_UNIT (aggr_type); /* One exception to the above is when the scalar step of the load in LOOP is zero. In this case the step here is also zero. */ if (*inv_p) ! iv_step = size_zero_node; ! else if (tree_int_cst_sgn (step) == -1) ! iv_step = fold_build1 (NEGATE_EXPR, TREE_TYPE (iv_step), iv_step); standard_iv_increment_position (loop, &incr_gsi, &insert_after); create_iv (aggr_ptr_init, ! fold_convert (aggr_ptr_type, iv_step), aggr_ptr, loop, &incr_gsi, insert_after, &indx_before_incr, &indx_after_incr); incr = gsi_stmt (incr_gsi); Index: gcc/tree-vect-stmts.c =================================================================== *** gcc/tree-vect-stmts.c.orig 2013-04-18 12:17:03.000000000 +0200 --- gcc/tree-vect-stmts.c 2013-04-18 12:18:47.745157947 +0200 *************** vectorizable_load (gimple stmt, gimple_s *** 4465,4471 **** if (negative) { ! gcc_assert (!grouped_load); alignment_support_scheme = vect_supportable_dr_alignment (dr, false); if (alignment_support_scheme != dr_aligned && alignment_support_scheme != dr_unaligned_supported) --- 4479,4491 ---- if (negative) { ! if (grouped_load) ! { ! if (dump_enabled_p ()) ! dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ! "negative step for group load not supported"); ! return false; ! } alignment_support_scheme = vect_supportable_dr_alignment (dr, false); if (alignment_support_scheme != dr_aligned && alignment_support_scheme != dr_unaligned_supported)