Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eliminate intrinsics #18754

Merged
merged 18 commits into from
Jan 20, 2017
Merged

eliminate intrinsics #18754

merged 18 commits into from
Jan 20, 2017

Conversation

vtjnash
Copy link
Sponsor Member

@vtjnash vtjnash commented Oct 1, 2016

After this, only 1 intrinsics (llvmcall and some ccall fixes) remain to go to be fully interpretable and statically compilable!

  • removes special parsing rules for ccall (and thus removes Expr(:ccall)), fixes Inconsistent parsing of ccall #18687
  • makes Expr(:call, :ccall) special in lowering (effectively, reserving ccall – as the keyword it already is) and which expands to Expr(:foreigncall) representing the lowered ffi call (instead of expanding to Expr(:call, Core.Intrinsics.ccall), even though this couldn't really be a first-class function)
  • adds error checking to all Core.Intrinsic functions
  • adds support to ccall for calling llvm intrinsics directly (via "llvmcall" calling convention)
  • the unbox intrinsic is now just a deprecated alias for the box intrinsic (aka reinterpret)

The ccall intrinsic now evaluates its global arguments during method definition time, eliminating the call back into the runtime from inside codegen (yay!), and making its semantics independent of runtime values (so that its behavior is statically compilable).

edit: see https://github.com/vtjnash/julep/wiki/0001:-Enhanced-static-compilation-and-C-interface

copysign(x::Float64, y::Float64) = box(Float64,copysign_float(unbox(Float64,x),unbox(Float64,y)))
copysign(x::Float32, y::Float32) = box(Float32,copysign_float(unbox(Float32,x),unbox(Float32,y)))
copysign(x::Float64, y::Float64) = box(Float64, copysign_float(x, y))
copysign(x::Float32, y::Float32) = box(Float32, copysign_float(x, y))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space preceding y in the method signature?

flipsign(x::Float64, y::Float64) = box(Float64,xor_int(unbox(Float64,x),and_int(unbox(Float64,y),0x8000000000000000)))
flipsign(x::Float32, y::Float32) = box(Float32,xor_int(unbox(Float32,x),and_int(unbox(Float32,y),0x80000000)))
flipsign(x::Float64, y::Float64) = box(Float64, xor_int(box(UInt64, x), and_int(box(UInt64, y), 0x8000000000000000)))
flipsign(x::Float32, y::Float32) = box(Float32, xor_int(box(UInt32, x), and_int(box(UInt32, y), 0x80000000)))
Copy link
Member

@Sacha0 Sacha0 Oct 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space preceding y in the method signature here as well?

@maleadt
Copy link
Member

maleadt commented Oct 2, 2016

Cool, the llvmcall calling convention will make some of our llvmcall(...) usage in CUDAnative redundant. What about function attributes though? Most NVPTX intrinsics are readnone nounwind.

For PTX we also need to call into libdevice, an IR blob providing implementations of common math functions. This blob is linked in during JIT, so regular ccall doesn't work (disregarding the fact that there's no dlopen, etc). Bottom line, it would be handy if the new llvmcall cc wouldn't check for isIntrinsic, even though it makes sense to require that for every other sane use case...


.. _CUDA: http://llvm.org/docs/NVPTXUsage.html

As with any ccall, it is essential to get the argument signature exactly correct.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code highlight ccall

jl_error(msg.c_str()); // TODO: this leaks memory
}
if (jl_is_cpointer_type(rt) && jl_is_typevar(jl_tparam0(rt)))
jl_error("ccall: return type Ptr should have an element type, not Ptr{_<:T}");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this Ptr{_<:T} will be pretty confusing

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't a new change

{
if (t->isFloatingPointTy())
return t;
unsigned nb = (t->isPointerTy() ? t->getPrimitiveSizeInBits() : sizeof(void*));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this backwards?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs-test then if it was passing with a mistake here

if (t == T_float16)
return T_int16;
//if (t == T_float128)
// return T_int128;
Copy link
Contributor

@tkelman tkelman Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leave a comment or a cross-reference about why this is commented out (same below in JL_JLUINTT and JL_JLSINTT)

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't a new change

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's not a reason to leave unexplained things or lousy error messages in the code. while it's being rearranged is the right time to make these little improvements

#else
Value *ret = builder.CreateCall3(prepare_call(jlpref_func), boxed(parg, ctx), iarg, alignarg);
#ifdef JL_NEED_FLOATTEMP_VAR
// Target platform might carry extra precision.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excess indent

@tkelman
Copy link
Contributor

tkelman commented Oct 3, 2016

needs a test for #18687

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Oct 3, 2016

this isn't that kind of fix. this "fixes" the issue by deleting the special parsing code and the tests for it (of which apparently there were none).

@vtjnash vtjnash force-pushed the jn/foreigncall branch 2 times, most recently from d175911 to 5595287 Compare October 3, 2016 16:34
@tkelman
Copy link
Contributor

tkelman commented Oct 3, 2016

doesn't matter how it's being fixed. add a test.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Oct 3, 2016

It's not fixed, it's deleted, along with all tests for it.

@tkelman
Copy link
Contributor

tkelman commented Oct 3, 2016

That issue is about the fact that it works differently on master. To close that issue, and just in general, should add tests that it no longer works differently in this pr. Not asking for much here, tests and comments. Why are you fighting that?

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Oct 4, 2016

I'm not fixing that issue, I'm deleting the feature that the referenced issue complained about.

tkelman
tkelman previously requested changes Oct 4, 2016
Copy link
Contributor

@tkelman tkelman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what? You're replacing it with a new implementation that needs to be tested that it no longer has the undesirable behavior.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Oct 4, 2016

So what? You're replacing it with a new implementation that needs to be tested that it no longer has the undesirable behavior.

No, it's completely gone. The parser no longer has any knowledge of ccall.

@tkelman
Copy link
Contributor

tkelman commented Oct 4, 2016

The implementation now happening in lowering instead of parsing doesn't change the fact that the parser behavior change for ccall should be tested and verified.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Oct 4, 2016

How does the parser not implementing ccall not eliminate the need to test how the parser implements ccall? The parser no longer has any special behavior related to the symbol ccall, it is handled by exactly the same code as handles all Expr(:call) form expressions.

@tkelman
Copy link
Contributor

tkelman commented Oct 4, 2016

Because the parser used to implement ccall. If it hadn't had a custom implementation before, it would be fine. This is a change in behavior specifically for ccall, and that's the part that should now be tested.

@tkelman
Copy link
Contributor

tkelman commented Oct 5, 2016

why is llvmcall2 a separate file here? would the "nonsensical valid conversions and errors" tests have caught the mistake from #18754 (comment) ?

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Oct 5, 2016

It tests v2 of llvmcall. Yes, it includes coverage of that case.

@JeffBezanson
Copy link
Sponsor Member

It occurs to me that after this change we should add t-functions for all intrinsics (previously we relied on their results always being passed to box).

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Oct 7, 2016

Yes, that's also on my list of eventually fixes for here (along with completely removing unbox and removing most calls to box)

@vtjnash vtjnash force-pushed the jn/foreigncall branch 4 times, most recently from 39680e3 to cfe8efc Compare October 13, 2016 21:18
all intrinsics (but one) are now fully error-checking and runtime-interpreter-compatible
a handful of packages seem to have unused functions that are triggering this error
it was neutered by earlier commits, this just finishes deleting it
by adding type inference information to all of the intrinsics,
the box intrinsic is no longer required for this purpose
this name better reflects what this intrinsic does,
which is to change the type-tag on some data,
without actually altering the data or its representation
@vtjnash vtjnash merged commit 5112619 into master Jan 20, 2017
@vtjnash vtjnash deleted the jn/foreigncall branch January 20, 2017 05:01
maleadt added a commit to JuliaGPU/CUDAnative.jl that referenced this pull request Feb 2, 2017
Cannot use it for all intrinsics as the libdevice ones aren't true intrinsics,
and are rejected by the new llvmcall.

Ref JuliaLang/julia#18754
maleadt added a commit to JuliaAttic/CUDArt.jl that referenced this pull request Feb 16, 2017
vchuravy pushed a commit to JuliaAttic/CUDArt.jl that referenced this pull request Feb 17, 2017
Sacha0 added a commit to Sacha0/julia that referenced this pull request May 13, 2017
Sacha0 added a commit to Sacha0/julia that referenced this pull request May 13, 2017
Sacha0 added a commit to Sacha0/julia that referenced this pull request May 20, 2017
Sacha0 added a commit to Sacha0/julia that referenced this pull request May 20, 2017
tkelman pushed a commit that referenced this pull request Jun 3, 2017
@ViralBShah ViralBShah added the gpu Affects running Julia on a GPU label Sep 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deprecation This change introduces or involves a deprecation gpu Affects running Julia on a GPU
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inconsistent parsing of ccall