This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/43864] New: Same basic blocks should be merged
- From: "carrot at google dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 23 Apr 2010 07:27:48 -0000
- Subject: [Bug middle-end/43864] New: Same basic blocks should be merged
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
Following is a simple example:
#include <stdio.h>
void foo (char*, FILE*);
char* hprofStartupp(char *outputFileName, char *ctx)
{
char fileName[1000];
FILE *fp;
sprintf(fileName, outputFileName);
if (access(fileName, 1) == 0) {
free(ctx); //A
return 0; //A
}
fp = fopen(fileName, 0);
if (fp == 0) {
free(ctx); //B
return 0; //B
}
foo(outputFileName, fp);
return ctx;
}
Basic block A and basic block B are exact same. They do some cleanup work and
exit the function. This pattern is quite common in large software. GCC failed
to merge them in this test case. With options -march=armv7-a -mthumb -Os, gcc
generates:
...
bl access
mov r7, r0
cbnz r0, .L2
mov r0, r4 //C
mov r4, r7 //C
bl free //C
b .L3 //C
.L2:
mov r0, sp
movs r1, #0
bl fopen
mov r5, r0
cbnz r0, .L4
mov r0, r4 //D
mov r4, r5 //D
bl free //D
b .L3 //D
.L4:
...
Here basic block C corresponds to basic block A, and basic block D corresponds
basic block B. They can be merged as following:
...
bl access
mov r5, r0
cbz r0, .L9
.L2:
mov r0, sp
movs r1, #0
bl fopen
mov r5, r0
cbnz r0, .L4
.L9:
mov r0, r4
mov r4, r5
bl free
b .L3
.L4:
...
The rtl cfg optimization can do some merge optimization. But it often fails due
to difference of register numbers. We may need to do this at tree level.
--
Summary: Same basic blocks should be merged
Product: gcc
Version: 4.6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: carrot at google dot com
GCC build triplet: i686-linux
GCC host triplet: i686-linux
GCC target triplet: arm-eabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43864