From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6089 invoked by alias); 30 Mar 2010 23:58:36 -0000 Received: (qmail 6026 invoked by uid 48); 30 Mar 2010 23:58:24 -0000 Date: Tue, 30 Mar 2010 23:58:00 -0000 Message-ID: <20100330235824.6025.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug rtl-optimization/43520] gcc.dg/pr43058.c uses way too memory on ia64 In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "wilson at gcc dot gnu dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2010-03/txt/msg03085.txt.bz2 ------- Comment #4 from wilson at gcc dot gnu dot org 2010-03-30 23:58 ------- I've confirmed that Vlad's -fsched-pressure patch is the problem, and done a bit more analysis to see why. The testcase has approximately 20,000 movdi_internal insns, 6000 movsi_internal insns, and 10,000 call_value_gp insns. The ia64 movdi_internal patterns has constraints 'd' for memory pipeline application registers and 'e' for integer pipeline application registers. The 'd' class has 2 regs, both fixed. The 'e' class has 3 regs, two fixed. Since the two classes have only 0 and 1 allocatable register each, the -fsched-pressure patch puts them in implicit_reg_pending_clobbers. The movsi_internal pattern also uses 'd', so it is handled similarly. So we end up with all 26,000 move insns on the reg_last->implicit_sets list. Meanwhile, because we have 4 fixed registers, every call insn is assumes to use these registers. Thus we end up with all 10,000 call insns on reg_last->uses. Since we create a dependency between implicit_sets and uses, that means we end up with approx 260M dependencies, each 40 bytes each, which is 10GB. Plus memory for insns lists and other stuff. The convention is that there is only supposed to be one mov* pattern, since reload does not re-recognize, so it doesn't appear to me that the ia64.md file is doing anything wrong. We could reduce the problem if the fixed registers were split out into separate move insns though. We still have the one not-fixed register (ar.lc), but it isn't call clobbered either, so I think that one might be OK. I haven't tested that theory yet. We would need to split the 'e' class to separate the fixed and non-fixed registers. Another option here would be to have a special letter like '*' and '#' except that it can be used to disable the register-pressure code. We still need to split the 'e' class for this, since we still want the register-pressure code for the non-fixed register (ar.lc). This would require fewer changes to the ia64 port than the above option. Another option here is to throttle the reg_last->use and/or reg_last->implicit_sets lists somehow. We could just keep a count of them and arbitrarily flush them when they get too big. There is already code to do this that uses uses_length and clobbers_length. Adding a implicit_sets_length might help. There is code to free a list when we see a set, but the testcase does not have sets for 4 of the 5 registers, so the lists do not get freed this way. The current code that tests uses_length and clobber_length only triggers if there is a clobber, and again there are no clobbers of any of the 5 registers here. The lists will only get freed if we flush them some how in the implicit_sets handling code. Or maybe we could try to keep trace of reads and writes better. If we have a series of implicit sets followed by a series of uses followed by some more implicit sets, then we can actually flush the implicit_set list when we see the second set of implicit sets. This is because every use will depend on every implicit set in the first group, and every implicit set in the second group will depend on every use, so there is no need to retain the insns in the first group in the implicit set list. Similarly, we can free insns from the use group when we see a second set of uses. Another option here is to make -fno-sched-pressure disable the code that sets implicit_reg_pending_clobbers, though this isn't a fix, just a workaround. -- wilson at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |vmakarov at redhat dot com Status|UNCONFIRMED |NEW Ever Confirmed|0 |1 Last reconfirmed|0000-00-00 00:00:00 |2010-03-30 23:58:23 date| | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43520