Get address of label?

Heywood Floyd soul8o8 at gmail.com
Sun Dec 26 09:21:34 PST 2010


Thank you bearophile and Simen for your replies! Very helpful! 
I'll keep looking into it...

BR
/HF



bearophile Wrote:

> Simen kjaeraas:
> 
> > Essentially, mark the switch as final, and cover every option.
> > Likely, the optimizer does that for you if you cover every option but
> > don't mark the switch as final.
> 
> This is true in theory, and I remember Walter liking this optimization. But in practice I don't know if DMD performs this optimization already, so you need to take a look at the produced asm to be sure.
> 
> --------------------------------
> 
> This is a little test, D2 code:
> 
> enum E { e1, e2, e3 }
> 
> int foo1(E e) {
>     switch (e) {
>         case E.e1: return 1;
>         case E.e2: return 2;
>         case E.e3: return 3;
>         default: assert(0);
>     }
> }
> 
> int foo2(E e) {
>     switch (e) {
>         case E.e1: return 1;
>         case E.e2: return 2;
>         default: return 3;
>     }
> }
> 
> int foo3(E e) {
>     final switch (e) {
>         case E.e1: return 1;
>         case E.e2: return 2;
>         case E.e3: return 3;
>     }
> }
> void main() {}
> 
> 
> _D5test4foo1FE5test31EZi
>         push EAX
>         test EAX,EAX
>         je  L11
>         cmp EAX,1
>         je  L18
>         cmp EAX,2
>         je  L1F
>         jmp short L26
> L11:    pop ECX
>         mov EAX,1
>         ret
> L18:    pop ECX
>         mov EAX,2
>         ret
> L1F:    pop ECX
>         mov EAX,3
>         ret
> L26:    hlt
> 
> _D5test4foo2FE5test31EZi
>         push EAX
>         test EAX,EAX
>         je  LC
>         cmp EAX,1
>         je  L13
>         jmp short L1A
> LC:     pop ECX
>         mov EAX,1
>         ret
> L13:    pop ECX
>         mov EAX,2
>         ret
> L1A:    pop ECX
>         mov EAX,3
>         ret
> 
> _D5test4foo3FE5test31EZi
>         push EAX
>         test EAX,EAX
>         je  L11
>         cmp EAX,1
>         je  L18
>         cmp EAX,2
>         je  L1F
>         jmp short L26
> L11:    pop ECX
>         mov EAX,1
>         ret
> L18:    pop ECX
>         mov EAX,2
>         ret
> L1F:    pop ECX
>         mov EAX,3
>         ret
> L26:    pop EAX
>         ret
> 
> --------------------------------
> 
> Some C code compiled with GCC 4.5.1:
> 
> typedef enum { e1, e2, e3 } E;
> 
> int foo2(E e) {
>     switch (e) {
>         case e1: return 1;
>         case e2: return 2;
>         default: return 3;
>     }
> }
> 
> int foo3(E e) {
>     switch (e) {
>         case e1: return 1;
>         case e2: return 2;
>         case e3: return 3;
>     }
> }
> 
> int foo4(E e) {
>     static void *array[] = { &&E1, &&E2, &&E3 };
> 
>     goto *array[e];
> 
>     E1: return 1;
>     E2: return 2;
>     E3: return 3;
> }
> 
> int main() {
>     return 0;
> }
> 
> 
> _foo2:
>     movl    4(%esp), %edx
>     movl    $3, %eax
>     cmpl    $1, %edx
>     jbe L5
>     rep
>     ret
>     .p2align 4,,7
> L5:
>     movl    _CSWTCH.1(,%edx,4), %eax
>     ret
>     .p2align 4,,15
> 
> _foo3:
>     movl    4(%esp), %edx
>     cmpl    $1, %edx
>     je  L11
>     movl    $1, %eax
>     jb  L6
>     cmpl    $2, %edx
>     je  L13
>     .p2align 4,,3
>     rep
>     ret
>     .p2align 4,,7
> L11:
>     movl    $2, %eax
> L6:
>     .p2align 4,,3
>     rep
>     ret
>     .p2align 4,,7
> L13:
>     movb    $3, %al
>     ret
> 
> _foo4:
> 	movl	4(%esp), %eax
> 	jmp	*_array.1639(,%eax,4)
> 	.p2align 4,,7
> L15:
> 	movl	$1, %eax
> 	ret
> 	.p2align 4,,7
> L17:
> 	movl	$2, %eax
> 	ret
> 	.p2align 4,,7
> L18:
> 	movl	$3, %eax
> 	ret
> 
> --------------------------------
> 
> > My forays into the inline asm idea proved fruitless, but there may yet be ways.
> 
> In D+DMD inline asm kills inlining, so you may use inline asm only if you need to do lot of computations.
> In LDC there are pragma(allow_inline) and asm expressions that some most of this problem.
> 
> Going back to the OP problem: in D there are no computed gotos, that are useful if you want to write very fast interpreters and other things. But keep in mind that DMD supports normal gotos from and in inlined asm (LLVM-LDC doesn't supports this well), plus naked asm, this gives you some possibilities.
> An option on Linux is to write the interpreter core using GNU C (that has computed gotos) and then link the core to the D code compiled with DMD/GDC.
> 
> It's strange how something as basic, old and necessary as a switch, to create a basic but fast interpreter, is so hard to compile well for compilers :-)
> 
> Bye,
> bearophile



More information about the Digitalmars-d-learn mailing list