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

typename is not fully optimized away #30430

Closed
JeffBezanson opened this issue Dec 18, 2018 · 5 comments
Closed

typename is not fully optimized away #30430

JeffBezanson opened this issue Dec 18, 2018 · 5 comments
Labels
compiler:optimizer Optimization passes (mostly in base/compiler/ssair/)

Comments

@JeffBezanson
Copy link
Sponsor Member

see #30420

For example

julia> f() = Base.typename(Int)

julia> @code_typed f()
CodeInfo(
1 ─ %1 = Base.typename::Const(typename, false)
│   %2 = invoke %1(Main.Int::DataType)::Const(Int64, false)
└──      return %2
) => TypeName

The called method is just

typename(a::DataType) = a.name

so it should be inlineable, and we know accessing DataType's name is nothrow and constant, so it's not clear why this call isn't removed.

@JeffBezanson JeffBezanson added the compiler:optimizer Optimization passes (mostly in base/compiler/ssair/) label Dec 18, 2018
@JeffBezanson
Copy link
Sponsor Member Author

typename has its own t-func. Commenting that out at least leads to inlining:

julia> @code_typed f()
CodeInfo(
1 ─ %1 = Main.Int::Const(Int64, false)
│   %2 = (Base.getfield)(%1, :name)::TypeName
└──      return %2
) => TypeName

@timholy
Copy link
Sponsor Member

timholy commented Dec 18, 2018

Has nothing to do with typename (though getfield seems close), but possibly related? #30222 (comment)

@martinholters
Copy link
Member

Remarkably

julia> Core.Compiler.getfield_tfunc(Core.Compiler.Const(Int64, false), Core.Compiler.Const(:name, false))
Core.Compiler.Const(Int64, false)

So why is the getfield call inferred as Typename while typename is inferred to the narrower Const(Int64, false)?

typename has its own t-func.

After unsuccessfully looking for a tfunc in tfuncs.jl, I guess you are referring to

elseif length(argtypes) == 2 && istopfunction(f, :typename)
return typename_static(argtypes[2])
right?

@martinholters
Copy link
Member

OTOH:

julia> f1() = Base.typename(Int)
f1 (generic function with 1 method)

julia> f2() = Int.name
f2 (generic function with 1 method)

julia> g1() = f1().wrapper
g1 (generic function with 1 method)

julia> g2() = f2().wrapper
g2 (generic function with 1 method)

julia> @code_typed f1()
CodeInfo(
1%1 = Base.typename::Const(typename, false)
│   %2 = invoke %1(Main.Int::DataType)::Const(Int64, false)
└──      return %2
) => TypeName

julia> @code_typed f2()
CodeInfo(
1%1 = Main.Int::Const(Int64, false)
│   %2 = (Base.getfield)(%1, :name)::TypeName
└──      return %2
) => TypeName

julia> @code_typed g1()
CodeInfo(
1%1 = Base.typename::typeof(typename)
│        invoke %1(Main.Int::DataType)::TypeName
└──      return Int64
) => Type{Int64}

julia> @code_typed g2()
CodeInfo(
1return Int64
) => Type{Int64}

So maybe the Typename vs. Const(...) difference noted above does not lead to any difference in practice and not special-casing typename is strictly better?

@laborg
Copy link
Contributor

laborg commented Oct 18, 2023

Apparently fixed on master:

julia> f1() = Base.typename(Int)
f1 (generic function with 1 method)

julia> f2() = Int.name
f2 (generic function with 1 method)

julia> g1() = f1().wrapper
g1 (generic function with 1 method)

julia> g2() = f2().wrapper
g2 (generic function with 1 method)

julia> @code_typed f1()
CodeInfo(
1 ─     return $(QuoteNode(typename(Int64)))
) => Core.TypeName

julia> @code_typed f2()
CodeInfo(
1 ─     return $(QuoteNode(typename(Int64)))
) => Core.TypeName

julia> @code_typed g1()
CodeInfo(
1 ─     return Int64
) => Type{Int64}

julia> @code_typed g2()
CodeInfo(
1 ─     return Int64
) => Type{Int64}

@laborg laborg closed this as completed Oct 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:optimizer Optimization passes (mostly in base/compiler/ssair/)
Projects
None yet
Development

No branches or pull requests

4 participants