Gil Dogon
2009-Mar-03 09:53 UTC
[LLVMdev] Adding Intrinsics for custom processor (frotend problem)
As mentioned in an earlier mail, I am working on an LLVM backend for a custom processor based on MIPS. My problem is how to extend LLVM to support some esoteric/non-standard feature of the underlying hardware. I saw in the "Extending LLVM" document, that the easiest / most common way to do this was using an intrinsic function, and examples of the technique abound (all SSE for example). My problem though as mentioned before is that the frontend support for intrinsics, is undocumented, and implemented in llvm-gcc which I prefer not to hack with (I use a binary precompiled one). As far as I could see it supports the intrinsics using gcc style __builtin_ function names. Currently what I think to do , is the following : 1. Define my intrinsics in a special (which would be preincluded in our build system) .h file (using whatever name convention I want) 2. Then I need to add a pass to llvm which will translate the names of those intrinsics to llvm style names , since LLVM intrinsics start with "llvm." which makes them non legal as "C" identifiers. I have two questions : 1. Is that the right way to go, or is there a simpler/more standard way to have frontend support for new architecture intrinsics ? 2. If thats the simplest way , I would like to have a quick advice on how to write the rather trivial pass described in '2'. I guess that I need to replace a given Function object with an allmost identical one, but with a different name (the "llvm.something' name of the intrisic) What is the correct code to do this ?
Richard Osborne
2009-Mar-03 11:12 UTC
[LLVMdev] Adding Intrinsics for custom processor (frotend problem)
Personally I would just modify the frontend - it's not that hard once you know where to look . In this case all you need to do is add the declaration of your builtin to the TARGET_INIT_BUILTINS target hook (see the gcc internals manual) defined in the gcc/config directory corresponding to your target. If the name the the declaration matches the name used with GCCBuiltin in the intrinsics td file then any calls to the gcc builtin in the source should get automatically translated to the calls to the LLVM intrinsic. Gil Dogon wrote:> As mentioned in an earlier mail, I am working on an LLVM backend for a > custom processor based on MIPS. > My problem is how to extend LLVM to support some esoteric/non-standard > feature of the underlying hardware. > I saw in the "Extending LLVM" document, that the easiest / most common > way to do this was using an intrinsic function, > and examples of the technique abound (all SSE for example). > My problem though as mentioned before is that the frontend support for > intrinsics, is undocumented, and implemented > in llvm-gcc which I prefer not to hack with (I use a binary > precompiled one). As far as I could see it supports the > intrinsics using gcc style __builtin_ function names. > > Currently what I think to do , is the following : > > 1. Define my intrinsics in a special (which would be preincluded in our > build system) .h file (using whatever name convention I want) > 2. Then I need to add a pass to llvm which will translate the names of > those intrinsics to llvm style names , since > LLVM intrinsics start with "llvm." which makes them non legal as "C" > identifiers. > > I have two questions : > > 1. Is that the right way to go, or is there a simpler/more standard way > to have frontend support for new architecture intrinsics ? > > 2. If thats the simplest way , I would like to have a quick advice on > how to write the rather trivial pass described in '2'. > I guess that I need to replace a given Function object with an > allmost identical one, but with a different name (the "llvm.something' name > of the intrisic) What is the correct code to do this ? > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-- Richard Osborne | XMOS http://www.xmos.com
Luke Dalessandro
2009-Mar-03 14:16 UTC
[LLVMdev] Adding Intrinsics for custom processor (frotend problem)
Gil Dogon wrote:> I have two questions : > > 1. Is that the right way to go, or is there a simpler/more standard way > to have frontend support for new architecture intrinsics ?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> 2. If thats the simplest way , I would like to have a quick advice on > how to write the rather trivial pass described in '2'. > I guess that I need to replace a given Function object with an > allmost identical one, but with a different name (the "llvm.something' name > of the intrisic) What is the correct code to do this ? > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Luke Dalessandro
2009-Mar-03 14:30 UTC
[LLVMdev] Adding Intrinsics for custom processor (frotend problem)
Richard Osborne wrote:> Personally I would just modify the frontend - it's not that hard once > you know where to look . In this case all you need to do is add the > declaration of your builtin to the TARGET_INIT_BUILTINS target hook (see > the gcc internals manual) defined in the gcc/config directory > corresponding to your target. If the name the the declaration matches > the name used with GCCBuiltin in the intrinsics td file then any calls > to the gcc builtin in the source should get automatically translated to > the calls to the LLVM intrinsic.Gil, this sounds like a much easier strategy than mine for your target-specific approach. The builtins that I added for my own purpose aren't target specific, they're more along the lines of the OpenMP stuff so I was looking for a general place to put them. Luke> > Gil Dogon wrote: >> As mentioned in an earlier mail, I am working on an LLVM backend for a >> custom processor based on MIPS. >> My problem is how to extend LLVM to support some esoteric/non-standard >> feature of the underlying hardware. >> I saw in the "Extending LLVM" document, that the easiest / most common >> way to do this was using an intrinsic function, >> and examples of the technique abound (all SSE for example). >> My problem though as mentioned before is that the frontend support for >> intrinsics, is undocumented, and implemented >> in llvm-gcc which I prefer not to hack with (I use a binary >> precompiled one). As far as I could see it supports the >> intrinsics using gcc style __builtin_ function names. >> >> Currently what I think to do , is the following : >> >> 1. Define my intrinsics in a special (which would be preincluded in our >> build system) .h file (using whatever name convention I want) >> 2. Then I need to add a pass to llvm which will translate the names of >> those intrinsics to llvm style names , since >> LLVM intrinsics start with "llvm." which makes them non legal as "C" >> identifiers. >> >> I have two questions : >> >> 1. Is that the right way to go, or is there a simpler/more standard way >> to have frontend support for new architecture intrinsics ? >> >> 2. If thats the simplest way , I would like to have a quick advice on >> how to write the rather trivial pass described in '2'. >> I guess that I need to replace a given Function object with an >> allmost identical one, but with a different name (the "llvm.something' name >> of the intrisic) What is the correct code to do this ? >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> > >
Chris Lattner
2009-Mar-03 17:39 UTC
[LLVMdev] Adding Intrinsics for custom processor (frotend problem)
On Mar 3, 2009, at 1:53 AM, Gil Dogon wrote:> My problem though as mentioned before is that the frontend support > for > intrinsics, is undocumented, and implemented > in llvm-gcc which I prefer not to hack with (I use a binary > precompiled one).As others have mentioned, hacking the front-end isn't that hard. In any case though, please be aware that a precompiled binary for a non- MIPS target won't produce correct code if you are (for example) using an x86 front-end and forcing llc to generate mips code with llc - march=mips. The front-end does type layout and knows very ABI things that have to be right for mips. -Chris
Seemingly Similar Threads
- [LLVMdev] Adding Intrinsics for custom processor (frotend, problem)
- [LLVMdev] Adding Intrinsics for custom processor (frotend problem)
- [LLVMdev] Adding Intrinsics for custom processor (frotend problem)
- [LLVMdev] A simple question regarding LLVM intrinsics.
- [LLVMdev] A partial reply to the previous question and another one