This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [tree-ssa] computed gotos
- From: Daniel Berlin <dberlin at dberlin dot org>
- To: law at redhat dot com
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 24 Jan 2003 16:01:11 -0500
- Subject: Re: [tree-ssa] computed gotos
On Friday, January 24, 2003, at 03:09 PM, law@redhat.com wrote:
This allows us to handle computed gotos in the presense of static
initializers containing label addresses. Fun fun.
If you actually want to *simplify* computed gotos (whose labels are
local to the function), you can transform them into a switch statement
by assigning each label whose address is taken some small integer
number.
CIL does this (http://manju.cs.berkeley.edu/cil)
" Labels as values and computed goto. This allows a program to take the
address of a label and to manipulate it as any value and also to
perform a computed goto. We compile this by assigning each label whose
address is taken a small integer that acts as its address. Every
computed goto in the body of the function is replaced with a switch
statement. If you want to invoke the label from another function, you
are on your own (the gcc documentation says the same.) "
That way, you don't have to handle the common case specially in the cfg
builder.
An example transformation, from the CIL manual:
static void *jtab[2]; // A jump table
static int doit(int x){
static int jtab_init = 0;
if(!jtab_init) { // Initialize the jump table
jtab[0] = &&lbl1;
jtab[1] = &&lbl2;
jtab_init = 1;
}
goto *jtab[x]; // Jump through the table
lbl1:
return 0;
lbl2:
return 1;
}
int main(void){
if (doit(0) != 0) exit(1);
if (doit(1) != 1) exit(1);
exit(0);
}
becomes
/* Generated by CIL v. 1.0.5 */
/* print_CIL_Input is true */
# 1 "cilcode.tmp/ex33.c"
static void *jtab[2] ;
# 4
static int doit(int x ) ;
# 4 "cilcode.tmp/ex33.c"
static int jtab_init = 0;
# 2 "cilcode.tmp/ex33.c"
static int doit(int x )
{ unsigned int __compgoto ;
{
# 5
if (! jtab_init) {
# 6
jtab[0] = (void *)0;
# 7
jtab[1] = (void *)1;
# 8
jtab_init = 1;
}
# 10
__compgoto = (unsigned int )jtab[x];
# 10
switch (__compgoto) {
case 1:
goto lbl2;
case 0:
goto lbl1;
default:
# 10
(*((int *)0)) = 0;
}
lbl1:
# 12
return (0);
lbl2:
# 14
return (1);
}
}
# 18
extern int ( /* missing proto */ exit)() ;
# 17 "cilcode.tmp/ex33.c"
int main(void)
{ int tmp ;
int tmp___0 ;
{
# 18
tmp = doit(0);
# 18
if (tmp != 0) {
# 18
exit(1);
}
# 19
tmp___0 = doit(1);
# 19
if (tmp___0 != 1) {
# 19
exit(1);
}
# 20
exit(0);
# 20
return (0);
}
}