From patchwork Sun Oct 23 12:16:04 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Rosen X-Patchwork-Id: 4790 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 4A28B23E06 for ; Sun, 23 Oct 2011 12:16:14 +0000 (UTC) Received: from mail-ey0-f180.google.com (mail-ey0-f180.google.com [209.85.215.180]) by fiordland.canonical.com (Postfix) with ESMTP id 2A6CFA1890C for ; Sun, 23 Oct 2011 12:16:14 +0000 (UTC) Received: by eyg5 with SMTP id 5so6248471eyg.11 for ; Sun, 23 Oct 2011 05:16:14 -0700 (PDT) Received: by 10.223.58.146 with SMTP id g18mr10352967fah.13.1319372173848; Sun, 23 Oct 2011 05:16:13 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.1.71 with SMTP id 7cs31089lak; Sun, 23 Oct 2011 05:16:12 -0700 (PDT) Received: by 10.236.173.165 with SMTP id v25mr29899450yhl.22.1319372165935; Sun, 23 Oct 2011 05:16:05 -0700 (PDT) Received: from mail-gy0-f178.google.com (mail-gy0-f178.google.com [209.85.160.178]) by mx.google.com with ESMTPS id b70si16692515yhn.152.2011.10.23.05.16.04 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 23 Oct 2011 05:16:05 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.160.178 is neither permitted nor denied by best guess record for domain of ira.rosen@linaro.org) client-ip=209.85.160.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.160.178 is neither permitted nor denied by best guess record for domain of ira.rosen@linaro.org) smtp.mail=ira.rosen@linaro.org Received: by gyh4 with SMTP id 4so5619667gyh.37 for ; Sun, 23 Oct 2011 05:16:04 -0700 (PDT) MIME-Version: 1.0 Received: by 10.68.38.132 with SMTP id g4mr37599589pbk.122.1319372164165; Sun, 23 Oct 2011 05:16:04 -0700 (PDT) Received: by 10.142.63.7 with HTTP; Sun, 23 Oct 2011 05:16:04 -0700 (PDT) Date: Sun, 23 Oct 2011 14:16:04 +0200 Message-ID: Subject: [patch] SLP data dependence testing - PR 50819 From: Ira Rosen To: gcc-patches@gcc.gnu.org Cc: Patch Tracking Hi, When there is pair of data-refs with unknown dependence in basic block SLP we currently require all the loads in the basic block to be before all the stores in order to avoid load after store dependencies. But this is too conservative. It's enough to check that in the pairs of loads and stores with unknown and known dependence, the load comes first. This is already done for the known case. This patch adds such check for unknown dependencies and removes vect_bb_vectorizable_with_dependencies. Bootstrapped and tested on powerpc64-suse-linux. Committed. Ira ChangeLog: PR tree-optimization/50819 * tree-vectorizer.h (vect_analyze_data_ref_dependences): Remove the last argument. * tree-vect-loop.c (vect_analyze_loop_2): Update call to vect_analyze_data_ref_dependences. * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Remove the last argument. Check load-after-store dependence for unknown dependencies in basic blocks. (vect_analyze_data_ref_dependences): Update call to vect_analyze_data_ref_dependences. * tree-vect-patterns.c (vect_recog_widen_shift_pattern): Fix typo. * tree-vect-slp.c (vect_bb_vectorizable_with_dependencies): Remove. (vect_slp_analyze_bb_1): Update call to vect_analyze_data_ref_dependences. Don't call vect_bb_vectorizable_with_dependencies. testsuite/Changelog: PR tree-optimization/50819 * g++.dg/vect/vect.exp: Set target dependent flags for slp-* tests. * g++.dg/vect/slp-pr50819.cc: New test. Index: ChangeLog =================================================================== --- ChangeLog (revision 180333) +++ ChangeLog (working copy) @@ -1,3 +1,21 @@ +2011-10-23 Ira Rosen + + PR tree-optimization/50819 + * tree-vectorizer.h (vect_analyze_data_ref_dependences): Remove + the last argument. + * tree-vect-loop.c (vect_analyze_loop_2): Update call to + vect_analyze_data_ref_dependences. + * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Remove + the last argument. Check load-after-store dependence for unknown + dependencies in basic blocks. + (vect_analyze_data_ref_dependences): Update call to + vect_analyze_data_ref_dependences. + * tree-vect-patterns.c (vect_recog_widen_shift_pattern): Fix typo. + * tree-vect-slp.c (vect_bb_vectorizable_with_dependencies): Remove. + (vect_slp_analyze_bb_1): Update call to + vect_analyze_data_ref_dependences. Don't call + vect_bb_vectorizable_with_dependencies. + 2011-10-22 David S. Miller * config/sparc/sparc.h (SECONDARY_INPUT_RELOAD_CLASS, Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 180333) +++ testsuite/ChangeLog (working copy) @@ -1,3 +1,9 @@ +2011-10-23 Ira Rosen + + PR tree-optimization/50819 + * g++.dg/vect/vect.exp: Set target dependent flags for slp-* tests. + * g++.dg/vect/slp-pr50819.cc: New test. + 2011-10-21 Paolo Carlini PR c++/45385 Index: testsuite/g++.dg/vect/vect.exp =================================================================== --- testsuite/g++.dg/vect/vect.exp (revision 180333) +++ testsuite/g++.dg/vect/vect.exp (working copy) @@ -42,12 +42,6 @@ set DEFAULT_VECTCFLAGS "" # These flags are used for all targets. lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fno-vect-cost-model" -set VECT_SLP_CFLAGS $DEFAULT_VECTCFLAGS - -lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" -lappend VECT_SLP_CFLAGS "-fdump-tree-slp-details" - - # Skip these tests for targets that do not support generating vector # code. Set additional target-dependent vector flags, which can be # overridden by using dg-options in individual tests. @@ -55,6 +49,11 @@ if ![check_vect_support_and_set_flags] { return } +set VECT_SLP_CFLAGS $DEFAULT_VECTCFLAGS + +lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" +lappend VECT_SLP_CFLAGS "-fdump-tree-slp-details" + # Initialize `dg'. dg-init Index: testsuite/g++.dg/vect/slp-pr50819.cc =================================================================== --- testsuite/g++.dg/vect/slp-pr50819.cc (revision 0) +++ testsuite/g++.dg/vect/slp-pr50819.cc (revision 0) @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +typedef float Value; + +struct LorentzVector +{ + + LorentzVector(Value x=0, Value y=0, Value z=0, Value t=0) : +theX(x),theY(y),theZ(z),theT(t){} + LorentzVector & operator+=(const LorentzVector & a) { + theX += a.theX; + theY += a.theY; + theZ += a.theZ; + theT += a.theT; + return *this; + } + + Value theX; + Value theY; + Value theZ; + Value theT; +} __attribute__ ((aligned(16))); + +inline LorentzVector +operator+(LorentzVector const & a, LorentzVector const & b) { + return +LorentzVector(a.theX+b.theX,a.theY+b.theY,a.theZ+b.theZ,a.theT+b.theT); +} + +inline LorentzVector +operator*(LorentzVector const & a, Value s) { + return LorentzVector(a.theX*s,a.theY*s,a.theZ*s,a.theT*s); +} + +inline LorentzVector +operator*(Value s, LorentzVector const & a) { + return a*s; +} + + +void sum1(LorentzVector & res, Value s, LorentzVector const & v1, LorentzVector +const & v2) { + res += s*(v1+v2); +} + +void sum2(LorentzVector & res, Value s, LorentzVector const & v1, LorentzVector +const & v2) { + res = res + s*(v1+v2); +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 2 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ Index: tree-vectorizer.h =================================================================== --- tree-vectorizer.h (revision 180333) +++ tree-vectorizer.h (working copy) @@ -832,7 +832,7 @@ extern enum dr_alignment_support vect_supportable_ extern tree vect_get_smallest_scalar_type (gimple, HOST_WIDE_INT *, HOST_WIDE_INT *); extern bool vect_analyze_data_ref_dependences (loop_vec_info, bb_vec_info, - int *, bool *); + int *); extern bool vect_enhance_data_refs_alignment (loop_vec_info); extern bool vect_analyze_data_refs_alignment (loop_vec_info, bb_vec_info); extern bool vect_verify_datarefs_alignment (loop_vec_info, bb_vec_info); Index: tree-vect-loop.c =================================================================== --- tree-vect-loop.c (revision 180333) +++ tree-vect-loop.c (working copy) @@ -1473,7 +1473,7 @@ vect_analyze_loop_operations (loop_vec_info loop_v static bool vect_analyze_loop_2 (loop_vec_info loop_vinfo) { - bool ok, dummy, slp = false; + bool ok, slp = false; int max_vf = MAX_VECTORIZATION_FACTOR; int min_vf = 2; @@ -1514,7 +1514,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) the dependences. FORNOW: fail at the first data dependence that we encounter. */ - ok = vect_analyze_data_ref_dependences (loop_vinfo, NULL, &max_vf, &dummy); + ok = vect_analyze_data_ref_dependences (loop_vinfo, NULL, &max_vf); if (!ok || max_vf < min_vf) { Index: tree-vect-data-refs.c =================================================================== --- tree-vect-data-refs.c (revision 180333) +++ tree-vect-data-refs.c (working copy) @@ -555,8 +555,7 @@ vect_mark_for_runtime_alias_test (ddr_p ddr, loop_ static bool vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, - loop_vec_info loop_vinfo, int *max_vf, - bool *data_dependence_in_bb) + loop_vec_info loop_vinfo, int *max_vf) { unsigned int i; struct loop *loop = NULL; @@ -587,6 +586,8 @@ vect_analyze_data_ref_dependence (struct data_depe if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) { + gimple earlier_stmt; + if (loop_vinfo) { if (vect_print_dump_info (REPORT_DR_DETAILS)) @@ -624,10 +625,11 @@ vect_analyze_data_ref_dependence (struct data_depe if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)) return true; - /* We deal with read-write dependencies in basic blocks later (by - verifying that all the loads in the basic block are before all the - stores). */ - *data_dependence_in_bb = true; + /* Check that it's not a load-after-store dependence. */ + earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb)); + if (DR_IS_WRITE (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt)))) + return true; + return false; } @@ -753,8 +755,7 @@ vect_analyze_data_ref_dependence (struct data_depe bool vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo, - bb_vec_info bb_vinfo, int *max_vf, - bool *data_dependence_in_bb) + bb_vec_info bb_vinfo, int *max_vf) { unsigned int i; VEC (ddr_p, heap) *ddrs = NULL; @@ -769,8 +770,7 @@ vect_analyze_data_ref_dependences (loop_vec_info l ddrs = BB_VINFO_DDRS (bb_vinfo); FOR_EACH_VEC_ELT (ddr_p, ddrs, i, ddr) - if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, max_vf, - data_dependence_in_bb)) + if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, max_vf)) return false; return true; Index: tree-vect-patterns.c =================================================================== --- tree-vect-patterns.c (revision 180333) +++ tree-vect-patterns.c (working copy) @@ -1225,7 +1225,7 @@ vect_recog_over_widening_pattern (VEC (gimple, hea where type 'TYPE' is at least double the size of type 'type'. - Also detect unsgigned cases: + Also detect unsigned cases: unsigned type a_t; unsigned TYPE u_res_T; Index: tree-vect-slp.c =================================================================== --- tree-vect-slp.c (revision 180333) +++ tree-vect-slp.c (working copy) @@ -1706,43 +1706,6 @@ vect_slp_analyze_operations (bb_vec_info bb_vinfo) return true; } -/* Check if loads and stores are mixed in the basic block (in that - case if we are not sure that the accesses differ, we can't vectorize the - basic block). Also return FALSE in case that there is statement marked as - not vectorizable. */ - -static bool -vect_bb_vectorizable_with_dependencies (bb_vec_info bb_vinfo) -{ - basic_block bb = BB_VINFO_BB (bb_vinfo); - gimple_stmt_iterator si; - bool detected_store = false; - gimple stmt; - struct data_reference *dr; - - for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) - { - stmt = gsi_stmt (si); - - /* We can't allow not analyzed statements, since they may contain data - accesses. */ - if (!STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt))) - return false; - - if (!STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt))) - continue; - - dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)); - if (DR_IS_READ (dr) && detected_store) - return false; - - if (!DR_IS_READ (dr)) - detected_store = true; - } - - return true; -} - /* Check if vectorization of the basic block is profitable. */ static bool @@ -1823,7 +1786,6 @@ vect_slp_analyze_bb_1 (basic_block bb) int i; int min_vf = 2; int max_vf = MAX_VECTORIZATION_FACTOR; - bool data_dependence_in_bb = false; bb_vinfo = new_bb_vec_info (bb); if (!bb_vinfo) @@ -1850,11 +1812,8 @@ vect_slp_analyze_bb_1 (basic_block bb) return NULL; } - if (!vect_analyze_data_ref_dependences (NULL, bb_vinfo, &max_vf, - &data_dependence_in_bb) - || min_vf > max_vf - || (data_dependence_in_bb - && !vect_bb_vectorizable_with_dependencies (bb_vinfo))) + if (!vect_analyze_data_ref_dependences (NULL, bb_vinfo, &max_vf) + || min_vf > max_vf) { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) fprintf (vect_dump, "not vectorized: unhandled data dependence "