Does the LLVM OCaml binding include intrinsic support? - ocaml

I can't seem to find reference to intrinsics in the official LLVM OCaml binding, beyond the is_intrinsic function.
I am building a backend which needs to perform some target-specific code-generation (for SSE, AVX, and NEON), and intrinsics are the standard path in the C++ API.

The OCaml binding supports intrinsics in exactly the same way as the C language binding:
There is no special support for them in the interface (as there is in the full C++ interface), but they can be declared extern and called just like any other functions.
e.g.:
open Llvm
let () =
let c = create_context () in
let f32_t = float_type c in
let f32x4_t = vector_type f32_t 4 in
let m = create_module c "test" in
(* declare void #printv(<4 x float>)
* nonce extern which forces preservation of vector results *)
let printv =
declare_function "printv"
(function_type (void_type c) [|f32x4_t|]) m in
(* declare <4 x float> #llvm.x86.sse.sqrt.ps(<4 x float>) nounwind readnone *)
let sqrtps =
declare_function "llvm.x86.sse.sqrt.ps"
(function_type f32x4_t [|f32x4_t|]) m in
(* define i32 #main() { entry: *)
let main = define_function "main" (function_type i32_t [| |]) m in
let at_entry = builder_at_end c (entry_block main) in
(*%sqrtps = call <4 x float> #llvm.x86.sse.sqrt.ps(<4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>)*)
let cv1234 = const_vector [| const_float f32_t 1.0; const_float f32_t 2.0;
const_float f32_t 3.0; const_float f32_t 4.0 |] in
let sqrt = build_call sqrtps [| cv1234 |] "sqrtps" at_entry in
(* call void printv(sqrtps) *)
ignore (build_call printv [| sqrt |] "" at_entry);
(* ret void *)
ignore (build_ret (const_null i32_t) at_entry);
(* Print .ll to stderr *)
dump_module m
produces:
; ModuleID = 'test'
declare void #printv(<4 x float>)
declare <4 x float> #llvm.x86.sse.sqrt.ps(<4 x float>) nounwind readnone
define i32 #main() {
entry:
%sqrtps = call <4 x float> #llvm.x86.sse.sqrt.ps(<4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>)
call void #printv(<4 x float> %sqrtps)
ret i32 0
}
which compiles into x86 correctly invoking sqrtps on the xmm registers.

Disclaimer: I never used LLVM. After a quick look at the binding documentation, it looks like the answer is "no". There is a support for inline assembly however, which may or may not suit your needs.
Finally, it seems it is accepted by the LLVM developers that the OCaml binding is not complete: if you want to, you can add some more functionality (if you're not familiar with OCaml, C bindings are really not the easiest part, but the LLVM bindings are full of example code that you could probably successfully adapt to other LLVM functions), then provide a patch for it on the LLVMdev list.

Related

LLVM ERROR: Cannot select: 0x5586a71270c0: f32 = Constant<1036831949>

I get the error LLVM ERROR: Cannot select: 0x5644a6291a10: f32 = Constant<1036831949> somewhere inside:
%a2 = load float, float* %a
%a3 = load float, float* %a
%cmp = fcmp one float %a3, 0.000000e+00
%not = xor i1 %cmp, true
%convert = zext i1 %not to i32
%conv = sitofp i32 %convert to float
%cmp2 = or float %conv, %a2
store float %cmp2, float* %a
Is there a possible type mismatch occurring here? I have encountered this error before, but in the context of a mismatch of types. Not sure what is wrong here, though.
Found the issue. %cmp2 = or float %conv, %a2 is invalid because or only takes int types.
Tip to other newbies, try running llc myfile.llvm to find issues in your LLVM IR.

ocaml wrong pow function give correct output

i wrote a pow function in ocaml and by mistake a wrote this
let rec pow x y acc = if y = 1 then acc else pow x (y-1) x*x;;
this function can be called with any value of acc and output the correct answer, but this must output x^2 .
this is the correct functon :
let rec pow x y acc = if y = 0 then acc else pow x (y-1) x*acc;;
and call this function with the value of acc of 1.
my question is why first function give the correct output ?
The key is that function application has higher precedence than binary operators. In the case at hand, the else term is equivalent to (pow x (y-1) x) * x, not pow x (y-1) (x*x).

Is it possible to have a compile-time "reference" to a variable?

Consider the following code:
Matrix4x4 perspective(const ViewFrustum &frustum) {
float l = frustum.l;
float r = frustum.r;
float b = frustum.b;
float t = frustum.t;
float n = frustum.n;
float f = frustum.f;
return {
{ 2 * n / (r - l), 0, (r + l) / (r - l), 0 },
{ 0, 2 * n / (t - b), (t + b) / (t - b), 0 },
{ 0, 0, -((f + n) / (f - n)), -(2 * n * f / (f - n)) },
{ 0, 0, -1, 0 }
};
}
In order to improve readability of constructing the matrix, I have to either make a copy of values from the frustum struct, or references to them. However, neither do I actually need copies or indirection.
Is it possible to have some kind of a "reference" that would be resolved at compile time, kind of like a symbolic link. It would have the same effect as:
Matrix4x4 perspective(const ViewFrustum &frustum) {
#define l frustum.l;
#define r frustum.r;
#define b frustum.b;
#define t frustum.t;
#define n frustum.n;
#define f frustum.f;
return {
{ 2 * n / (r - l), 0, (r + l) / (r - l), 0 },
{ 0, 2 * n / (t - b), (t + b) / (t - b), 0 },
{ 0, 0, -((f + n) / (f - n)), -(2 * n * f / (f - n)) },
{ 0, 0, -1, 0 }
};
#undef l
#undef r
#undef b
#undef t
#undef n
#undef f
}
Without the preprocessor (or is it acceptable?). I suppose it isn't really needed, or could be avoided in this particular case by making those 6 values arguments to a function directly (though it would be a bit irritating having to call the function like that - but even then, I could make an inline proxy function).
But I was just wondering if this is somehow possible in general? I could not find anything like it. I think it would come in handy for locally shortening descriptive names that are going to be used a lot, without actually having to lose the original names.
Well, that's what C++ references are for:
const float &l = frustum.l;
const float &r = frustum.r;
const float &b = frustum.b;
const float &t = frustum.t;
const float &n = frustum.n;
const float &f = frustum.f;
Most modern compilers will optimize out the references, and use the values from the frustum object verbatim, in the following expression, by resolving the references at compile-time.
Obligatory disclaimer: do not prematurely optimize.
Let me compare your naive perspective function, containing
float l = frustum.l;
float r = frustum.r;
float b = frustum.b;
float t = frustum.t;
float n = frustum.n;
float f = frustum.f;
With define's and #Sam Varshavchik solution with references.
We assume that our compiler is optimizing, and optimizing at least decent.
Assembly output for all three versions: https://godbolt.org/g/G06Bx8.
You can notice that reference and define versions are exactly the same - as expected. But naive differs a lot. It first loads all the values from memory:
movss (%rdi), %xmm2 # xmm2 = mem[0],zero,zero,zero
movss 4(%rdi), %xmm1 # xmm1 = mem[0],zero,zero,zero
movss 8(%rdi), %xmm0 # xmm0 = mem[0],zero,zero,zero
movss %xmm0, 12(%rsp) # 4-byte Spill
movss 12(%rdi), %xmm0 # xmm0 = mem[0],zero,zero,zero
movss %xmm0, 8(%rsp) # 4-byte Spill
movss 16(%rdi), %xmm3 # xmm3 = mem[0],zero,zero,zero
movaps %xmm3, 16(%rsp) # 16-byte Spill
movss 20(%rdi), %xmm0
And then never again references the %rdi (frustrum) memory. Reference and define versions, on the other hand, load values as they are needed.
This happens because the implementation of Vector4 constructor is hidden from the optimizer and it can't assume that constructor doesn't modify frustrum, so it must insert loads, even when such loads are redundant.
So, naive version can be even faster than "optimized" one, under certain circumstances.
In general, you can use plain references, as long as you are in the local scope. Modern compilers "see through them" and just treat them as aliases (notice that this actually applies even to pointers).
However, when dealing with stuff on the small side, copying to a local variable, if anything, is generally beneficial. frustnum.ris one layer of indirection away (frustnum is actually a pointer under the hood), so accessing it is costlier than it may seem, and if you have function calls in the middle of your function the compiler may not be able to prove that its value isn't changing, so the access may need to be repeated.
Local variables instead are normally directly on the stack (cheap) or straight in registers (cheapest), and, most importantly, given that they usually have no interaction with "the outside", the compiler has an easier time reasoning about them, so it can be more aggressive with optimizations; also, when actually performing the computations those values are going to be copied in registers and on the stack anyway.
So go ahead and use copies, at worst the compiler will probably do the same, at best you may helped it optimizing stuff.

Z3 C++ API: set parameter for tactic

I'm using the Z3 C++ API of the SMT Solver and I'd like to change parameters of the "ctx-solver-simplify". I don't know how to input them to the tactic. I tried:
z3::context c;
c.set("arith_lhs",false);
c.set("eq2ineq",true);
And
z3::params params(c);
params.set("arith_lhs",true);
params.set("eq2ineq",true);
Example code:
z3::expr x = c.int_const("x");
z3::expr cond1 = !(x==4);
z3::goal g(c);
g.add(cond1);
z3::tactic t(c, "ctx-solver-simplify");
z3::apply_result r = t(g);
The result is
(goal (not (= x 4)))
And not
(goal and (< x 4) (> x 4)
Same applies for arith_lhs. Any help?
Thanks!
Change:
z3::tactic t(c, "ctx-solver-simplify");
to
z3::tactic t = with(z3::tactic(c, "simplify"), params);
This will instruct Z3 to apply the simplify tactic with the selected parameters. In the SMT-LIB API this is accomplished with the "using-params" combinator. I got the above C++ equivalent from example.cpp shipped with the Z3 source.
So there were two problems: (1) You need to tell Z3 to apply the given tactic with the selected parameters. (2) the ctx-solver-simplify tactic does not have an eq2ineq option. Other tactics do, though, including simplify.

Coerce built-ins to their GL equivalents

I just wrote a quick Conway's Game of Life in Haskell for practice and I though that I should now animate it.
I wanted to use GLUT + OpenGL and few seconds of Googling later, I had an example up and ready to fire. The difference in the example is that it defines a function that returns some points as myPoints :: [(GLfloat,GLfloat,GLfloat)] whereas I have Coord defined as data Coord = Coord {x :: Int, y :: Int} deriving (Show, Eq). That's all nice and neat and the game seems to work in its plain form, but there are issues when I try to draw it. Namely the part when I am supposed to pass the points to the renderer:
renderPrimitive Points $ mapM_ (\(x, y, z)->vertex$Vertex3 x y z) myPoints
That's all fine if myPoints contains values of type GLfloat but renderPrimitive Points $ mapM_ (\(Coord x y)->vertex$Vertex2 x y) myCoords complains:
No instance for (VertexComponent Int)
arising from a use of `vertex'
Possible fix: add an instance declaration for (VertexComponent Int)
I tried things like fromIntegral x and adding a type signatures :: GLfloat or GLint but it always seems to complain that it can't take the type or that it can't go Int -> GLfloat/GLint.
My question is, how do I get my Coord type to play with OpenGL types? I can't find any hint on the Web and I'd rather not make Coord = Coord {x :: GLfloat, y :: GLfloat} for the simple reason that the whole lot of other code will not play nicely with GLfloats as it's all expecting Num or Int and whatnot.
Below is minimum scenario where the issue is illustrated and which I'd love to be able to compile:
module Main
where
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
data Coord = Coord {x :: Int, y :: Int} deriving (Show, Eq)
someCoords = [Coord 1 1, Coord 1 2, Coord 42 7]
main = do
(progName, _) <- getArgsAndInitialize
createWindow "Please compile."
displayCallback $= display
mainLoop
display = do
clear [ColorBuffer]
renderPrimitive Points $ mapM_ (\(Coord x y) -> vertex $ Vertex2 x y) someCoords
After hunting for a longer while with another programmer in my household, we have found a snippet of code which let us make GLfloat from an int, namely fromIntegral x :: GLfloat will produce the desired result. Similarly, fromRational can be used for Float -> GLfloat.