{"id":1546,"date":"2017-03-27T06:32:46","date_gmt":"2017-03-27T10:32:46","guid":{"rendered":"http:\/\/codinggorilla.domemtech.com\/?p=1546"},"modified":"2017-08-29T12:33:19","modified_gmt":"2017-08-29T16:33:19","slug":"swig-llvm-llilc","status":"publish","type":"post","link":"http:\/\/165.227.223.229\/index.php\/2017\/03\/27\/swig-llvm-llilc\/","title":{"rendered":"Swig, LLVM, LLILC"},"content":{"rendered":"<p>As I work to enhance Campy, a C# library for GPU programming I wrote, I&#8217;m trying to capitalize on some new code from the <a href=\"https:\/\/dotnetfoundation.org\/\" target=\"_blank\" rel=\"noopener\">NET Foundation Projects<\/a>. These include <a href=\"https:\/\/dotnetfoundation.org\/llilc\" target=\"_blank\" rel=\"noopener\">LLILC<\/a>, a MS IL compiler based on LLVM. I want to be able to use some of the APIs in LLVM to perform SSA analysis rather than roll my own. But, that turns out to be easier said than done. This note describes some of the issues in building LLILC, LLVM, and SWIG.<\/p>\n<p><!--more--><\/p>\n<hr \/>\n<h3>SWIG<\/h3>\n<p>Simplified Wrapper and Interface Generator (SWIG) is a tool to generate a wrapper in one programming language from the API written in another language. SWIG has the capability to parse C\/C++ header files and output C# classes and native C interfaces that perform PInvoke calls for C#. It is a reasonable choice when one wants to create a C# interface to LLVM, or any C++ API for that matter.<\/p>\n<p>However, SWIG is baroque, if not outright grotesque. The rules for type mapping C++ to C# are difficult to understand, even with full debugging enabled (-debug-memory -debug-classes -debug-symtabs -debug-tmsearch -debug-tmused -debug-symbols -debug-csymbols -debug-lsymbols -debug-typemap -debug-template). <a href=\"http:\/\/www.nickdarnell.com\/swig-and-a-miss\/\" target=\"_blank\" rel=\"noopener\">Conversion of basics<\/a> like <em>void* -&gt; IntPtr<\/em> are not handled out of the box.<\/p>\n<p>While SWIG can run on Windows, I find that it is easier to build in a Linux shell, and call the command-line tool via <a href=\"https:\/\/msdn.microsoft.com\/en-us\/commandline\/wsl\/install_guide\" target=\"_blank\" rel=\"noopener\">WSL<\/a>, e.g., <em>bash -c swig &#8230;.\u00c2\u00a0<\/em>That said, Swig is one of those tools in which you sometimes need to debug the code in order to understand the type mapping rules&#8211;not that that will be easy as almost every object in SWIG is encoded as what the authors call a <em><a href=\"https:\/\/github.com\/swig\/swig\/blob\/master\/Source\/DOH\/doh.h\" target=\"_blank\" rel=\"noopener\">DOH object<\/a><\/em>&#8212; which is just a <em>void*<\/em>.<\/p>\n<h4>Installation:<\/h4>\n\n<h4>Example:<\/h4>\n<p><br \/>\n(Note! If you make your own API, make sure to update the .SLN file with a &lt;ProjectReference&gt; entry. See <a href=\"https:\/\/blogs.msdn.microsoft.com\/kirillosenkov\/2015\/04\/04\/how-to-have-a-project-reference-without-referencing-the-actual-binary\/\" target=\"_blank\" rel=\"noopener\">https:\/\/blogs.msdn.microsoft.com\/kirillosenkov\/2015\/04\/04\/how-to-have-a-project-reference-without-referencing-the-actual-binary\/<\/a>)<\/p>\n<h4>Resources:<\/h4>\n<p><a href=\"http:\/\/swig.org\" target=\"_blank\" rel=\"noopener\">http:\/\/swig.org<\/a><br \/>\n<a href=\"https:\/\/sourceforge.net\/projects\/swig\/\" target=\"_blank\" rel=\"noopener\">https:\/\/sourceforge.net\/projects\/swig\/<\/a><\/p>\n<h4>Documentation:<\/h4>\n<p><a href=\"http:\/\/swig.org\/Doc3.0\/SWIGDocumentation.html\" target=\"_blank\" rel=\"noopener\">http:\/\/swig.org\/Doc3.0\/SWIGDocumentation.html<\/a><\/p>\n<hr \/>\n<h3>Swigged LLVM<\/h3>\n<p>LLVM (Low Level Virtual Machine) is a compiler infrastructure project, and is the defacto tool for compiler writers nowadays (which is too bad, because it lacks some flexibility, and it is better for people to learn and know compiler theory).<\/p>\n<p>Building LLVM on Windows is well documented. However, if you want to call LLVM from C#, you will need to use SWIG to generate a thunking layer, or write your own. In fact, others have done so: <a href=\"https:\/\/github.com\/Microsoft\/LLVMSharp\" target=\"_blank\" rel=\"noopener\">LLVMSharp<\/a> and <a href=\"https:\/\/github.com\/xen2\/SharpLang\" target=\"_blank\" rel=\"noopener\">SharpLang<\/a>. However, <a href=\"https:\/\/github.com\/xen2\/SharpLang\" target=\"_blank\" rel=\"noopener\">SharpLang<\/a> is no longer active (<a href=\"https:\/\/twitter.com\/SharpLangDev\" target=\"_blank\" rel=\"noopener\">as of November 2015<\/a>), and <a href=\"https:\/\/github.com\/Microsoft\/LLVMSharp\" target=\"_blank\" rel=\"noopener\">LLVMSharp<\/a>\u00c2\u00a0is not quite up to date (which may not matter if one is using the LLVM-C API), and does not expose the SSA analysis API.<\/p>\n<p>Using SWIG to generate a C# API does require some finesse. A basic SWIG input file might be:<br \/>\n<br \/>\nHowever, this will result in many poorly named C# files, e.g.,\u00c2\u00a0<em>SWIGTYPE_p_LLVMTypeRef.cs<\/em>. Therefore, one should apply SWIG <em>%typemap&#8217;s<\/em> to rename the types appropriately. <a href=\"https:\/\/github.com\/xen2\/SharpLang\" target=\"_blank\" rel=\"noopener\">SharpLang<\/a> uses this approach, and I&#8217;ve updated the rewrite rules slightly to handle more of the LLVM API. <a href=\"https:\/\/github.com\/Microsoft\/ClangSharp\" target=\"_blank\" rel=\"noopener\">LLVMSharp<\/a> uses a different approach, using a home-grown tool\u00c2\u00a0to parse C\/C++ header files and convert them into wrappers.<\/p>\n<p><em>NB: SWIG\/LLVM is so difficult to understand, that I\u00c2\u00a0will be exploring it in a later post in this blog.<\/em><\/p>\n<h4>Installation:<\/h4>\n\n<h4>Example:<\/h4>\n<p><a href=\"https:\/\/github.com\/kaby76\/swigged-llvm\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/kaby76\/swigged-llvm<\/a><\/p>\n<h4>Resources:<\/h4>\n<p><a href=\"http:\/\/llvm.org\/\" target=\"_blank\" rel=\"noopener\">http:\/\/llvm.org\/<\/a><br \/>\n<a href=\"https:\/\/github.com\/llvm-mirror\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/llvm-mirror<\/a><br \/>\n<a href=\"http:\/\/www.telegrid.enea.it\/SGI\/Altix\/Typemaps.pdf\" target=\"_blank\" rel=\"noopener\">http:\/\/www.telegrid.enea.it\/SGI\/Altix\/Typemaps.pdf<\/a><br \/>\n<a href=\"http:\/\/swig.org\/Doc3.0\/SWIGDocumentation.html\" target=\"_blank\" rel=\"noopener\">http:\/\/swig.org\/Doc3.0\/SWIGDocumentation.html<\/a><\/p>\n<h4>Documentation:<\/h4>\n<p><a href=\"http:\/\/llvm.org\/docs\/\" target=\"_blank\" rel=\"noopener\">http:\/\/llvm.org\/docs\/<\/a><\/p>\n<hr \/>\n<h3>LLILC<\/h3>\n<p>LLILC is a compiler backend for MS IL based on LLVM. It was started by Microsoft to address ahead-of-time (AOT) compilation of MS IL, different from the JIT compiler, <a href=\"https:\/\/blogs.msdn.microsoft.com\/dotnet\/2013\/09\/30\/ryujit-the-next-generation-jit-compiler-for-net\/\" target=\"_blank\" rel=\"noopener\">RyuJIT<\/a>, the compiler backend since Net 4.6. The JIT compiler is not LLVM based.<\/p>\n<p>The main use I would have for LLILC is to convert MS IL into LLVM for code analysis. However, I am not interested in code generation; I want to use the SSA graph to answer some basic questions of what code is referenced when calling a Campy parallel-for.<\/p>\n<p>Unfortunately, LLILC is code that is difficult to understand. LLILC merges the parsing of MSIL, construction of a control-flow graph, and translation of MSIL into LLVM IR with each instruction that is parsed. Further,\u00c2\u00a0LLILC is CoreCLR dependent, which means this cannot be used with a NET Framework application (the reverse is possible).<\/p>\n<h4>Installation:<\/h4>\n<p>See\u00c2\u00a0<a href=\"https:\/\/github.com\/dotnet\/llilc\/blob\/master\/Documentation\/Getting-Started-For-Windows.md\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/dotnet\/llilc\/blob\/master\/Documentation\/Getting-Started-For-Windows.md<\/a><\/p>\n<h4>Resources:<\/h4>\n<p><a href=\"https:\/\/dotnetfoundation.org\/llilc\" target=\"_blank\" rel=\"noopener\">https:\/\/dotnetfoundation.org\/llilc<\/a><br \/>\n<a href=\"https:\/\/github.com\/dotnet\/llilc\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/dotnet\/llilc<\/a><br \/>\n<a href=\"https:\/\/github.com\/dotnet\/coreclr\/blob\/master\/Documentation\/botr\/ryujit-overview.md\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/dotnet\/coreclr\/blob\/master\/Documentation\/botr\/ryujit-overview.md<\/a><br \/>\n<a href=\"http:\/\/www.c-sharpcorner.com\/UploadFile\/b26131\/ryujit-the-64-bit-compiler-for-net\/\" target=\"_blank\" rel=\"noopener\">http:\/\/www.c-sharpcorner.com\/UploadFile\/b26131\/ryujit-the-64-bit-compiler-for-net\/<\/a><br \/>\n<a href=\"https:\/\/github.com\/dotnet\/coreclr\/tree\/master\/src\/jit\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/dotnet\/coreclr\/tree\/master\/src\/jit<\/a><br \/>\n<a href=\"http:\/\/blog.llvm.org\/2015\/04\/llilc-llvm-based-compiler-for-dotnet.html\" target=\"_blank\" rel=\"noopener\">http:\/\/blog.llvm.org\/2015\/04\/llilc-llvm-based-compiler-for-dotnet.html<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As I work to enhance Campy, a C# library for GPU programming I wrote, I&#8217;m trying to capitalize on some new code from the NET Foundation Projects. These include LLILC, a MS IL compiler based on LLVM. I want to be able to use some of the APIs in LLVM to perform SSA analysis rather &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/165.227.223.229\/index.php\/2017\/03\/27\/swig-llvm-llilc\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Swig, LLVM, LLILC&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[],"tags":[],"_links":{"self":[{"href":"http:\/\/165.227.223.229\/index.php\/wp-json\/wp\/v2\/posts\/1546"}],"collection":[{"href":"http:\/\/165.227.223.229\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/165.227.223.229\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/165.227.223.229\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/165.227.223.229\/index.php\/wp-json\/wp\/v2\/comments?post=1546"}],"version-history":[{"count":0,"href":"http:\/\/165.227.223.229\/index.php\/wp-json\/wp\/v2\/posts\/1546\/revisions"}],"wp:attachment":[{"href":"http:\/\/165.227.223.229\/index.php\/wp-json\/wp\/v2\/media?parent=1546"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/165.227.223.229\/index.php\/wp-json\/wp\/v2\/categories?post=1546"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/165.227.223.229\/index.php\/wp-json\/wp\/v2\/tags?post=1546"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}