-
-
Notifications
You must be signed in to change notification settings - Fork 8
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
Add more types to the returned allocation #19
Changes from 3 commits
7da2acf
2f79357
41c3931
a07a4a2
f71421b
47188ae
ddd6af4
cf363bf
f8eae41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -19,6 +19,8 @@ const known_nonalloc_funcs = ( | |||||||||
"jl_pop_handler", "ijl_pop_handler", | ||||||||||
"jl_f_typeof", "ijl_f_typeof", | ||||||||||
"jl_clock_now", "ijl_clock_now", | ||||||||||
"jl_throw", "ijl_throw", #= the allocation of the error is separate =# | ||||||||||
"jl_gc_queue_root", "ijl_gc_queue_root", | ||||||||||
) | ||||||||||
|
||||||||||
const known_alloc_with_throw_funcs = ( | ||||||||||
|
@@ -73,9 +75,8 @@ function guess_julia_type(val::LLVM.Value, typeof=true) | |||||||||
end | ||||||||||
if isa(val, LLVM.CallInst) && typeof | ||||||||||
fn = LLVM.called_operand(val) | ||||||||||
if isa(fn, LLVM.Function) && (LLVM.name(fn) in ("ijl_gc_pool_alloc_instrumented", "ijl_gc_big_alloc_instrumented", "ijl_gc_alloc_typed")) | ||||||||||
if isa(fn, LLVM.Function) && (LLVM.name(fn) in ("ijl_gc_pool_alloc_instrumented", "ijl_gc_big_alloc_instrumented", "ijl_gc_alloc_typed", "jl_gc_pool_alloc_instrumented", "jl_gc_big_alloc_instrumented", "jl_gc_alloc_typed")) | ||||||||||
res = guess_julia_type(operands(val)[end-1], false) | ||||||||||
|
||||||||||
if res !== nothing | ||||||||||
return res | ||||||||||
end | ||||||||||
|
@@ -87,10 +88,63 @@ function guess_julia_type(val::LLVM.Value, typeof=true) | |||||||||
return res | ||||||||||
end | ||||||||||
end | ||||||||||
|
||||||||||
if isa(fn, LLVM.Function) && in(LLVM.name(fn), ("ijl_alloc_string", "jl_alloc_string")) | ||||||||||
return String | ||||||||||
end | ||||||||||
|
||||||||||
if isa(fn, LLVM.Function) && in(LLVM.name(fn), ("ijl_copy_array", "jl_copy_array")) | ||||||||||
return Array | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any way for us to know the type of the array? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, grepping for this function in the runtime brings up nothing for me. Do you know what's up? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is typo of mine, it should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this still needs fixing? |
||||||||||
end | ||||||||||
if isa(fn, LLVM.Function) && occursin(r"(ijl_|jl_)box_(.*)", name(fn)) | ||||||||||
typestr = match(r"(ijl_|jl_)box_(.*)", name(fn)).captures[end] | ||||||||||
typestr == "bool" && return Bool | ||||||||||
typestr == "char" && return Char | ||||||||||
typestr == "float32" && return Float32 | ||||||||||
typestr == "float64" && return Float64 | ||||||||||
typestr == "int16" && return Int16 | ||||||||||
typestr == "int32" && return Int32 | ||||||||||
typestr == "int64" && return Int64 | ||||||||||
typestr == "int8" && return Int8 | ||||||||||
typestr == "slotnumber" && return Core.SlotNumber | ||||||||||
typestr == "ssavalue" && return Core.SSAValue | ||||||||||
typestr == "uint16" && return UInt16 | ||||||||||
typestr == "uint32" && return UInt32 | ||||||||||
typestr == "uint64" && return UInt64 | ||||||||||
typestr == "uint8" && return UInt8 | ||||||||||
typestr == "uint8pointer" && return Ptr{UInt8} | ||||||||||
typestr == "voidpointer" && return Ptr{Cvoid} | ||||||||||
return Any | ||||||||||
end | ||||||||||
|
||||||||||
if isa(fn, LLVM.Function) && in(LLVM.name(fn), ("ijl_gc_pool_alloc", "jl_gc_pool_alloc")) | ||||||||||
for use in uses(val) | ||||||||||
istag = user(use) | ||||||||||
if isa(istag, LLVM.BitCastInst) | ||||||||||
for bituse in uses(istag) | ||||||||||
isgep = user(bituse) | ||||||||||
if isa(isgep, LLVM.GetElementPtrInst) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this logic is correct, since it will, e.g., ignore a It might be simpler to introduce something like |
||||||||||
istag = isgep | ||||||||||
@goto gep_handling | ||||||||||
end | ||||||||||
end | ||||||||||
elseif isa(istag, LLVM.GetElementPtrInst) | ||||||||||
@goto gep_handling | ||||||||||
else | ||||||||||
continue | ||||||||||
end | ||||||||||
@label gep_handling | ||||||||||
if convert(Int,operands(istag::LLVM.GetElementPtrInst)[2]) == -1 | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Also, ideally this would also inspect the type of the GEP so that we know exactly what byte offset this is in memory (and the size of the store). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also I think this needs to check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we are lacking the accessor functions :(. I need to add some getSrcType/getDestType calls to LLVM.jl There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But I don't think we do a -1 gep on anything except the tag. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, it looks like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, great we do wrap it. We don't have most of these. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's only in LLVM 15 :( |
||||||||||
for gepuse in uses(istag) | ||||||||||
isstore = user(gepuse) | ||||||||||
if isa(isstore, LLVM.StoreInst) | ||||||||||
return guess_julia_type(operands(isstore)[1], true) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All asserts are unnecessary - this is to make explicit our assumptions on the IR. Do we expect this to not be constant sometimes? If so, can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it costs us nothing to do it. |
||||||||||
end | ||||||||||
end | ||||||||||
end | ||||||||||
end | ||||||||||
return guess_julia_type(operands(val)[1], false) | ||||||||||
end | ||||||||||
break | ||||||||||
end | ||||||||||
break | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A good test for this is to check that
foo() = throw(EOFError())
is considered non-allocating