Hello there, I'm trying to use a simple implementation of a queue (my own implementation of it, actually), and I'm trying to use the functions defined on my queue class inside some llvm-ir code. Unfortunately, the names of the functions are being messed up, then I created some function wrappers just to avoid having to deal with the C++ weird function renaming. So, to easily wrapper the class, I wrote a queue_wrapper.h library, which, basically, has the following code (where Q is a reference to my queue, and the channel is not really important): *extern "C" { * *#ifdef INT_TYPE* * void __attribute__((noinline))* * TYPED_NAME(produceValue)(int channel, TYPE elem)* * {Q->addElement (channel, (long)elem);}* * * * TYPE __attribute__((noinline))* * TYPED_NAME(consumeValue)(int channel)* * {return (TYPE) Q->removeElement (channel);}* *#endif* * * * void __attribute__((noinline))* * TYPED_NAME(producePtrValue)(int channel, TYPE* elem)* * {Q->addPtrElement (channel, (void*)elem);}* * * * TYPE* __attribute__((noinline))* * TYPED_NAME(consumePtrValue)(int channel)* * {return (TYPE*) Q->removePtrElement (channel);}* * * *#ifdef FP_TYPE* * void __attribute__((noinline))* * TYPED_NAME(produceFPValue)(int channel, TYPE elem)* * {Q->addFPElement (channel, (double)elem);}* * * * TYPE __attribute__((noinline))* * TYPED_NAME(consumeFPValue)(int channel)* * {return (TYPE) Q->removeFPElement (channel);}* *#endif* *}* In order to define a set of functions for a type, I can simply insert the following lines on my original library: *#define INT_TYPE* *#define TYPE char* *#define TYPED_NAME(x) i8_##x* *#include "queue_wrappers.h"* *#undef TYPE* *#undef TYPED_NAME* *#undef INT_TYPE* And, for this example, the functions i8_produceValue, i8_consumeValue, i8_producePtrValue and i8_consumePtrValue should be defined. Well, the problem is that all those functions are being defined, indeed, but every function inside the #ifdef INT_TYPE's preprocessor flag has only a call to llvm.trap() function inside its body =/ And this is only happening to the functions (*)_consumeValue and (*)_produceValue: all the other functions [(*)_consumePtrValue, (*)_producePtrValue, (*)_consumeFPValue and (*)_produceFPValue] has their bodies correctly defined on the resultant bc file. Since the only difference between their implementation on the queue is the type defined inside the queue (long for integer types, void* for pointers and double for floating point numbers), does anyone have any ideia why I am having this issue with integers? PS: I tried to implement the integer type functions using C++ templates, and it was as I expected: the functions for integer types were created with their correct set of instructions inside. However, when using templates, the names of the functions are being messed up (which was the issue I was trying to avoid in the first place). Thanks in advance, -- Cristianno Martins PhD Student of Computer Science University of Campinas cmartins at ic.unicamp.br <cristiannomartins at hotmail.com> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130514/4bf331f5/attachment.html>
On Tue, May 14, 2013 at 11:42 AM, Cristianno Martins < cristiannomartins at gmail.com> wrote:> Hello there, > > I'm trying to use a simple implementation of a queue (my own > implementation of it, actually), and I'm trying to use the functions > defined on my queue class inside some llvm-ir code. Unfortunately, the > names of the functions are being messed up, then I created some function > wrappers just to avoid having to deal with the C++ weird function renaming. >FYI, this "weird function renaming" is traditionally called "name mangling" :) What frontend are you using? Clang or g++ w/dragonegg or something else?> So, to easily wrapper the class, I wrote a queue_wrapper.h library, which, > basically, has the following code (where Q is a reference to my queue, and > the channel is not really important): >The problem is probably in the definition of your queue itself. The code below generates completely reasonable output for me, with... struct q { void addElement(int, char); char removeElement(int); void addPtrElement(int, void*); void *removePtrElement(int); } *Q;> *extern "C" { * > > *#ifdef INT_TYPE* > > * void __attribute__((noinline))* > > * TYPED_NAME(produceValue)(int channel, TYPE elem)* > > * {Q->addElement (channel, (long)elem);}* > > * > * > > * TYPE __attribute__((noinline))* > > * TYPED_NAME(consumeValue)(int channel)* > > * {return (TYPE) Q->removeElement (channel);}* > > *#endif* > > * > * > > * void __attribute__((noinline))* > > * TYPED_NAME(producePtrValue)(int channel, TYPE* elem)* > > * {Q->addPtrElement (channel, (void*)elem);}* > > * > * > > * TYPE* __attribute__((noinline))* > > * TYPED_NAME(consumePtrValue)(int channel)* > > * {return (TYPE*) Q->removePtrElement (channel);}* > > * * > > *#ifdef FP_TYPE* > > * void __attribute__((noinline))* > > * TYPED_NAME(produceFPValue)(int channel, TYPE elem)* > > * {Q->addFPElement (channel, (double)elem);}* > > * > * > > * TYPE __attribute__((noinline))* > > * TYPED_NAME(consumeFPValue)(int channel)* > > * {return (TYPE) Q->removeFPElement (channel);}* > > *#endif* > > *}* > > > In order to define a set of functions for a type, I can simply insert the > following lines on my original library: > > *#define INT_TYPE* > > *#define TYPE char* > > *#define TYPED_NAME(x) i8_##x* > > *#include "queue_wrappers.h"* > > *#undef TYPE* > > *#undef TYPED_NAME* > > *#undef INT_TYPE* > > And, for this example, the functions i8_produceValue, i8_consumeValue, > i8_producePtrValue and i8_consumePtrValue should be defined. > > Well, the problem is that all those functions are being defined, indeed, > but every function inside the #ifdef INT_TYPE's preprocessor flag has only > a call to llvm.trap() function inside its body =/ >One possibility is that you have a function which returns non-void but is missing a 'return' statement. Are you getting any -Wreturn-type warnings? Do you see the call to llvm.trap if you build with no optimizations? If not, can you provide the IR for that?> And this is only happening to the functions (*)_consumeValue and > (*)_produceValue: all the other functions [(*)_consumePtrValue, > (*)_producePtrValue, (*)_consumeFPValue and (*)_produceFPValue] has their > bodies correctly defined on the resultant bc file. > > Since the only difference between their implementation on the queue is the > type defined inside the queue (long for integer types, void* for pointers > and double for floating point numbers), does anyone have any ideia why I am > having this issue with integers? > > > PS: I tried to implement the integer type functions using C++ templates, > and it was as I expected: the functions for integer types were created with > their correct set of instructions inside. However, when using templates, > the names of the functions are being messed up (which was the issue I was > trying to avoid in the first place). > > Thanks in advance, > > > -- > Cristianno Martins > PhD Student of Computer Science > University of Campinas > cmartins at ic.unicamp.br > <cristiannomartins at hotmail.com> > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130514/37eb2bb2/attachment.html>
Hi Richard, First of all, thank you so much for your reply ;) <cristiannomartins at hotmail.com> On Tue, May 14, 2013 at 3:36 PM, Richard Smith <richard at metafoo.co.uk>wrote:> On Tue, May 14, 2013 at 11:42 AM, Cristianno Martins < > cristiannomartins at gmail.com> wrote: > >> Hello there, >> >> I'm trying to use a simple implementation of a queue (my own >> implementation of it, actually), and I'm trying to use the functions >> defined on my queue class inside some llvm-ir code. Unfortunately, the >> names of the functions are being messed up, then I created some function >> wrappers just to avoid having to deal with the C++ weird function renaming. >> > > FYI, this "weird function renaming" is traditionally called "name > mangling" :) >Thanks for the info, man =)> > What frontend are you using? Clang or g++ w/dragonegg or something else? >I'm currently using clang++ 3.4 (directly from its git repo).> > >> So, to easily wrapper the class, I wrote a queue_wrapper.h library, >> which, basically, has the following code (where Q is a reference to my >> queue, and the channel is not really important): >> > > The problem is probably in the definition of your queue itself. The code > below generates completely reasonable output for me, with... > > struct q { > void addElement(int, char); > char removeElement(int); > void addPtrElement(int, void*); > void *removePtrElement(int); > } *Q; >I just thought it was a little strange that the same code could generate the correct LLVMIR if I've written the wrappers using templates, but only a call to llvm.trap (and only for a subset of the functions) if I use defines =/> *extern "C" { * >> >> *#ifdef INT_TYPE* >> >> * void __attribute__((noinline))* >> >> * TYPED_NAME(produceValue)(int channel, TYPE elem)* >> >> * {Q->addElement (channel, (long)elem);}* >> >> * >> * >> >> * TYPE __attribute__((noinline))* >> >> * TYPED_NAME(consumeValue)(int channel)* >> >> * {return (TYPE) Q->removeElement (channel);}* >> >> *#endif* >> >> * >> * >> >> * void __attribute__((noinline))* >> >> * TYPED_NAME(producePtrValue)(int channel, TYPE* elem)* >> >> * {Q->addPtrElement (channel, (void*)elem);}* >> >> * >> * >> >> * TYPE* __attribute__((noinline))* >> >> * TYPED_NAME(consumePtrValue)(int channel)* >> >> * {return (TYPE*) Q->removePtrElement (channel);}* >> >> * * >> >> *#ifdef FP_TYPE* >> >> * void __attribute__((noinline))* >> >> * TYPED_NAME(produceFPValue)(int channel, TYPE elem)* >> >> * {Q->addFPElement (channel, (double)elem);}* >> >> * >> * >> >> * TYPE __attribute__((noinline))* >> >> * TYPED_NAME(consumeFPValue)(int channel)* >> >> * {return (TYPE) Q->removeFPElement (channel);}* >> >> *#endif* >> >> *}* >> >> >> In order to define a set of functions for a type, I can simply insert the >> following lines on my original library: >> >> *#define INT_TYPE* >> >> *#define TYPE char* >> >> *#define TYPED_NAME(x) i8_##x* >> >> *#include "queue_wrappers.h"* >> >> *#undef TYPE* >> >> *#undef TYPED_NAME* >> >> *#undef INT_TYPE* >> >> And, for this example, the functions i8_produceValue, i8_consumeValue, >> i8_producePtrValue and i8_consumePtrValue should be defined. >> >> Well, the problem is that all those functions are being defined, indeed, >> but every function inside the #ifdef INT_TYPE's preprocessor flag has only >> a call to llvm.trap() function inside its body =/ >> > One possibility is that you have a function which returns non-void but is > missing a 'return' statement. Are you getting any -Wreturn-type warnings? > Do you see the call to llvm.trap if you build with no optimizations? If > not, can you provide the IR for that? >I'm using -O4 as the optimization level for this code. Curiously, I could generate a bc file from my queue.h library (simply creating a queue.cpp file with nothing more than including its respective header file) and the result was a bc file with all the correct function bodies (none of them was referring to llvm.trap). So, for now, I think I'll be using this bc file as my starting point =)> And this is only happening to the functions (*)_consumeValue and >> (*)_produceValue: all the other functions [(*)_consumePtrValue, >> (*)_producePtrValue, (*)_consumeFPValue and (*)_produceFPValue] has their >> bodies correctly defined on the resultant bc file. >> >> Since the only difference between their implementation on the queue is >> the type defined inside the queue (long for integer types, void* for >> pointers and double for floating point numbers), does anyone have any ideia >> why I am having this issue with integers? >> >> >> PS: I tried to implement the integer type functions using C++ templates, >> and it was as I expected: the functions for integer types were created with >> their correct set of instructions inside. However, when using templates, >> the names of the functions are being messed up (which was the issue I was >> trying to avoid in the first place). >> >> Thanks in advance, >> >> >> -- >> Cristianno Martins >> PhD Student of Computer Science >> University of Campinas >> cmartins at ic.unicamp.br >> <cristiannomartins at hotmail.com> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >> >-- Cristianno Martins PhD Student of Computer Science University of Campinas cmartins at ic.unicamp.br -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130514/21067d24/attachment.html>