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

failure to infer/inline #11

Closed
maleadt opened this issue Nov 13, 2017 · 4 comments
Closed

failure to infer/inline #11

maleadt opened this issue Nov 13, 2017 · 4 comments

Comments

@maleadt
Copy link
Contributor

maleadt commented Nov 13, 2017

Reduced from getindex(Number,Int), the following code demonstrates a failure to infer a call to Cassette.execute and subsequent failure to inline the overdubbed code:

using Cassette

Cassette.@context Ctx

foobar(i::Int, whatever) = i == 1

code_warntype(foobar, Tuple{Int, Int})

let ctx = Ctx(foobar)
    @code_warntype (Cassette.Overdub(Cassette.Execute(), foobar, Cassette.Settings(ctx)))(1,1)
end

Original IR:

Variables:
  i::Int64
  whatever<optimized out>

Body:
  begin
      return (i::Int64 === 1)::Bool
  end::Bool

Overdubbed:

Variables:
  o<optimized out>
  args::Tuple{Int64,Int64}

Body:
  begin
      return $(Expr(:invoke, MethodInstance for execute(::Cassette.Overdub{Cassette.Execute,typeof(==),Cassette.Settings{Ctx{0xc9f9ac09b400a019},Void,0x00000000000059fe,false}}, ::Int64, ::Int64, ::Vararg{Int64,N} where N), :(Cassette.execute), :($(QuoteNode(Cassette.Overdub{Cassette.Execute,typeof(==),Cassette.Settings{Ctx{0xc9f9ac09b400a019},Void,0x00000000000059fe,false}}(Cassette.Execute(), ==, Cassette.Settings{Ctx{0xc9f9ac09b400a019},Void,0x00000000000059fe,false}(Ctx{14553852828499091481}(), nothing, Cassette.World{0x00000000000059fe}(), Val{false}()))))), :((Core.getfield)(args, 1)::Int64), 1))::Any
  end::Any

Tested both on master and the IPO branch (JuliaLang/julia#24362).
Dropping the unused whatever argument resolved the issue. Is this a case of #5?

@jrevels
Copy link
Collaborator

jrevels commented Nov 13, 2017

Assuming invoke isn't a de facto inlining barrier (EDIT: confirmed that it isn't), it might be interesting to see if @JeffBezanson's workaround in #5 could sidestep this. Still stuck on implementing that, though, due to the StackOverflow I posted about there.

@jrevels
Copy link
Collaborator

jrevels commented Nov 13, 2017

So I made a workaround for the workaround, and it does indeed seem to resolve this issue (using a freshly built Julia master):

julia> using Cassette

julia> Cassette.@context Ctx

julia> foobar(i::Int, whatever) = i == 1
foobar (generic function with 1 method)

julia> code_warntype(foobar, Tuple{Int, Int})
Variables:
  i::Int64
  whatever<optimized out>

Body:
  begin
      return (i::Int64 === 1)::Bool
  end::Bool

julia> code_warntype(Cassette.overdub(Ctx, foobar), Tuple{Int,Int})
Variables:
  o<optimized out>
  x1::Int64
  x2<optimized out>
  #temp#@_4::Bool

Body:
  begin
      # meta: location /Users/jarrettrevels/.julia/v0.7/Cassette/src/workarounds.jl execute 16
       # a lot of meta locations
      # meta: location /Users/jarrettrevels/.julia/v0.7/Cassette/src/contextual/metadata.jl @generated body
      #= line 48 =#
      #temp#@_4::Bool = (===)(x1::Int64, 1)::Bool
      goto 33
      # meta: pop location
      33:
      # meta: pop locations (8)
      goto 37
      # meta: pop location
      37:
      # meta: pop locations (17)
      return #temp#@_4::Bool
  end::Bool

@maleadt
Copy link
Contributor Author

maleadt commented Nov 14, 2017

Thanks, this one seems fixed now.

Do you have an efficient way of figuring these out; should I file issues or are there known issues with the workarounds? Because I'll probably be running into plenty such cases, e.g.

foo(ptr::Ptr{T}, i) where {T} = Base.unsafe_load(ptr, i)::T
# removing ::T or i arg fixes this one


code_llvm(foo, Tuple{Ptr{Float32}, Int})


using Cassette

Cassette.@context Ctx
const ctx = Ctx(foo)

code_llvm(Cassette.Overdub(Cassette.Execute(), foo, Cassette.Settings(ctx)),
          Tuple{Ptr{Float32}, Int})

@maleadt maleadt closed this as completed Nov 14, 2017
@jrevels
Copy link
Collaborator

jrevels commented Nov 14, 2017

Do you have an efficient way of figuring these out

Not really, but most of them so far have ended up getting resolved by a) finding some region that's being "poisoned" by a specialization heuristic and b) figuring out the right way to force specialization for that region.

My hope is that eventually the compiler's specialization heuristics and the quality of partially unspecialized generated code both improve enough that this won't be as much of a problem. I also need to play around with removing all the forced @inline annotations at some point; it's pretty excessive at the moment, and might even be making it harder for the specialization heuristics to make good choices in the first place.

should I file issues

Definitely! They're super helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants