From patchwork Fri Sep 9 12:53:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 114096 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]) by ozlabs.org (Postfix) with SMTP id 40D31B708F for ; Fri, 9 Sep 2011 22:53:47 +1000 (EST) Received: (qmail 8729 invoked by alias); 9 Sep 2011 12:53:45 -0000 Received: (qmail 8718 invoked by uid 22791); 9 Sep 2011 12:53:43 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-fx0-f47.google.com (HELO mail-fx0-f47.google.com) (209.85.161.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 09 Sep 2011 12:53:29 +0000 Received: by fxi1 with SMTP id 1so93038fxi.20 for ; Fri, 09 Sep 2011 05:53:27 -0700 (PDT) Received: by 10.223.50.150 with SMTP id z22mr1362490faf.30.1315572807865; Fri, 09 Sep 2011 05:53:27 -0700 (PDT) Received: from richards-thinkpad.stglab.manchester.uk.ibm.com (gbibp9ph1--blueice3n2.emea.ibm.com [195.212.29.84]) by mx.google.com with ESMTPS id d23sm2830654fam.4.2011.09.09.05.53.25 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 09 Sep 2011 05:53:25 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [ARM] Loosen MODES_TIEABLE_P Date: Fri, 09 Sep 2011 13:53:23 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 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 ARM's MODES_TIEABLE_P only allows classes of the same mode to be tied: #define MODES_TIEABLE_P(MODE1, MODE2) \ (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)) But for NEON, we'd like structure modes to be tied to their vector elements. In particular, a vector subreg of a structure register should be considered "cheap", rather than as something that is likely to need an intermediate. The current definition made sense before my patch to redefine CLASS_CANNOT_CHANGE_MODE: http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01631.html so I think this is really a missing piece from that patch. I haven't measured any direct benefit from this patch alone, because no pass propogates the sources of subreg moves, even if the modes are tieable. But with a patch to do that too, I see significant improvements for several vectorised loops. Tested on arm-linux-gnueabi. OK to install? Richard gcc/ * config/arm/arm-protos.h (arm_modes_tieable_p): Declare. * config/arm/arm.h (MODES_TIEABLE_P): Use it. * config/arm/arm.c (arm_modes_tieable_p): New function. Allow NEON vector and structure modes to be tied. Index: gcc/config/arm/arm-protos.h =================================================================== --- gcc/config/arm/arm-protos.h 2011-09-08 10:31:01.455663735 +0100 +++ gcc/config/arm/arm-protos.h 2011-09-09 13:46:32.797939324 +0100 @@ -46,6 +46,7 @@ extern void arm_output_fn_unwind (FILE * extern bool arm_vector_mode_supported_p (enum machine_mode); extern bool arm_small_register_classes_for_mode_p (enum machine_mode); extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode); +extern bool arm_modes_tieable_p (enum machine_mode, enum machine_mode); extern int const_ok_for_arm (HOST_WIDE_INT); extern int const_ok_for_op (HOST_WIDE_INT, enum rtx_code); extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx, Index: gcc/config/arm/arm.h =================================================================== --- gcc/config/arm/arm.h 2011-09-08 10:31:01.455663735 +0100 +++ gcc/config/arm/arm.h 2011-09-09 13:46:32.865939164 +0100 @@ -962,12 +962,7 @@ #define HARD_REGNO_NREGS(REGNO, MODE) #define HARD_REGNO_MODE_OK(REGNO, MODE) \ arm_hard_regno_mode_ok ((REGNO), (MODE)) -/* Value is 1 if it is a good idea to tie two pseudo registers - when one has mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ -#define MODES_TIEABLE_P(MODE1, MODE2) \ - (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)) +#define MODES_TIEABLE_P(MODE1, MODE2) arm_modes_tieable_p (MODE1, MODE2) #define VALID_IWMMXT_REG_MODE(MODE) \ (arm_vector_mode_supported_p (MODE) || (MODE) == DImode) Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c 2011-09-08 10:31:01.455663735 +0100 +++ gcc/config/arm/arm.c 2011-09-09 13:46:32.842939218 +0100 @@ -18236,6 +18236,29 @@ arm_hard_regno_mode_ok (unsigned int reg && regno <= LAST_FPA_REGNUM); } +/* Implement MODES_TIEABLE_P. */ + +bool +arm_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2) +{ + if (GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2)) + return true; + + /* We specifically want to allow elements of "structure" modes to + be tieable to the structure. This more general condition allows + other rarer situations too. */ + if (TARGET_NEON + && (VALID_NEON_DREG_MODE (mode1) + || VALID_NEON_QREG_MODE (mode1) + || VALID_NEON_STRUCT_MODE (mode1)) + && (VALID_NEON_DREG_MODE (mode2) + || VALID_NEON_QREG_MODE (mode2) + || VALID_NEON_STRUCT_MODE (mode2))) + return true; + + return false; +} + /* For efficiency and historical reasons LO_REGS, HI_REGS and CC_REGS are not used in arm mode. */