Skip to content

Concatenation of string constants isn't concretely evaluated, but is inferred as a Const #54921

Open
@Seelengrab

Description

Consider this silly little function:

f() = "foo" * "bar"

which concatenates two string constants, "foo" and "bar", into one bigger constant "foobar". The compiler agrees, and according to Cthulhu, infers that this is a constant:

julia> f() = "foo" * "bar"
f (generic function with 1 method)

julia> @descend f()
f() @ Main REPL[4]:1
1 f()::Core.Const("foobar") = "foo" * "bar"::String
[...]

However, even though it's inferred as a constant (and thus "foobar" is already allocated somewhere!), the compiler doesn't actually concretely evaluate this:

julia> @code_llvm f()
; Function Signature: f()
;  @ REPL[4]:1 within `f`
define nonnull ptr @julia_f_4243() #0 {
top:
  %0 = call nonnull ptr @"j_*_4246"(ptr nonnull @"jl_global#4247.jit", ptr nonnull @"jl_global#4248.jit")
  ret ptr %0
}

julia> @code_native dump_module=false f()
	.text
; ┌ @ REPL[4]:1 within `f`
	push	rbp
	mov	rbp, rsp
	mov	rax, qword ptr [r13 + 16]
	movabs	rdi, 139273527936000
	lea	rsi, [rdi + 56]
	mov	rax, qword ptr [rax + 16]
	mov	rax, qword ptr [rax]
	movabs	rax, offset "*"
	call	rax
	pop	rbp
	ret
; └
; ┌ @ REPL[4]:1 within `<invalid>`
	nop	dword ptr [rax + rax]
; └

Preferring to do this at runtime instead.

Effects look wonderful too:

julia> Base.infer_effects(f)
(+c,+e,+n,+t,+s,+m,+u)

So why doesn't the compiler fold this away, since the result was inferred as Core.Const & presumably allocated during that?

I was able to reproduce this on 1.11 & master.


I've labelled this with compiler:optimizer, but I'm not sure this fits there exactly. Feel free to relabel as appropriate.

Metadata

Assignees

No one assigned

    Labels

    compiler:optimizerOptimization passes (mostly in base/compiler/ssair/)strings"Strings!"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions