-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Fix the representation of C void pointers in LLVM IR #11539
Conversation
Could you post some before/after code of what this change in types enables? It's also probably worth adding to the comment on the definition of |
Test code: fn main() {
let x = ~3;
} Compile with define internal void @main::hd4b0664c300788adah::v0.0({ i64, %tydesc*, i8*, i8*, i8 }* nocapture readnone) unnamed_addr #0 {
"function top level":
%1 = tail call %"enum.std::libc::types::common::c95::c_void[#1]"* @malloc(i64 8)
%2 = icmp eq %"enum.std::libc::types::common::c95::c_void[#1]"* %1, null
br i1 %2, label %_ZN2rt11global_heap10malloc_raw19h000735e5ce40b7f3aR4v0.9E.exit.thread, label %cond.i
_ZN2rt11global_heap10malloc_raw19h000735e5ce40b7f3aR4v0.9E.exit.thread: ; preds = %"function top level"
tail call void @abort()
call void @llvm.trap()
unreachable
cond.i: ; preds = %"function top level"
%3 = bitcast %"enum.std::libc::types::common::c95::c_void[#1]"* %1 to i64*
store i64 3, i64* %3, align 8
tail call void @free(%"enum.std::libc::types::common::c95::c_void[#1]"* %1) #1
ret void
} After: define internal void @main::hd4b0664c300788adah::v0.0({ i64, %tydesc*, i8*, i8*, i8 }* nocapture readnone) unnamed_addr #0 {
"_ZN13_$UP$$LP$$RP$9glue_drop19h82dc7f896d315c35a8E.exit":
ret void
} |
Before:
After:
|
I played around a bit, and I think we can get the same optimization with #[repr(u8)]
pub enum c_void {
priv variant1,
priv variant2,
} In order for |
Currently, we have c_void defined to be represented as an empty struct, but LLVM expects C's void* to be represented as i8*. That means we currently generate code in which LLVM doesn't recognize malloc() and free() and can't apply certain optimization that would remove calls to those functions.
The test suite isn't built with LTO. With LTO we get: Before:
After:
The "before" numbers are probably faster than before, because I copied the benchmarks into their own file and we still get better inlining behaviour when there is only one user of a function. |
Currently, we have c_void defined to be represented as an empty struct, but LLVM expects C's void* to be represented as i8*. That means we currently generate code in which LLVM doesn't recognize malloc() and free() and can't apply certain optimization that would remove calls to those functions.
…ntri3 Warn missing_enforced_import_renames by default Similar to rust-lang/rust-clippy#8261 that did the same thing to disallowed_methods & disallowed_types. This lint is also only triggered if import renames are defined in the `clippy.toml` file. changelog: Moved [`missing_enforced_import_renames`] to `style` (Now warn-by-default) [rust-lang#11539](rust-lang/rust-clippy#11539)
Currently, we have c_void defined to be represented as an empty struct,
but LLVM expects C's void* to be represented as i8*. That means we
currently generate code in which LLVM doesn't recognize malloc() and
free() and can't apply certain optimization that would remove calls to
those functions.