I am attaching a C program and two cfg files corresponding to the program. First cfg file is generated by using the gcc -fdump-tree-cfg command and the second cfg is obtained after performing some manual optimizations on the gcc generated cfg.
In the first cfg file there are many temporary variables like a.0, b.1 etc. It seems that these varaibles can be replaced/removed without effecting the semantics; as shown in the second cfg file.
My Question is that:
- Is it always possible to remove these temporary variables or there are some peculiar cases in some more complex programs when they can't be removed?
- Is there a flag/command available in gcc to pervent creation of these (so many) temporary variables? If there exists, please tell the command.
While removing temporary varaibles my aim is to remove varaibles like a.0, b.1 etc only. I recognize that variables which don't contain a dot in their name and the variables of the form D.1234 caot be removed.
The complete example doesn't contain any varaible of the form D.<4 digit integer>. Hence, I am giving the following smaller example for illusrating the variable:
E.g. Illustration of variable with uppercase
D:
Statement
d = -d / c;
is transformed to
D.2184 = -d;
d = D.2184 / c;
Complete example:
Cfile:
// GCD.c
#include <stdio.h>
void main ()
{
int a, b;
scanf ("%d", &a);
scanf ("%d", &b);
if (a < 1 || b < 1)
{
a = -1;
printf ("%d", a);
}
else
{
while (a != b)
{
if (a > b)
a = a - b;
else
b = b - a;
}
printf ("%d", a);
}
}
First
cfg: generated by usinggcc -fdump-tree-cfg:
;; Function main (main, funcdef_no=0, decl_uid=2176, cgraph_uid=0)
main ()
{
int b;
int a;
int a.13;
int b.12;
int a.11;
int b.10;
int a.9;
int b.8;
int a.7;
int b.6;
int a.5;
int b.4;
int a.3;
int a.2;
int b.1;
int a.0;
<bb 2>:
scanf ("%d", &a);
scanf ("%d", &b);
a.0 = a;
if (a.0 <= 0)
goto <bb 4>;
else
goto <bb 3>;
<bb 3>:
b.1 = b;
if (b.1 <= 0)
goto <bb 4>;
else
goto <bb 5>;
<bb 4>:
a = -1;
a.2 = a;
printf ("%d", a.2);
goto <bb 11>;
<bb 5>:
goto <bb 9>;
<bb 6>:
a.3 = a;
b.4 = b;
if (a.3 > b.4)
goto <bb 7>;
else
goto <bb 8>;
<bb 7>:
a.5 = a;
b.6 = b;
a.7 = a.5 - b.6;
a = a.7;
goto <bb 9>;
<bb 8>:
b.8 = b;
a.9 = a;
b.10 = b.8 - a.9;
b = b.10;
<bb 9>:
a.11 = a;
b.12 = b;
if (a.11 != b.12)
goto <bb 6>;
else
goto <bb 10>;
<bb 10>:
a.13 = a;
printf ("%d", a.13);
<bb 11>:
a = {CLOBBER};
b = {CLOBBER};
retu;
}
Second cfg: Some manual optimization over the second
cfg. Look at the massive reduction in total number of varaibles and statements.
;; Function main (main, funcdef_no=0, decl_uid=2176, cgraph_uid=0)
main ()
{
int b;
int a;
<bb 2>:
scanf ("%d", &a);
scanf ("%d", &b);
if (a <= 0)
goto <bb 4>;
else
goto <bb 3>;
<bb 3>:
if (b <= 0)
goto <bb 4>;
else
goto <bb 5>;
<bb 4>:
a = -1;
printf ("%d", a);
goto <bb 11>;
<bb 5>:
goto <bb 9>;
<bb 6>:
if (a > b)
goto <bb 7>;
else
goto <bb 8>;
<bb 7>:
a = a - b;
goto <bb 9>;
<bb 8>:
b = b - a;
<bb 9>:
if (a != b)
goto <bb 6>;
else
goto <bb 10>;
<bb 10>:
printf ("%d", a);
<bb 11>:
a = {CLOBBER};
b = {CLOBBER};
retu;
}
