I just tried to compile the attached C++ source code with both gcc 4.3.1 and gcc 4.4.0 snapshot 20081031. gcc 431 took less than one second and consumed a trivial amount of virtual memory. gcc 440 snapshot 20081031 took over 90 seconds on an idle machine, and consumed over 11 Gig of virtual memory before running out of virtual memory. In my opinion, 11 Gig of memory is an excessive amount of memory to use. I suspect the compiler is looping without doing any productive work. Preprocessed source code attached. Flag -O2 required.
Created attachment 16611 [details] C++ source code
Confirmed. We seem to be very slowly eating all of memory during processing a single SCC in FRE - which means iteration doesn't converge.
Reducing.
The following fails this way with plain -O. The key is the typedef - if you replace the use of UInt32 with unsinged int the testcase succeeds. Mine. typedef unsigned int UInt32; int Read(unsigned int *processedSize); void FindAndReadSignature(void) { unsigned int numPrevBytes = 31; for (;;) { unsigned int numReadBytes = (1 << 16) - numPrevBytes; unsigned int processedSize; int __result__ = Read(&processedSize); unsigned int numBytesInBuffer = numPrevBytes + processedSize; UInt32 numTests = numBytesInBuffer - 31; for (unsigned int pos = 0; pos < numTests; pos++) ; numPrevBytes = numBytesInBuffer - numTests; } }
More reduced: typedef int Int32; void use_it(int); void FindAndReadSignature(int processedSize) { int numPrevBytes = 1; for (;;) { int numBytesInBuffer = numPrevBytes + processedSize; Int32 numTests = numBytesInBuffer - 1; use_it (numTests); numPrevBytes = numBytesInBuffer - numTests; } } to not oscillate we rely on numTests _not_ be varying. It happens to be with the typedef as we forget to strip useless conversions. Otherwise we oscillate numPrevBytes (loop entry vs. back edge) between 1 and varying. Which may hint at that the speedup brought up by Danny (not processing a use further if it got varying) is even a correctness thing... I have a patch for this particular case.
Fixed.
Subject: Bug 37991 Author: rguenth Date: Sun Nov 2 13:34:58 2008 New Revision: 141532 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141532 Log: 2008-11-02 Richard Guenther <rguenther@suse.de> PR tree-optimization/37991 * tree-ssa-sccvn.h (copy_vuses_from_stmt): Remove. * tree-ssa-sccvn.c (copy_vuses_from_stmt): Make static. (set_ssa_val_to): Print if the value changed. (simplify_binary_expression): Strip useless conversions. * gcc.c-torture/compile/pr37991.c: New testcase. Added: trunk/gcc/testsuite/gcc.c-torture/compile/pr37991.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-ssa-sccvn.c trunk/gcc/tree-ssa-sccvn.h
Subject: Re: [4.4 Regression] excessive memory consumption - possible hang On Sun, Nov 2, 2008 at 7:04 AM, rguenth at gcc dot gnu dot org <gcc-bugzilla@gcc.gnu.org> wrote: > > > ------- Comment #5 from rguenth at gcc dot gnu dot org 2008-11-02 12:04 ------- > More reduced: > > typedef int Int32; > void use_it(int); > void FindAndReadSignature(int processedSize) > { > int numPrevBytes = 1; > for (;;) > { > int numBytesInBuffer = numPrevBytes + processedSize; > Int32 numTests = numBytesInBuffer - 1; > use_it (numTests); > numPrevBytes = numBytesInBuffer - numTests; > } > } > > to not oscillate we rely on numTests _not_ be varying. It happens to be > with the typedef as we forget to strip useless conversions. Otherwise > we oscillate numPrevBytes (loop entry vs. back edge) between 1 and varying. > > Which may hint at that the speedup brought up by Danny (not processing a > use further if it got varying) is even a correctness thing... Things should never go up the lattice :)