[LLVMdev] Queue implementation is being trapped

Cristianno Martins cristiannomartins at gmail.com
Tue May 14 15:33:24 PDT 2013


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>


More information about the llvm-dev mailing list