From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1493 invoked by alias); 5 Oct 2003 16:53:00 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 916 invoked from network); 5 Oct 2003 16:52:49 -0000 Received: from unknown (HELO amd.ucw.cz) (160.218.145.86) by sources.redhat.com with SMTP; 5 Oct 2003 16:52:49 -0000 Received: by amd.ucw.cz (Postfix, from userid 8) id 807CE19E6B8; Sun, 5 Oct 2003 18:52:38 +0200 (CEST) Date: Sun, 05 Oct 2003 16:53:00 -0000 From: Pavel Machek To: Matthew Wilcox Cc: gcc@gcc.gnu.org Subject: Re: [ACPI] Why does gcc suck at switch()? Message-ID: <20031005165237.GB753@elf.ucw.cz> References: <20031003145614.GP24824@parcelfarce.linux.theplanet.co.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20031003145614.GP24824@parcelfarce.linux.theplanet.co.uk> X-Warning: Reading this can be dangerous to your mental health. User-Agent: Mutt/1.5.4i X-SW-Source: 2003-10/txt/msg00144.txt.bz2 Hi! > Why does gcc generate worse code for switch() statements than for > multiple-if? > > $ gcc --version > gcc (GCC) 3.3.2 20030908 (Debian prerelease) > > I would expect a compiler to produce the same code for these cases. > Instead, switch is worse than the multiple-if: > > - switch (event) { > - case ACPI_THERMAL_NOTIFY_TEMPERATURE: > + if (event == ACPI_THERMAL_NOTIFY_TEMPERATURE) { > acpi_thermal_check(tz); > - break; > - case ACPI_THERMAL_NOTIFY_THRESHOLDS: > + } else if (event == ACPI_THERMAL_NOTIFY_THRESHOLDS) { > acpi_thermal_get_trip_points(tz); > acpi_thermal_check(tz); > acpi_bus_generate_event(device, event, 0); > - break; > - case ACPI_THERMAL_NOTIFY_DEVICES: > + } else if (event == ACPI_THERMAL_NOTIFY_DEVICES) { > if (tz->flags.devices) > acpi_thermal_get_devices(tz); > acpi_bus_generate_event(device, event, 0); > - break; > - default: > + } else { > ACPI_DEBUG_PRINT((ACPI_DB_INFO, > "Unsupported event [0x%x]\n", event)); > - break; > } > > $ size *.o > text data bss dec hex filename > 5996 704 16 6716 1a3c thermal-multiple-if.o > 6005 704 16 6725 1a45 thermal-switch.o > > Here's the asm diff between the two versions: > > - cmpl $129, %esi > - je .L597 > - cmpl $129, %esi > - ja .L602 > - addl $-128, %esi > - je .L596 > - jmp .L592 > -.L602: > - cmpl $130, %esi > - je .L598 > - jmp .L592 > -.L596: > + cmpl $128, %esi > + jne .L595 > ... > -.L597: > +.L595: > + cmpl $129, %esi > + jne .L597 > ... > -.L598: > +.L597: > + cmpl $130, %esi > + jne .L592 > > The other diffs are just label numbers changing. Given that gcc was > instructed to optimise for space (full command line: > > gcc -Wp,-MD,drivers/acpi/.thermal.o.d -nostdinc -iwithprefix include \ > -D__KERNEL__ -Iinclude -D__KERNEL__ -Iinclude -Wall \ > -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing \ > -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 \ > -Iinclude/asm-i386/mach-default -fomit-frame-pointer -Os \ > -DKBUILD_BASENAME=thermal -DKBUILD_MODNAME=thermal -c \ > -o drivers/acpi/thermal.o drivers/acpi/thermal.c > > I think it should choose the more space-efficient approach. Okay, but please don't change kernel code to workaround compiler problem. This should probably be sent to gcc mailing list... Ahha, it is. Not sure if it needs to be cc-ed to acpi at all. Pavel -- When do you have a heart between your knees? [Johanka's followup: and *two* hearts?]