From 1327b5cb4320ca7655ea06c251eed43a0133e81b Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 8 Dec 2020 22:36:50 -0500 Subject: [PATCH 1/2] Add isdefined check `count_const_size` This doesn't do much currently, because we only call this function on `Const` objects which we don't currently create if the initialization of the object is incomplete, but we may want to do so in the future, so might as well be defensive about it. --- base/compiler/utilities.jl | 1 + test/compiler/inline.jl | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/base/compiler/utilities.jl b/base/compiler/utilities.jl index 487396e11119a..37f4ce2f09340 100644 --- a/base/compiler/utilities.jl +++ b/base/compiler/utilities.jl @@ -82,6 +82,7 @@ function count_const_size(@nospecialize(x)) dtfd = DataTypeFieldDesc(dt) for i = 1:nfields(x) dtfd[i].isptr || continue + isdefined(x, i) || continue sz += count_const_size(getfield(x, i)) sz > MAX_INLINE_CONST_SIZE && return MAX_INLINE_CONST_SIZE + 1 end diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 5a08e7129c1ff..ee01feba3a1ff 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -324,3 +324,9 @@ let ci = code_typed(NonIsBitsDims, Tuple{})[1].first @test length(ci.code) == 1 && isa(ci.code[1], ReturnNode) && ci.code[1].val.value == NonIsBitsDims() end + +struct NonIsBitsDimsUndef + dims::NTuple{N, Int} where N + NonIsBitsDimsUndef() = new() +end +@test Core.Compiler.is_inlineable_constant(NonIsBitsDimsUndef()) From 793f8756a094b0451a5211f4d199a0ddbaa814c9 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 8 Dec 2020 23:37:39 -0500 Subject: [PATCH 2/2] Don't accidentally skip over pointers in count_const_size Since we can inline pointer-containing structs into other structs now, an `isptr` check is insufficient to determine whether or not we need to recurse here. Also check the actual type of the field in addition. --- base/compiler/utilities.jl | 11 +++++++---- test/compiler/inline.jl | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/base/compiler/utilities.jl b/base/compiler/utilities.jl index 37f4ce2f09340..60038cad7675d 100644 --- a/base/compiler/utilities.jl +++ b/base/compiler/utilities.jl @@ -72,18 +72,21 @@ function quoted(@nospecialize(x)) return is_self_quoting(x) ? x : QuoteNode(x) end -function count_const_size(@nospecialize(x)) +function count_const_size(@nospecialize(x), count_self::Bool = true) (x isa Type || x isa Symbol) && return 0 ismutable(x) && return MAX_INLINE_CONST_SIZE + 1 isbits(x) && return Core.sizeof(x) dt = typeof(x) - sz = sizeof(dt) + sz = count_self ? sizeof(dt) : 0 sz > MAX_INLINE_CONST_SIZE && return MAX_INLINE_CONST_SIZE + 1 dtfd = DataTypeFieldDesc(dt) for i = 1:nfields(x) - dtfd[i].isptr || continue isdefined(x, i) || continue - sz += count_const_size(getfield(x, i)) + f = getfield(x, i) + if !dtfd[i].isptr && datatype_pointerfree(typeof(f)) + continue + end + sz += count_const_size(f, dtfd[i].isptr) sz > MAX_INLINE_CONST_SIZE && return MAX_INLINE_CONST_SIZE + 1 end return sz diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index ee01feba3a1ff..e8b4c4f4cc77e 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -330,3 +330,4 @@ struct NonIsBitsDimsUndef NonIsBitsDimsUndef() = new() end @test Core.Compiler.is_inlineable_constant(NonIsBitsDimsUndef()) +@test !Core.Compiler.is_inlineable_constant((("a"^1000, "b"^1000), nothing))