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

Improve codegen for Core.throw_methoderror and Core.current_scope #55803

Merged
merged 2 commits into from
Sep 19, 2024

Conversation

topolarity
Copy link
Member

@topolarity topolarity commented Sep 18, 2024

This slightly improves our (LLVM) codegen for Core.throw_methoderror and Core.current_scope

julia> foo() = Core.current_scope()
julia> bar() = Core.throw_methoderror(+, nothing)

Before:

; Function Signature: foo()
define nonnull ptr @julia_foo_2488() #0 {
top:
  %0 = call ptr @jl_get_builtin_fptr(ptr nonnull @"+Core.#current_scope#2491.jit")
  %Builtin_ret = call nonnull ptr %0(ptr nonnull @"jl_global#2492.jit", ptr null, i32 0)
  ret ptr %Builtin_ret
}
; Function Signature: bar()
define void @julia_bar_589() #0 {
top:
  %jlcallframe1 = alloca [2 x ptr], align 8
  %0 = call ptr @jl_get_builtin_fptr(ptr nonnull @"+Core.#throw_methoderror#591.jit")
  %jl_nothing = load ptr, ptr @jl_nothing, align 8
  store ptr @"jl_global#593.jit", ptr %jlcallframe1, align 8
  %1 = getelementptr inbounds ptr, ptr %jlcallframe1, i64 1
  store ptr %jl_nothing, ptr %1, align 8
  %Builtin_ret = call nonnull ptr %0(ptr nonnull @"jl_global#592.jit", ptr nonnull %jlcallframe1, i32 2)
  call void @llvm.trap()
  unreachable
}

After:

; Function Signature: foo()
define nonnull ptr @julia_foo_713() #0 {
top:
  %thread_ptr = call ptr asm "movq %fs:0, $0", "=r"() #5
  %tls_ppgcstack = getelementptr inbounds i8, ptr %thread_ptr, i64 -8
  %tls_pgcstack = load ptr, ptr %tls_ppgcstack, align 8
  %current_scope = getelementptr inbounds i8, ptr %tls_pgcstack, i64 -72
  %0 = load ptr, ptr %current_scope, align 8
  ret ptr %0
}
; Function Signature: bar()
define void @julia_bar_1581() #0 {
top:
  %jlcallframe1 = alloca [2 x ptr], align 8
  %jl_nothing = load ptr, ptr @jl_nothing, align 8
  store ptr @"jl_global#1583.jit", ptr %jlcallframe1, align 8
  %0 = getelementptr inbounds ptr, ptr %jlcallframe1, i64 1
  store ptr %jl_nothing, ptr %0, align 8
  %jl_f_throw_methoderror_ret = call nonnull ptr @jl_f_throw_methoderror(ptr null, ptr nonnull %jlcallframe1, i32 2)
  call void @llvm.trap()
  unreachable
}

I'm not sure why we don't require these addresses to be available for
all builtins, but this mildly improves our codegen for these.

```julia
julia> foo() = Core.current_scope()
```

Before:
```llvm
define nonnull ptr @julia_foo_2488() #0 {
top:
  %0 = call ptr @jl_get_builtin_fptr(ptr nonnull @"+Core.#current_scope#2491.jit")
  %Builtin_ret = call nonnull ptr %0(ptr nonnull @"jl_global#2492.jit", ptr null, i32 0)
  ret ptr %Builtin_ret
}
```

After:
```llvm
define nonnull ptr @julia_foo_1066() #0 {
top:
  %jl_f_current_scope_ret = call nonnull ptr @jl_f_current_scope(ptr null, ptr null, i32 0)
  ret ptr %jl_f_current_scope_ret
}
```
@topolarity
Copy link
Member Author

@vtjnash Do you know why we don't just make builtin_func_map fully exhaustive (i.e. require all lookups to succeed)?

@vtjnash
Copy link
Sponsor Member

vtjnash commented Sep 18, 2024

We certainly could. Just hasn't been done by anyone yet

@vtjnash
Copy link
Sponsor Member

vtjnash commented Sep 18, 2024

We could also do better to inline that pointer, since we don't need to call jl_get_builtin_fptr when we could inline a load from the CodeInstance directly there

@topolarity
Copy link
Member Author

Which CodeInstance?

@vtjnash
Copy link
Sponsor Member

vtjnash commented Sep 18, 2024

The one in jl_get_builtin_fptr

@topolarity
Copy link
Member Author

Ah right - but if we make builtin_func_map fully-exhaustive, then we should almost never use jl_get_builtin_fptr at runtime?

@gbaraldi
Copy link
Member

Current scope should just be codegened to lower to just getting the scope out of the task. The fact it's a builtin is slightly annoying but it's fine.

julia/src/codegen.cpp

Lines 6789 to 6793 in 0073917

static Value *get_scope_field(jl_codectx_t &ctx)
{
Value *ct = get_current_task(ctx);
return emit_ptrgep(ctx, ct, offsetof(jl_task_t, scope), "current_scope");
}

@topolarity topolarity added backport 1.11 Change should be backported to release-1.11 and removed backport 1.11 Change should be backported to release-1.11 labels Sep 18, 2024
@topolarity topolarity changed the title Inline fptr lookup for Core.throw_methoderror and Core.current_scope Improve codegen for Core.throw_methoderror and Core.current_scope Sep 18, 2024
@topolarity
Copy link
Member Author

Current scope should just be codegened to lower to just getting the scope out of the task

Done 👍

@topolarity topolarity merged commit 86c567f into JuliaLang:master Sep 19, 2024
7 checks passed
@topolarity topolarity deleted the ct/codegen-fptr branch September 19, 2024 03:27
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

Successfully merging this pull request may close these issues.

4 participants