Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
December 20, 2015 [dmd-internals] Help with dl_* functions in DMD | ||||
---|---|---|---|---|
| ||||
I’m trying to generate code using the dl_* functions in DMD. The corresponding D code would be the following: struct TLS { int* function (TLS*) thunk; size_t key; size_t offset; } extern (C) __gshared TLS bar; extern (C) int main (int i, char**) { auto foo = *bar.thunk(&bar); return 0; } The code that DMD is generating, for the above “main” functions, is: pushq %rbp movq %rsp, %rbp movq _bar(%rip), %rdi movq %rdi, %rax callq *_main(%rax) movl _main(%rax), %ecx xorl %eax, %eax popq %rbp retq What I’ve got so far is the following code below, instead of [1]: switch (op * 2 + x) { case OPvar * 2 + 1: e = el_una(OPind, TYnptr, e); e = el_una(OPind, TYnptr, e); break; case OPvar * 2 + 0: case OPrelconst * 2 + 1: e = el_una(OPind, TYnptr, e); break; case OPrelconst * 2 + 0: break; default: assert(0); break; } e = el_una(OPaddr, TYnptr, e); e = doptelem(e, GOALvalue | GOALflags); e = el_una(OPind, TYnptr, e); e = el_bin(OPcallns, TYnptr, e, e); e = el_una(OPind, TYnptr, e); With the above code DMD and for this example: extern (C) int main (int i, char**) { auto foo = bar; return 0; } DMD generates the following: pushq %rbp movq %rsp, %rbp movq _bar(%rip), %rax movq _main(%rax), %rdi callq *_bar(%rip) movl _main(%rax), %ecx xorl %eax, %eax popq %rbp retq Basically I have no idea what I’m doing and I don’t really understand how these el_* functions are working. Anyone could give me some help with this? [1] https://github.com/D-Programming-Language/dmd/blob/master/src/backend/el.c#L1259-L1263 -- /Jacob Carlborg _______________________________________________ dmd-internals mailing list dmd-internals@puremagic.com http://lists.puremagic.com/mailman/listinfo/dmd-internals |
December 27, 2015 Re: [dmd-internals] Help with dl_* functions in DMD | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg Attachments:
| On 12/20/2015 09:11 PM, Jacob Carlborg via dmd-internals wrote: > I’m trying to generate code using the dl_* functions in DMD. The corresponding D code would be the following: > > struct TLS > { > int* function (TLS*) thunk; > size_t key; > size_t offset; > } > > extern (C) __gshared TLS bar; > > extern (C) int main (int i, char**) > { > auto foo = *bar.thunk(&bar); > > return 0; > } > > The code that DMD is generating, for the above “main” functions, is: > > pushq %rbp > movq %rsp, %rbp > movq _bar(%rip), %rdi > movq %rdi, %rax > callq *_main(%rax) > movl _main(%rax), %ecx > xorl %eax, %eax > popq %rbp > retq What do you want to achieve? In general specific instructions such as for TLS access should be implemented by the corresponding cd* function, not in the intermediate representation. The IR might be the right place for a low-level lowering though. > Basically I have no idea what I’m doing and I don’t really understand how these el_* functions are working. Anyone could give me some help with this? The simply construct an IR tree, no magic here. OPind (dereference a pointer) OPadd (+ int or pointer) OPaddr (& take an address) OPconst (a constant value) OPcallns (call a function) You can find the documentation here. https://github.com/D-Programming-Language/dmd/blob/fc9edc34c7d7403b8c69b49abfe4c5ec2ae66061/src/backend/oper.h#L22 |
December 28, 2015 Re: [dmd-internals] Help with dl_* functions in DMD | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin Nowak Attachments:
| > On 27 dec 2015, at 22:33, Martin Nowak via dmd-internals <dmd-internals@puremagic.com> wrote: > > What do you want to achieve? My overall goal is to implement native TLS on OS X in DMD. For this particular question I was trying to figure out how to get DMD to generate same assembly as the corresponding D code, when a TLS variable is accessed, using the el_* functions. auto foo = *bar.thunk(&bar); > In general specific instructions such as > for TLS access should be implemented by the corresponding cd* function, > not in the intermediate representation. > The IR might be the right place for a low-level lowering though. It looks like the lowering for a TLS variable access to a call to ___tls_get_addr occurs in el_picvar for OS X. > The simply construct an IR tree, no magic here. You make it sound so easy :). I guess my main problem is that I’m reading the assembly that Clang outputs then I have no idea how to get DMD to generate the same assembly. Anyway, I think I managed to figure it out, this seems to work [1]. I basically traced all the el_* functions to see which were called and with what arguments when I compiled D code looking something like "auto foo = *bar.thunk(&bar);”. [1] https://github.com/jacob-carlborg/dmd/commit/49ecd3ff7861e2eb5838e2b2cd14b18f7fe2e07b -- /Jacob Carlborg |
December 29, 2015 Re: [dmd-internals] Help with dl_* functions in DMD | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | Debug DMD's secret '--b' switch will helpfully print out the elem tree for every function that reaches the backend, if you want to avoid manually tracing through e2ir. On Mon, Dec 28, 2015 at 11:29 PM, Jacob Carlborg via dmd-internals <dmd-internals@puremagic.com> wrote: > On 27 dec 2015, at 22:33, Martin Nowak via dmd-internals <dmd-internals@puremagic.com> wrote: > > What do you want to achieve? > > > My overall goal is to implement native TLS on OS X in DMD. For this particular question I was trying to figure out how to get DMD to generate same assembly as the corresponding D code, when a TLS variable is accessed, using the el_* functions. > > auto foo = *bar.thunk(&bar); > > In general specific instructions such as > for TLS access should be implemented by the corresponding cd* function, > not in the intermediate representation. > The IR might be the right place for a low-level lowering though. > > > It looks like the lowering for a TLS variable access to a call to ___tls_get_addr occurs in el_picvar for OS X. > > The simply construct an IR tree, no magic here. > > > You make it sound so easy :). I guess my main problem is that I’m reading the assembly that Clang outputs then I have no idea how to get DMD to generate the same assembly. > > Anyway, I think I managed to figure it out, this seems to work [1]. I basically traced all the el_* functions to see which were called and with what arguments when I compiled D code looking something like "auto foo = *bar.thunk(&bar);”. > > [1] https://github.com/jacob-carlborg/dmd/commit/49ecd3ff7861e2eb5838e2b2cd14b18f7fe2e07b > > -- > /Jacob Carlborg > > _______________________________________________ > dmd-internals mailing list > dmd-internals@puremagic.com > http://lists.puremagic.com/mailman/listinfo/dmd-internals _______________________________________________ dmd-internals mailing list dmd-internals@puremagic.com http://lists.puremagic.com/mailman/listinfo/dmd-internals |
December 29, 2015 Re: [dmd-internals] Help with dl_* functions in DMD | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Monday, 28 December 2015 at 12:29:41 UTC, Jacob Carlborg wrote: >> On 27 dec 2015, at 22:33, Martin Nowak via dmd-internals <dmd-internals@puremagic.com> wrote: >> >> What do you want to achieve? > > My overall goal is to implement native TLS on OS X in DMD. For this particular question I was trying to figure out how to get DMD to generate same assembly as the corresponding D code, when a TLS variable is accessed, using the el_* functions. > > auto foo = *bar.thunk(&bar); If you point us to some documentation of the native TLS, we might be able to help guide you a bit better. > It looks like the lowering for a TLS variable access to a call to ___tls_get_addr occurs in el_picvar for OS X. That's b/c our emulated TLS is simply a function call, no linker recognition and dedicated relocations are involved. Look at the native TLS implementation for linux, it works very differently, and I'd expect OSX' implementation to be somewhat similar. >> They simply construct an IR tree, no magic here. > > > You make it sound so easy :). I guess my main problem is that I’m reading the assembly that Clang outputs then I have no idea how to get DMD to generate the same assembly. Well it is fairly easy, https://en.wikipedia.org/wiki/Binary_expression_tree, but it's still quite difficult to construct the correct IR tree. As Daniel said, try to print your tree, there is some helper function (el_print or so). As I said earlier, when you're relying on a specific sequence of instructions, you have to implement it in the codegen, not the IR construction. _______________________________________________ dmd-internals mailing list dmd-internals@puremagic.com http://lists.puremagic.com/mailman/listinfo/dmd-internals |
December 29, 2015 Re: [dmd-internals] Help with dl_* functions in DMD | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin Nowak | > On 29 dec 2015, at 12:14, Martin Nowak via dmd-internals <dmd-internals@puremagic.com> wrote: > > If you point us to some documentation of the native TLS, we might be able to help guide you a bit better. As far as I know there is no documentation. But I have already figured it out. > That's b/c our emulated TLS is simply a function call, no linker recognition and dedicated relocations are involved. Look at the native TLS implementation for linux, it works very differently, and I'd expect OSX' implementation to be somewhat similar. It looks like it works very similar for Linux. At least it has the same kind of lowering. > Well it is fairly easy, https://en.wikipedia.org/wiki/Binary_expression_tree, but it's still quite difficult to construct the correct IR tree. As Daniel said, try to print your tree, there is some helper function (el_print or so). > As I said earlier, when you're relying on a specific sequence of instructions, you have to implement it in the codegen, not the IR construction. Anyway, I have already figured it out. Thanks for the help. -- /Jacob Carlborg _______________________________________________ dmd-internals mailing list dmd-internals@puremagic.com http://lists.puremagic.com/mailman/listinfo/dmd-internals |
Copyright © 1999-2021 by the D Language Foundation