JuliaLang/julia — pull request #8740 by maleadt (2014-10-20 13:13:52+00:00)
Title:  Extend llvmcall with support for entering declarations.

*This is a copy of PR #8673 -- I accidentally created the old PR from my `master` branch, which isn't very clean.*

This PR adds support to `llvmcall` for inserting required declarations in the module. This is useful when you want to `llvmcall` intrinsics, because LLVM refuses to parse IR with undeclared identifiers (for example, see [this thread](https://groups.google.com/forum/#!searchin/julia-dev/llvmcall/julia-dev/X0k-AErZBYk/f5DoyAFwhkAJ)).

The idea behind this solution is to allow passing a tuple `(decls, ir)`as first argument to `llvmcall`, where currently only an IR string or a pointer to a LLVM function is allowed. The `decls` IR is then pasted before the function `llvmcall` generates. In order to avoid duplicate declarations, which LLVM does not like, a global set keeps track of the declarations added to the current module.

Example usage:
```julia
function floor(x::Float64)
llvmcall(
("""declare double @llvm.floor.f64(double)""",
"""%2 = call double @llvm.floor.f64(double %0)
ret double %2"""),
Float64, (Float64,), x)
end
```

As mentioned in issue #8308 I also tried other approaches, such as automatically parsing identifiers in the IR, but that turned out pretty fragile.