

Define immutable statics with const qualified types by yvt · Pull Request #165 ·...
source link: https://github.com/rust-lang/rustc_codegen_gcc/pull/165
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

This PR adds const
qualification to the types of immutable statics to allow them to be placed in a read-only section.
Fixes #161.
#[no_mangle]
pub extern "C" fn ultimate_answer_concise() -> u32 {
const CANDIDATES: &[u32] = &[41, 42, 43];
CANDIDATES[1]
}
Before:
0000000000001100 <ultimate_answer>:
1100: 48 8d 05 19 2f 00 00 lea 0x2f19(%rip),%rax # 4020 <ultimate_answer_concise+0x2f10>
1107: c3 ret
1108: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
110f: 00
After:
0000000000001110 <ultimate_answer_concise>:
1110: b8 2a 00 00 00 mov $0x2a,%eax
1115: c3
|
With
With
|
Collaborator
antoyo
left a comment
LGTM.
Thanks!
Outdated Show resolved
I realized that a
Do you want me to disable this PR's behavior entirely for libgccjit12, or ...? |
Just adding |
The const qualifier is now stripped as soon as a static's address is taken. This prevents const-qualified pointers, which shouldn't appear otherwise, from circulating and may fix bugs that we are not aware of. Also feature-gates the use of |
Collaborator
antoyo
left a comment
Can you explain to me why you canonicalize the rvalue?
I don't understand why it's done.
Outdated Show resolved
Basically, when taking a pointer of a static, we don't want to get different pointer types depending on whether the static is mutable ( |
Do you mean that was added as a workaround to libgccjit, to be able to load the address of a global variable? If so, maybe there's a better solution. Thinking out loud, it would be great if we could know in Since that might not be easy to do (and the solution posted above is a bit hackish), another option could be to set an initializer to the local variable. Not sure if that would work as well (because the needs to be allowed in initializers), so perhaps you would have to only do that when the pointer is const (but then, we can surely have a const pointer to a non-global). What do you think of this? Now that I think of it, those two ideas do not seem better than yours. However, I worry about the effect of only having non-const pointer (could that change the code generation?). Perhaps it would be better to only call canonicalize in |
To be more precise, it's to make the local variable to store the loaded data assignable. (A const-qualified local variable cannot be assigned to.) I'd rather see this as a symptom of inconsistent typing of rvalues, which this "canonicalization" fixes. Meanwhile, #170 has changed the situation; the local variable created in
Assuming that the semantics of libgccjit instructions is similar to that of C, the presence of const qualifier only matters for the mutability of variables ( |
Collaborator
antoyo commented 24 days ago
Why would you recommend to still do canonicalization?
Good to know. I worried about TBAA doing something here, but it's disabled in Rust anyway. |
I'm starting to understand your design intent. But as you probably already know, there are differences between LLVM and libgccjit's APIs, and sometimes we have to make compromise and take an approach unique to cg_gcc. And when we do, the best thing we can do to mitigate the impact is to contain it to a narrow scope. Why did I add Realizing immutability in this way has a side effect: the pointer taken from an immutable global variable now has a different type. In one case (#165 (comment)) this actually caused a type mismatch in a module that is seemingly unconnected to this change. This particular case was mitigated by #170, but we don't know to what extent this will cause problems in the present or the future. This is a problem specific to libgccjit, so cg_llvm will continue to assume that the pointer types of immutable global variables and mutable ones are identical, and whenever we port its changes to cg_gcc, we risk breakage because this assumption does not hold for libgccjit. This brings us to a solution: Cast the taken pointer immediately ("canonicalization"), thus localizing the problem to a module that is responsible for dealing with global variables. In conclusion, doing canonicalization here keeps the code free of latent bugs, improves the code quality, and minimizes risks, which is why I'm still in favor of doing this. |
Collaborator
antoyo commented 22 days ago
That makes a lot of sense, so let's keep it that way. You could please add these explanations in the code as comments? |
Collaborator
antoyo commented 19 days ago
I believe I could make the equivalent of (Sorry for all the back-and-forth.) Thanks for all your work! |
Contributor
Author
yvt commented 17 days ago
Yes, I think so. Though, I'm curious how willing the libgccjit maintainers are to accept the patch, especially considering that it's not strictly necessary and doesn't directly map to any of the existing GCC variable attributes. |
Collaborator
antoyo commented 17 days ago
There was no such concern when I added a new API to set the alignment while it was already possible to set it via the type, so my guess is that it's gonna be OK. (Sure, there's a GCC attribute for alignment, but still.) |
Contributor
Author
yvt commented 17 days ago
In that case, I'd say go for it. |
Collaborator
antoyo commented 17 days ago
Ok, I'll do it in the following days. |
Collaborator
antoyo commented 8 days ago
Ok, I added the function in this commit and in the bindings as well. |
Collaborator
antoyo commented 8 days ago
I just wanted to make sure that using the new readonly API it gives the same result. |
Yes, it's a perfect match
|
Collaborator
antoyo
left a comment
A small nit, then we can merge.
Thanks a lot!
Outdated Show resolved
Collaborator
antoyo
left a comment
Thanks a lot!
And again, sorry for all the back and forth.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK