-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Support for the program data address space option of LLVM's Target Datalayout #54993
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
src/librustc_codegen_llvm/type_.rs
Outdated
if self.kind() == TypeKind::Function { | ||
unsafe { | ||
llvm::LLVMPointerType(self, | ||
cx.data_layout().program_memory_address_space as c_uint) |
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.
It is possible to "mis-use" this, I assume, for example via transmutes or something? Can we wind up with "valid Rust code" giving weird LLVM assertion failures or other errors?
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.
That's a good point. I'll see what happens if I transmute a few things to a function pointer.
cc @rust-lang/compiler — seems like an ad-hoc extension, nominating for brief T-compiler discussion to decide best path |
Yeah, this is definitely a bit ad-hoc, however overall the approach doesn't seem too bad to me. In any case, I came up with this while trying to get a target to work that isn't even officially supported yet. I'd be totally happy if you said this requires some more design work in the future. |
@TimNN to be clear, I didn't mean "ad hoc" in the pejorative sense. Just that it's one of those "small features" that we often decide without an RFC -- it might however warrant a feature gate or a tracking issue or some such thing. |
My patch can be easily extended to support this. But I think the space should be called the instruction address space, since "program memory" is kinda ambiguous (even though this is the term LLVM uses). @eddyb wanted any value to be cast into the flat address space before that value is used (ie uses of a |
I'd be fine with that, as you noticed I was just copying LLVM terminology.
I don't know. I understand how my patch works but overall I'm mostly unfamiliar with the involved concepts. IIRC, however, LLVM was unhappy casting a function to a function pointer in an incorrect addrspace (In case that information helps you). In any case, if you think that the functionality added here could be better supported with your patch, I'd be happy to wait for that to be merged. (I'd probably open this PR against the |
☔ The latest upstream changes (presumably #55171) made this pull request unmergeable. Please resolve the merge conflicts. |
src/librustc_codegen_llvm/type_.rs
Outdated
@@ -233,7 +234,26 @@ impl Type { | |||
} | |||
} | |||
|
|||
pub fn ptr_to(&self) -> &Type { | |||
pub fn ptr_to(&self, cx: &CodegenCx<'ll, '_>) -> &Type { | |||
if self.kind() == TypeKind::Function { |
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.
I really want to avoid us introspecting LLVM types. I think we should either not use non-flat address space pointers or we should special-case fn
pointers - from a quick search, I found only 2 places that create them:
rust/src/librustc_codegen_llvm/type_of.rs
Line 268 in 40123a1
FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to() |
rust/src/librustc_codegen_llvm/meth.rs
Line 42 in 40123a1
let llvtable = bx.pointercast(llvtable, fn_ty.llvm_type(bx.cx).ptr_to().ptr_to()); |
Since these are both calling .ptr_to()
on the result of FnType::llvm_type
, a helper method on FnType
can probably be added.
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.
I approve
src/librustc_target/abi/mod.rs
Outdated
@@ -96,6 +106,8 @@ impl TargetDataLayout { | |||
match spec.split(':').collect::<Vec<_>>()[..] { | |||
["e"] => dl.endian = Endian::Little, | |||
["E"] => dl.endian = Endian::Big, | |||
[ref p] if p.starts_with("P") => |
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.
[ref p] if p.starts_with("P") => | |
[p] if p.starts_with("P") => |
@TimNN Well, I've push a change to support the feature needed in this PR, so feel free to give it a try.
It does help. As I said, my patch put the vtable entries and all declared functions in the instruction address space, so that should work. I just realized it would not, however, do the same for function ptrs cast from non fn ptr values, like integers (perhaps a bit of an edge case). Currently, it tries to cast the value to the flat address space just like any other ptr. But, baring that, it should work for AVR with a suitable target spec. If you'd like to give my patch a shot, let me know how it goes! I would definitely prefer to have my patch merged instead; it (now) supports (that int -> fn ptr issue not withstanding) this address space, and can compile Rust which then runs on an AMDGPU. |
Thanks for your reviews, @eddyb & @nikomatsakis! I'm not sure what you think, but I feel like @DiamondLovesYou's PR #51576 is the way to go in the long term. I however don't know what the timeline would be to get that merged (or if you maybe have concerns that would prevent merging it). I see two ways forward:
What do you all think? |
A drive-by comment from AVR-land... We think that users would like / need the ability to annotate certain pieces of memory with which address space they should go in. We opened an issue about this, but in short, something like this strawman syntax could address the issue: #[space(progmem)]
pub static FOOBAR: &'static str = "hello world"; I don't know that this PR would handle something like that, but it may be worth keeping in mind for the underlying design. |
5a2494b
to
465ba9d
Compare
I've updated this PR to address the review comments. However I'll close this for now until there's a decision on ##51576. |
Your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem. Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
Support for the program data address space option of LLVM's Target Datalayout This was introduced recently (specifically, for AVR, cc @dylanmckay). (I came up with this when attempting to run [avr-rust](/~https://github.com/avr-rust/rust) rebased on the latest [rust-lang](/~https://github.com/rust-lang/rust) commits. If this requires a different design, some additional discussions, or is not something to pursue right now, I'd be happy to close this PR). Note that this somewhat overlaps with @DiamondLovesYou's rust-lang#51576, I think, although the implementation here is significantly simpler: Since the address space applies to _all_ program data, we can just check the pointee's type whenever we create an LLVM pointer type. If it is a function we use the program data address space; if not we use the default address space. cc @eddyb, who has been reviewing rust-lang#51576 Ref: https://llvm.org/docs/LangRef.html#data-layout
⌛ Testing commit 50a2d47 with merge f705d13c0de0f6721468e867ae993bbf819ddbbd... |
💔 Test failed - status-appveyor |
@bors retry 3 hour timeout in |
⌛ Testing commit 50a2d47 with merge b3a9ad420ecc2b738cc66a2437a865ec6f6f648d... |
💔 Test failed - status-appveyor |
@bors retry
|
Support for the program data address space option of LLVM's Target Datalayout This was introduced recently (specifically, for AVR, cc @dylanmckay). (I came up with this when attempting to run [avr-rust](/~https://github.com/avr-rust/rust) rebased on the latest [rust-lang](/~https://github.com/rust-lang/rust) commits. If this requires a different design, some additional discussions, or is not something to pursue right now, I'd be happy to close this PR). Note that this somewhat overlaps with @DiamondLovesYou's #51576, I think, although the implementation here is significantly simpler: Since the address space applies to _all_ program data, we can just check the pointee's type whenever we create an LLVM pointer type. If it is a function we use the program data address space; if not we use the default address space. cc @eddyb, who has been reviewing #51576 Ref: https://llvm.org/docs/LangRef.html#data-layout
☀️ Test successful - status-appveyor, status-travis |
This was introduced recently (specifically, for AVR, cc @dylanmckay).
(I came up with this when attempting to run avr-rust rebased on the latest rust-lang commits. If this requires a different design, some additional discussions, or is not something to pursue right now, I'd be happy to close this PR).
Note that this somewhat overlaps with @DiamondLovesYou's #51576, I think, although the implementation here is significantly simpler: Since the address space applies to all program data, we can just check the pointee's type whenever we create an LLVM pointer type. If it is a function we use the program data address space; if not we use the default address space.
cc @eddyb, who has been reviewing #51576
Ref: https://llvm.org/docs/LangRef.html#data-layout