From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1686 invoked by alias); 17 Jul 2012 15:01:16 -0000 Received: (qmail 1652 invoked by uid 22791); 17 Jul 2012 15:01:13 -0000 X-SWARE-Spam-Status: No, hits=2.3 required=5.0 tests=AWL,BAYES_50,KHOP_RCVD_UNTRUST,KHOP_THREADED,MEDICAL_SUBJECT,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_NO X-Spam-Check-By: sourceware.org Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 17 Jul 2012 15:00:49 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Tue, 17 Jul 2012 16:00:47 +0100 Received: from [10.1.69.67] ([10.1.255.212]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 17 Jul 2012 16:01:58 +0100 Message-ID: <50057E1D.1000705@arm.com> Date: Tue, 17 Jul 2012 15:01:00 -0000 From: Richard Earnshaw User-Agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:13.0) Gecko/20120614 Thunderbird/13.0.1 MIME-Version: 1.0 To: Ulrich Weigand CC: "gcc-patches@gcc.gnu.org" , "patches@linaro.org" , "ramana.radhakrishnan@linaro.org" Subject: Re: [PATCH, ARM] Fix length attributes for sync.md patterns References: <201207161345.q6GDjLqu016862@d06av02.portsmouth.uk.ibm.com> In-Reply-To: <201207161345.q6GDjLqu016862@d06av02.portsmouth.uk.ibm.com> X-MC-Unique: 112071716004700701 Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes 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 X-SW-Source: 2012-07/txt/msg00746.txt.bz2 On 16/07/12 14:45, Ulrich Weigand wrote: > Hello, >=20 > when testing an out-of-tree patch I ran into a latent bug. > The symptom is error messages along the lines of > /tmp/cc6q0E3x.s:38: Error: co-processor offset out of range > caused by an out-of-range reference to a literal pool constant. > This happens only with -O0. >=20 > This turns out to caused by insn_and_split patterns in sync.md > used to represent atomic instructions. Those will (must) always > be split (usually into some form of compare-and-swap loop). If > optimization is on, this split happens shortly after reload, > before literal pool placement is finalized. >=20 > However, when building with -O0, this split is done very late; > in fact it happens *after* the machine-dependent reorg pass > where literal pools are handled. This means that this pass > sees the atomic patterns as single insns, and unfortunately, > since they have no length attribute, they are handled as if > they had a default length of 4 bytes. >=20 > But since those patterns in the end will expand to at least > 5-9 actual machine instructions, this default drastically > underestimates the code size, causing the out of range > references. >=20 > The patch below adds length attributes giving conservative > estimates of the final resulting code sizes. (They could > probably be made more specific, but since this is relevant > only for -O0, that's probably not worth the effort.) >=20 > This fixes the problems I was seeing. >=20 > Tested on arm-linux-gnueabi with no regressions. >=20 > OK for mainline? >=20 Hmm, I wonder if we should just unconditionally call split_all_insns() at the start of md_reorg when -O0. This would address your problem, but have the added benefit that the length calculations would be more accurate. We're going to have to split the insns anyway during output, so why not get it over and done with... R. > Bye, > Ulrich >=20 >=20 > ChangeLog: >=20 > * config/arm/sync.md (cas_length): New mode attribute. > (atomic_op_length, atomic_nand_length): Likewise. > ("atomic_compare_and_swap_1"): Add length attribute. > ("atomic_exchange"): Likewise. > ("atomic_"): Likewise. > ("atomic_nand"): Likewise. > ("atomic_fetch_"): Likewise. > ("atomic_fetch_nand"): Likewise. > ("atomic__fetch"): Likewise. > ("atomic_nand_fetch"): Likewise. >=20 > Index: gcc/config/arm/sync.md > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > *** gcc/config/arm/sync.md (revision 189459) > --- gcc/config/arm/sync.md (working copy) > *************** > *** 127,138 **** > { > arm_split_compare_and_swap (operands); > DONE; > ! }) >=20=20=20 > (define_mode_attr cas_cmp_operand > [(SI "arm_add_operand") (DI "cmpdi_operand")]) > (define_mode_attr cas_cmp_str > [(SI "rIL") (DI "rDi")]) >=20=20=20 > (define_insn_and_split "atomic_compare_and_swap_1" > [(set (reg:CC_Z CC_REGNUM) ;; bool out > --- 127,141 ---- > { > arm_split_compare_and_swap (operands); > DONE; > ! } > ! [(set_attr "length" "32")]) >=20=20=20 > (define_mode_attr cas_cmp_operand > [(SI "arm_add_operand") (DI "cmpdi_operand")]) > (define_mode_attr cas_cmp_str > [(SI "rIL") (DI "rDi")]) > + (define_mode_attr cas_length > + [(SI "32") (DI "44")]) >=20=20=20 > (define_insn_and_split "atomic_compare_and_swap_1" > [(set (reg:CC_Z CC_REGNUM) ;; bool out > *************** > *** 155,161 **** > { > arm_split_compare_and_swap (operands); > DONE; > ! }) >=20=20=20 > (define_insn_and_split "atomic_exchange" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") ;; output > --- 158,165 ---- > { > arm_split_compare_and_swap (operands); > DONE; > ! } > ! [(set_attr "length" "")]) >=20=20=20 > (define_insn_and_split "atomic_exchange" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") ;; output > *************** > *** 175,181 **** > arm_split_atomic_op (SET, operands[0], NULL, operands[1], > operands[2], operands[3], operands[4]); > DONE; > ! }) >=20=20=20 > (define_mode_attr atomic_op_operand > [(QI "reg_or_int_operand") > --- 179,186 ---- > arm_split_atomic_op (SET, operands[0], NULL, operands[1], > operands[2], operands[3], operands[4]); > DONE; > ! } > ! [(set_attr "length" "20")]) >=20=20=20 > (define_mode_attr atomic_op_operand > [(QI "reg_or_int_operand") > *************** > *** 186,191 **** > --- 191,199 ---- > (define_mode_attr atomic_op_str > [(QI "rn") (HI "rn") (SI "rn") (DI "r")]) >=20=20=20 > + (define_mode_attr atomic_op_length > + [(QI "24") (HI "24") (SI "24") (DI "28")]) > +=20 > (define_insn_and_split "atomic_" > [(set (match_operand:QHSD 0 "mem_noofs_operand" "+Ua") > (unspec_volatile:QHSD > *************** > *** 204,210 **** > arm_split_atomic_op (, NULL, operands[3], operands[0], > operands[1], operands[2], operands[4]); > DONE; > ! }) >=20=20=20 > (define_insn_and_split "atomic_nand" > [(set (match_operand:QHSD 0 "mem_noofs_operand" "+Ua") > --- 212,222 ---- > arm_split_atomic_op (, NULL, operands[3], operands[0], > operands[1], operands[2], operands[4]); > DONE; > ! } > ! [(set_attr "length" "")]) > !=20 > ! (define_mode_attr atomic_nand_length > ! [(QI "28") (HI "28") (SI "28") (DI "32")]) >=20=20=20 > (define_insn_and_split "atomic_nand" > [(set (match_operand:QHSD 0 "mem_noofs_operand" "+Ua") > *************** > *** 225,231 **** > arm_split_atomic_op (NOT, NULL, operands[3], operands[0], > operands[1], operands[2], operands[4]); > DONE; > ! }) >=20=20=20 > (define_insn_and_split "atomic_fetch_" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") > --- 237,244 ---- > arm_split_atomic_op (NOT, NULL, operands[3], operands[0], > operands[1], operands[2], operands[4]); > DONE; > ! } > ! [(set_attr "length" "")]) >=20=20=20 > (define_insn_and_split "atomic_fetch_" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") > *************** > *** 247,253 **** > arm_split_atomic_op (, operands[0], operands[4], operands[1], > operands[2], operands[3], operands[5]); > DONE; > ! }) >=20=20=20 > (define_insn_and_split "atomic_fetch_nand" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") > --- 260,267 ---- > arm_split_atomic_op (, operands[0], operands[4], operands[1], > operands[2], operands[3], operands[5]); > DONE; > ! } > ! [(set_attr "length" "")]) >=20=20=20 > (define_insn_and_split "atomic_fetch_nand" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") > *************** > *** 270,276 **** > arm_split_atomic_op (NOT, operands[0], operands[4], operands[1], > operands[2], operands[3], operands[5]); > DONE; > ! }) >=20=20=20 > (define_insn_and_split "atomic__fetch" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") > --- 284,291 ---- > arm_split_atomic_op (NOT, operands[0], operands[4], operands[1], > operands[2], operands[3], operands[5]); > DONE; > ! } > ! [(set_attr "length" "")]) >=20=20=20 > (define_insn_and_split "atomic__fetch" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") > *************** > *** 292,298 **** > arm_split_atomic_op (, NULL, operands[0], operands[1], > operands[2], operands[3], operands[4]); > DONE; > ! }) >=20=20=20 > (define_insn_and_split "atomic_nand_fetch" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") > --- 307,314 ---- > arm_split_atomic_op (, NULL, operands[0], operands[1], > operands[2], operands[3], operands[4]); > DONE; > ! } > ! [(set_attr "length" "")]) >=20=20=20 > (define_insn_and_split "atomic_nand_fetch" > [(set (match_operand:QHSD 0 "s_register_operand" "=3D&r") > *************** > *** 315,321 **** > arm_split_atomic_op (NOT, NULL, operands[0], operands[1], > operands[2], operands[3], operands[4]); > DONE; > ! }) >=20=20=20 > (define_insn "arm_load_exclusive" > [(set (match_operand:SI 0 "s_register_operand" "=3Dr") > --- 331,338 ---- > arm_split_atomic_op (NOT, NULL, operands[0], operands[1], > operands[2], operands[3], operands[4]); > DONE; > ! } > ! [(set_attr "length" "")]) >=20=20=20 > (define_insn "arm_load_exclusive" > [(set (match_operand:SI 0 "s_register_operand" "=3Dr") >=20