<div dir="ltr">On Tue, Nov 5, 2013 at 2:39 PM, Rob Stewart <span dir="ltr"><<a href="mailto:robstewart57@gmail.com" target="_blank">robstewart57@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">On 3 November 2013 05:44, Sean Silva <<a href="mailto:chisophugis@gmail.com">chisophugis@gmail.com</a>> wrote:<br>

<br>
> LLVM doesn't provide a runtime or "VM". You basically do these things the<br>
> same way that you do them in C. Yes, this unfortunately requires knowing<br>
> your target platform's system libraries and how to link to them and such;<br>
> LLVM doesn't paper over this.<br>
<br>
</div>OK. So to be specific, I am using a Haskell language binding to LLVM,<br>
not C. With my multimedia IO examples, am I correct in thinking I have<br>
a few options:<br>
1. Do IO in my host language, and parse bytestrings in to LLVM data<br>
structures, e.g. vectors. Then, pass these data structures to LLVM<br>
generated code for JIT compilation.<br>
2. Write IO functions in C, and compile with -emit-llvm . Then in my<br>
LLVM code generation, I read this external function from a bitcode<br>
file generated by clang. Here, there is no IO in my host language.<br>
3. Call libc functions within LLVM to parse bytestrings directly in to<br>
structs or vectors. If libc embedded in LLVM even possible?<br>
<br></blockquote><div>LLVM's JIT can use a call instruction to call a function, and the runtime will attempt<br>to find a symbol for that function in the linked libraries, see for example the bit on<br><br> <a href="http://llvm.org/docs/tutorial/LangImpl4.html">http://llvm.org/docs/tutorial/LangImpl4.html</a><br>
<br></div><div>where it talks about "Whoa, how does the JIT know about sin and cos?". There's nothing<br>intrinsically different about IO functions from any other functions here (since any "function" could have<br>
a static variable or refer to a global variable, unlike in a functional setup like Haskell where<br>they're very different things) and indeed later on that page there's an example of using an IO<br>output function. This is probably going to be the easiest way to do things, rather than<br>
taking the output of -emit-llvm (although that shouldn't be that hard either). Note that libc isn't<br>really "embedded" in your LLVM code in this case: you'll be using the same libc as is used by LLVM<br>
</div><div>itself. The only difference is in how the mapping from call names in LLVM IR to actual callable entries is done.<br></div><div>You don't even have to stick to libc: you could write normal C code for IO, compile it into a shared library,<br>
</div><div>and then call those functions.<br></div><div><br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Is there an LLVM cookbook for interaction with IO runtime systems?<br><div class="im"></div></blockquote><div><br>There's no "in principle" difference between IO and a general runtime at this level:<br>both can have both accessible and hidden "state". I'm not aware of any specific<br>
</div><div>recipes for this.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">
> The state of backend documentation is pretty dire. I brain dumped basically<br>
> all the backend docs I could think of in<br>
> <<a href="http://thread.gmane.org/gmane.comp.compilers.llvm.devel/65898" target="_blank">http://thread.gmane.org/gmane.comp.compilers.llvm.devel/65898</a>>. That thread<br>
> also has some other good pointers for a person interested in writing a<br>
> backend.<br>
<br>
</div>That's a great resource, thanks.<br>
<br>
One thing I'd really appreciate is a cookbook on LLVM data structures.<br>
I have read the language reference <a href="http://llvm.org/docs/LangRef.html" target="_blank">http://llvm.org/docs/LangRef.html</a> ,<br>
and understand the expressivity of aggregate types. What I do not yet<br>
have a good feeling for is when to use them. To give a concrete<br>
example, I'd like to parse a greyscale image in to an LLVM data<br>
structure. At each {x,y} point, there is an Int8 value between 0 and<br>
255. Take a small 4x3 image. I could feed my pixels in to a flat Int8<br>
vector of length 12. I could also feed it in to an array of length 4,<br>
of Int8 arrays of length 3.<br>
<br>
Now take 2 simple functions: one does greyscale brightening, the other<br>
does a sobel filter. The first needs only to know the value of 1 pixel<br>
at a time, i.e. to increase its value. For this, the vector option<br>
would be fine, and I assume (naively) that I'd enjoy SIMD performance<br>
over this vector, executing `add x` to each element? However, the<br>
Sobel filter needs information not only about the value of a pixel,<br>
but also the values of its surrounding pixels. In this case, the 2D<br>
array would be more suitable, as the shape of the image is known.<br>
Would I lose SIMD vectorisation, probably? Or as a third option, would<br>
I use a struct with a triple of three elements: a vector, and two Int8<br>
values indicating the X and Y lengths of the image?<br></blockquote><div><br></div><div>The paragraph above suggests you're thinking of an _LLVM_ vector as<br>a generic construct, including for storage. Actually LLVM's vector is designed<br>
as a representation of a _vector register_ but able to use standard LLVM<br>IR instructions rather than a CPU specific instruction set (simplifying the story dramatically). You<br></div><div>probably want to store images as 2-D array of the basic<br>
element type. Auto-vectorisation (nothing prevents you generating LLVM<br>IR to process your data using vectors) is successful primarily based upon<br>the ability of the auto-vectoriser to see what the true data dependencies<br>
are in your code. A 2-D array will use indices in accesses which are<br></div><div>most easily analysed, so should give you the berst chance of auto-vectorization.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

What I'm after is a cookbook for LLVM data structures, and how to<br>
apply them. E.g, when to use structs, when to use aggregated types,<br>
and how to hold on to SIMD vectorisation when ever is possible.--<br><div class=""><div class="h5"></div></div></blockquote><div><br clear="all"></div></div>Unfortunately I'm not aware of such a thing. But I'd say a basic rule of<br>
</div><div class="gmail_extra">thumb would be that if you would naturally use a given structure in C<br>it's probably a reasonable strategy to use the LLVM analogue.<br></div><br><div class="gmail_extra">-- <br><div>cheers, dave tweed__________________________</div>
<div>high-performance computing and machine vision expert: <a href="mailto:david.tweed@gmail.com" target="_blank">david.tweed@gmail.com</a></div><div>"while having code so boring anyone can maintain it, use Python." -- attempted insult seen on slashdot</div>
<div> </div>
</div></div>