From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id BC3273858C00 for ; Thu, 4 Aug 2022 09:39:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BC3273858C00 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 10A7A11FB; Thu, 4 Aug 2022 02:39:35 -0700 (PDT) Received: from localhost (e121540-lin.manchester.arm.com [10.32.98.37]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DC2073F67D; Thu, 4 Aug 2022 02:39:33 -0700 (PDT) From: Richard Sandiford To: Jeff Law via Gcc-patches Mail-Followup-To: Jeff Law via Gcc-patches , Jeff Law , richard.sandiford@arm.com Subject: Re: [PATCH] lower-subreg, expr: Mitigate inefficiencies derived from "(clobber (reg X))" followed by "(set (subreg (reg X)) (...))" References: Date: Thu, 04 Aug 2022 10:39:32 +0100 In-Reply-To: (Jeff Law via Gcc-patches's message of "Wed, 3 Aug 2022 11:23:43 -0600") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-46.4 required=5.0 tests=BAYES_00, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Aug 2022 09:39:36 -0000 Jeff Law via Gcc-patches writes: > On 8/3/2022 1:52 AM, Richard Sandiford via Gcc-patches wrote: >> Takayuki 'January June' Suwa via Gcc-patches w= rites: >>> Emitting "(clobber (reg X))" before "(set (subreg (reg X)) (...))" keeps >>> data flow consistent, but it also increases register allocation pressure >>> and thus often creates many unwanted register-to-register moves that >>> cannot be optimized away. >> There are two things here: >> >> - If emit_move_complex_parts emits a clobber of a hard register, >> then that's probably a bug/misfeature. The point of the clobber is >> to indicate that the register has no useful contents. That's useful >> for wide pseudos that are written to in parts, since it avoids the >> need to track the liveness of each part of the pseudo individually. >> But it shouldn't be necessary for hard registers, since subregs of >> hard registers are simplified to hard registers wherever possible >> (which on most targets is "always"). >> >> So I think the emit_move_complex_parts clobber should be restricted >> to !HARD_REGISTER_P, like the lower-subreg clobber is. If that helps >> (if only partly) then it would be worth doing as its own patch. > Agreed. > >> >> - I think it'd be worth looking into more detail why a clobber makes >> a difference to register pressure. A clobber of a pseudo register R >> shouldn't make R conflict with things that are live at the point of >> the clobber. > Also agreed. > >> >>> It seems just analogous to partial register >>> stall which is a famous problem on processors that do register renaming. >>> >>> In my opinion, when the register to be clobbered is a composite of hard >>> ones, we should clobber the individual elements separetely, otherwise >>> clear the entire to zero prior to use as the "init-regs" pass does (like >>> partial register stall workarounds on x86 CPUs). Such redundant zero >>> constant assignments will be removed later in the "cprop_hardreg" pass. >> I don't think we should rely on the zero being optimised away later. >> >> Emitting the zero also makes it harder for the register allocator >> to elide the move. For example, if we have: >> >> (set (subreg:SI (reg:DI P) 0) (reg:SI R0)) >> (set (subreg:SI (reg:DI P) 4) (reg:SI R1)) >> >> then there is at least a chance that the RA could assign hard registers >> R0:R1 to P, which would turn the moves into nops. If we emit: >> >> (set (reg:DI P) (const_int 0)) >> >> beforehand then that becomes impossible, since R0 and R1 would then >> conflict with P. >> >> TBH I'm surprised we still run init_regs for LRA. I thought there was >> a plan to stop doing that, but perhaps I misremember. > I have vague memories of dealing with some of this nonsense a few=20 > release cycles.=C2=A0 I don't recall all the details, but init-regs +=20 > lower-subreg + regcprop + splitting all conspired to generate poor code=20 > on the MIPS targets.=C2=A0 See pr87761, though it doesn't include all my= =20 > findings -- I can't recall if I walked through the entire tortured=20 > sequence in the gcc-patches discussion or not. > > I ended up working around in the mips backend in conjunction with some=20 > changes to regcprop IIRC. Thanks for the pointer, hadn't seen that. And yeah, for the early-ish passes, I guess the interaction between lower-subreg and init-regs is important too, not just the interaction between lower-subreg and RA. It probably also ties into the problems with overly-scalarised register moves, like in PR 106106. So maybe I was being too optimistic :-) Richard