<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jul 21, 2014 at 9:22 AM, David Jones <span dir="ltr"><<a href="mailto:djones@xtreme-eda.com" target="_blank">djones@xtreme-eda.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div>I am writing a compiler using LLVM 3.2 to generate native code (currently x86-64) from IR. The native code will be linked by the system linker (not a JIT).<br>
<br></div>The compiler generates calls to a run-time library to perform many operations. Therefore, each Module that I generate needs to be have declarations for all of these run-time functions added to it.<br>
<br></div><div>Question: is this true? I am assuming that LLVM works like a C++ compiler: before you can call a function from anywhere in a compilation unit, you need its prototype in scope. <br></div></div></div></div></div>
</div></blockquote><div><br></div><div>Yes.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div><div><div><div><div></div><div><br></div>Initially, I did this by calling Function::Create for each declaration I wanted to make. However, this is starting to "not scale".<br></div></div></div>
</div></div></blockquote><div><br></div><div>I also started out on this path, but once there are a lot of runtime functions it creates a lot of code to gen them, which is what I presume you mean by "not scale". </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div><div>
<br></div>I also want to experiment with defining some of these library functions using LLVM IR directly. I can then have LLVM inline and optimize calls to these functions. Given that many of the arguments to the functions are constants, there is plenty of opportunity for loop unrolling and optimization.<br>
<br></div>To this end, I would like to read LLVM bitcode into an existing module. The bitcode would contain declarations for all of my library functions, plus definitions for anything I want to try to inline and optimize.<br>
</div></div></div></blockquote><div><br></div><div>Being unable to find any articles that suggested one method or another, I do this, which works well for what I am doing:</div><div><br></div><div>I have a runtime library written in C++ and compiled with clang.</div>
<div><br></div><div>I have a project module with a single .cpp file, that includes all the relevant headers to pick up code inlined the .h files, and which uses enough runtime methods for the inline code to be generated etc. In practice this is not that much code.</div>
<div><br></div><div>I compile that .cpp file to a .bc file runtimeinterface.bc</div><div><br></div><div>When it comes to code gen time in my compiler, I first load runtimeinterface.bc and compile it:</div><div><br></div><div>
this->codeModule = llvm::ParseIRFile(libFile, ed, this->Context);<br></div><div><br></div><div>I then use setModuleIdentifier() to change the module ID appropriately</div><div><br></div><div>I then locate the 'junk' added by clang, such as the GLOBAL__I constructor stuff and my dummy runtime interface function and perform removeFromParent().</div>
<div><br></div><div>I now have declarations for all the runtime methods, which I need not hard code in to the compiler as well as having the IR for the internal link once inlinable functions in my runtime .h files. Use module->getFunction() to find the function definitions and the approriate other getXXX calls in the Module class. Use assert so that you can detect in debug builds when someone changed the runtime underneath you (you cannot find the function or definition any more)</div>
<div><br></div><div>I then start code generation in to this module as if it were an empty one as is the usual case.</div><div><br></div><div>I have to admit that I just dreamed this method up after casting around with Google quite a bit and I can see a few possible issue with this such as being possibly dependent on the version of clang that is used. This works for me because I am in control of the end use environment however and can ensure that the versions of the components being used are the correct ones.</div>
<div><br></div><div>If anyone with greater experience in LLVM than I have sees other issues, then please pipe up!</div><div><br></div><div>Cheers,</div><div><br></div><div>Jim</div></div></div></div>