[LLVMdev] Adding Intrinsics for custom processor (frotend, problem)

Gil Dogon gil.dogon at mobileye.com
Wed Mar 4 00:19:19 PST 2009


Luke Dalessandro wrote:

> Gil, it's really easy to add builtins to the llvm-gcc frontend and have 
> them auto-magically converted to the llvm intrinsic versions. The main 
> problem with this is that you end up with a non-standard front end that 
> you have to somehow distribute to the people who need it. There may be 
> funny licensing problems, etc... I don't really know.
>
> Here's a quick how-to based on adding an intrinsic which we want to look 
> like:
>
>    void* llvm.my.foo(void**, void*)
>
> 1) Get the llvm-gcc source from svn.
>
> 2) Edit the file gcc/builtins.def
>
>         The comments at the top are helpful, read them.
>
>     a) Add a macro that looks something like
>
> #undef DEF_MY_BUILTIN
> #define DEF_MY_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
>    DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_MD, TYPE, TYPE,    \
>                 false, false, true, ATTRS, false, true)
>
>         You can figure out what this means based on the comments in the
>         builtins.def file. Essentially the important magic is the
>         BUILT_IN_MD flag trickles through and gets your llvm intrinsic
>         generated automatically. Also, all of your builtins will be
>         prefixed with __builtin_ --- you could change this if you wanted.
>
>     b) Add an include directive at the bottom of the file,
>        "#include my-builtins.def"
>
>         This isn't strictly necessary, you could just add your builtins
>         directly to the builtins.def file, but it helps keep them
>         separate.
>
> 3) Edit the gcc/Makefile.in file (not necessary if you skipped b above)
>
>     a) Find the BUILTINS_DEF line and add your "my-builtins.def" file.
>
> 4) Create and edit gcc/my-builtins.def
>
>         The file gcc/builtin-types.def lists the macros you can use to
>         declare the function types for your macros, and
>         gcc/builtin-attrs.def lists the attributes, though I've only ever
>         used ATTR_NOTHROW_LIST.
>
>     a) Use the macro you defined earlier to generate your builtins, in
>        our example case it is
>
> DEF_MY_BUILTIN (BUILT_IN_MY_FOO, "my_foo", \
>     BT_FN_PTR_PTRPTR_PTR, ATTR_NOTHROW_LIST)
>
>         This is straightforward, the first parameter is an ID for your
>         builtin within gcc -- it just needs to be unique. The second is
>         the "name" of your builtin, which will be prepended with
>         "__builtin_" based on our definition of DEF_MY_BUILTIN. The third
>         is the function type from gcc/builtin-types.def, (here a function
>         taking a pointer to a pointer, and a pointer, and returning a
>         pointer). The fourth is the function attributes which I don't
>         really know anything about.
>
>     b) In our case here, the correct function type didn't exist, so an
>        additional step is to edit gcc/builtin-types.def. I would add the
>        following in the section where the 2-parameter types are defined.
>
> DEF_FUNCTION_TYPE_2 (BT_FN_PTR_PTRPTR_PTR, BT_PTR, BT_PTR_PTR, BT_PTR)
>
>        That's all you need to change within llvm-gcc (I think, I didn't
>        bug-test the instructions, but I'm pretty sure it will work.
>
> 5) Get llvm source from svn
>
> 6) Edit include/llvm/Intrinsics.td
>
>        You can either add your intrinsics directly, or just add an
>        include to your own file. Here I'm adding them directly.
>
>     a) Add a definition of your intrinsic. In our case, it looks like
>
> def int_my_foo : Intrinsic<[llvm_ptr_ty],
>                             [llvm_ptrptr_ty, llvm_ptr_ty]>,
>                   GCCBuiltin<"__builtin_my_foo">;
>
>        Clearly the fun here is the GCCBuiltin tag which is what gets
>        everything to /just work/.
>
> 7) Build llvm.
>
> 8) Configure llvm-gcc with your modified llvm binary directory as it's
>     llvm directory.
>
> 9) Build llvm-gcc.
>
> 10) Configure llvm with the llvm-gcc directory.
>
> 11) Rebuild llvm.
>
> And voila, users can now use your gcc builtin as
> "void* addr = __builtin_my_foo(&bar, bar)" and compilation will 
> naturally generate a llvm.my.foo for it.
>
> One caveat is that I've never actually done this with parameters that 
> have address types, but ints, voids, and longs work fine. There's a 
> routine in llvm-gcc inside of "gcc/llvm-convert.cpp" called 
> TreeToLLVM::EmitBuiltinCall that does the actual conversion, you may 
> need to do some work in that area. My guess is that it will /just work/ 
> though.
>
> Hope this helps. There may be other ways to do this using gcc asm tags 
> and such, but I know that this works and gets parameters in the right 
> place, etc.
>
> Let me know if there are any bugs in the instructions.
>
> Luke
>
>   
Well Luke , First I just wanted to thank you for your effort , even 
though I am not likely to follow what you suggested, It seems very 
detailed, and maybe
even it can be added to the LLVM documentation (I think that currently 
there is no document about llvm-gcc hacking) and help future compiler 
writers .. :-) .

I decide to avoid this approach mainly because of the problem that 
you've mentioned above. Adding source level llvm-gcc frontend to
our distribution is too much of a headache right now, and also increases 
build time dramatically, so I'd like to avoid it.

What I did was a rather quick-and-dirty hack which I know is 
non-standard, but nevertheless quite painless and straightforward :

A. I define my proprietary intrinsics in an include file something like

int __VMPINTR__something(....) ;

B. I define a corresponding int_vmp_something in llvms Intrinsics.td .

C. I changed Function::getIntrinsicID by adding the following :

unsigned vmpi=VMP_intrinsic(Name,Len);
if(vmpi)
return vmpi;

where VMP_intrinsic function code recognizes my proprietary 
'__VMPINTR__' style intrinsic names.

I know also that for Chris or other LLVM tblgen masters it could be 
quite easy to make this VMP_intrinsic function code
tblgened , but I will be content to manually edit it as I go along .(I 
do not expect to have that many of them) ...




More information about the llvm-dev mailing list