Skip to content
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

Implement sym operands for global_asm! #94468

Merged
merged 3 commits into from
Apr 16, 2022
Merged

Conversation

Amanieu
Copy link
Member

@Amanieu Amanieu commented Mar 1, 2022

Tracking issue: #93333

This PR is pretty much a complete rewrite of sym operand support for inline assembly so that the same implementation can be shared by asm! and global_asm!. The main changes are:

  • At the AST level, sym is represented as a special InlineAsmSym AST node containing a path instead of an Expr.
  • At the HIR level, sym is split into SymStatic and SymFn depending on whether the path resolves to a static during AST lowering (defaults to SynFn if get_early_res fails).
    • SymFn is just an AnonConst. It runs through typeck and we just collect the resulting type at the end. An error is emitted if the type is not a FnDef.
    • SymStatic directly holds a path and the DefId of the static that it is pointing to.
  • The representation at the MIR level is mostly unchanged. There is a minor change to THIR where SymFn is a constant instead of an expression.
  • At the codegen level we need to apply the target's symbol mangling to the result of tcx.symbol_name() depending on the target. This is done by calling the LLVM name mangler, which handles all of the details.
    • On Mach-O, all symbols have a leading underscore.
    • On x86 Windows, different mangling is used for cdecl, stdcall, fastcall and vectorcall.
    • No mangling is needed on other platforms.

r? @nagisa
cc @eddyb

@rust-highfive
Copy link
Collaborator

Some changes occured to rustc_codegen_gcc

cc @antoyo

Some changes occurred in src/tools/clippy.

cc @rust-lang/clippy

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 1, 2022
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 1, 2022
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Copy link
Contributor

@antoyo antoyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gcc part looks good to me.

@Amanieu
Copy link
Member Author

Amanieu commented Mar 1, 2022

The gcc part looks good to me.

Note that there is still an issue on the GCC side: symbols are not mangled correctly on Mach-O (leading underscore) and x86 Windows (cdecl/stdcall/fastcall/vectorcall mangling). This is why we need to call LLVM to get the full mangled symbol name on those platforms.

Comment on lines +1917 to +1843
extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) {
RawRustStringOstream OS(Str);
GlobalValue *GV = unwrap<GlobalValue>(V);
Mangler().getNameWithPrefix(OS, GV, true);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if long-term we could implement this on the rustc side by getting the "mangling" flavor out of the datalayout string.

(Also, I wish both high-level mangling and this lower-level concept weren't both called "mangling" ugh)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rustc already parses the datalayout string for type layouts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was referring to the m:<mangling> field specifically. Though, looking at the docs:

  • x: Windows x86 COFF mangling: Private symbols get the usual prefix. Regular C symbols get a _ prefix. Functions with __stdcall, __fastcall, and __vectorcall have custom mangling that appends @N where N is the number of bytes used to pass parameters. C++ symbols starting with ? are not mangled in any way.

Yikes, that's a pretty hefty ask. Even if we generated it ourselves we'd probably still want to assert that we got it right by asking the backend what it would generate based on its own knowledge.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if long-term we could implement this on the rustc side by getting the "mangling" flavor out of the datalayout string.

LLVM seems to be moving in the direction of moving the responsibility for low-level mangling to the front-end: llvm/llvm-project#54090

Copy link
Member

@eddyb eddyb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM on the typeck/THIR side of things, nothing surprising there.

@@ -59,6 +61,11 @@ fn main() {
}
}

unsafe fn generic<T>() {
asm!("{}", sym generic::<T>);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this actually work correctly when the generic_const_exprs is enabled? Could you add a test for that as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails with error: unconstrained generic constant and I'm not exactly sure how to go about fixing it.

Copy link
Member

@nagisa nagisa Mar 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be fair, I feel like this should work, without any additional feature gates. I don't consider it a blocker for landing this PR, but I suspect it may require some significant changes to the approach (again) in order to make it work.

Comment on lines 28 to 35
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/type-check-1.rs:47:24
|
LL | let x = 0;
| ----- help: consider using `const` instead of `let`: `const x`
...
LL | asm!("{}", sym x);
| ^ non-constant value
Copy link
Member

@nagisa nagisa Mar 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would argue that the “sym operand must point to a function or static” kind of error would be more actionable here.

Especially because changing the let to a const won't help either way (I believe in any case, since FnDef types cannot be named)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be possible by using a custom rib kind in the resolver instead of using ConstantItemRibKind. I'll look into it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reworked name resolution to generate a specific error for referring to a local in a sym operand.

compiler/rustc_builtin_macros/src/asm.rs Outdated Show resolved Hide resolved
| hir::InlineAsmOperand::SplitInOut { .. } => {}
// No special checking is needed for these:
// - Typeck has checked that Const operands are integers.
// - AST lowering guarantees that SymStatic points to a static.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it guarantee that all sym STATICs become a SymStatic, though? It if does, that's also important to note (otherwise we'd start outputting errors in the branch below.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the DefId for a static is resolved during AST lowering and kept in the operand.

compiler/rustc_passes/src/intrinsicck.rs Outdated Show resolved Hide resolved
@bors
Copy link
Contributor

bors commented Mar 6, 2022

☔ The latest upstream changes (presumably #90076) made this pull request unmergeable. Please resolve the merge conflicts.

// TODO(@Commeownist): This may not be sufficient for all kinds of statics.
// Some statics may need the `@plt` suffix, like thread-local vars.
// TODO(@Amanieu): Additional mangling is needed on
// some targets to add a leading underscore (Mach-O).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change imply correct handling of @PLT and similar? If so, is there a test to that effect?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We never add @ suffixes to symbol names, it's the user's responsibility to add any necessary suffixes.

@bstrie bstrie mentioned this pull request Mar 16, 2022
12 tasks
@nagisa nagisa added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 3, 2022
@Amanieu
Copy link
Member Author

Amanieu commented Apr 4, 2022

Addressed all review feedback.

@Amanieu Amanieu removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 4, 2022
@bstrie bstrie added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 6, 2022
@nagisa
Copy link
Member

nagisa commented Apr 10, 2022

@bors r+

🥳

@bors
Copy link
Contributor

bors commented Apr 10, 2022

📌 Commit e0ed0f4 has been approved by nagisa

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 10, 2022
@bors
Copy link
Contributor

bors commented Apr 15, 2022

⌛ Testing commit 2d90e592e668e7aa8fd72062a51e604d128c9e34 with merge 4f6221d74fef75b3704a708f9f6a97a6d5749072...

@Dylan-DPC
Copy link
Member

@bors retry (yield to rollup)

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Apr 15, 2022

⌛ Testing commit 2d90e592e668e7aa8fd72062a51e604d128c9e34 with merge 276047d2ef1543eb466b420e5e82b72b912c9b5a...

@bors
Copy link
Contributor

bors commented Apr 15, 2022

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 15, 2022
@rust-log-analyzer

This comment has been minimized.

@Amanieu
Copy link
Member Author

Amanieu commented Apr 16, 2022

@bors r=nagisa

@bors
Copy link
Contributor

bors commented Apr 16, 2022

📌 Commit bdba897 has been approved by nagisa

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 16, 2022
@bors
Copy link
Contributor

bors commented Apr 16, 2022

⌛ Testing commit bdba897 with merge 080d545...

@bors
Copy link
Contributor

bors commented Apr 16, 2022

☀️ Test successful - checks-actions
Approved by: nagisa
Pushing 080d545 to master...

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (080d545): comparison url.

Summary:

  • Primary benchmarks: no relevant changes found
  • Secondary benchmarks: 🎉 relevant improvement found
Regressions 😿
(primary)
Regressions 😿
(secondary)
Improvements 🎉
(primary)
Improvements 🎉
(secondary)
All 😿 🎉
(primary)
count1 0 0 0 1 0
mean2 N/A N/A N/A -0.3% N/A
max N/A N/A N/A -0.3% N/A

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

Footnotes

  1. number of relevant changes

  2. the arithmetic mean of the percent change

flip1995 pushed a commit to flip1995/rust that referenced this pull request Apr 21, 2022
Implement sym operands for global_asm!

Tracking issue: rust-lang#93333

This PR is pretty much a complete rewrite of `sym` operand support for inline assembly so that the same implementation can be shared by `asm!` and `global_asm!`. The main changes are:
- At the AST level, `sym` is represented as a special `InlineAsmSym` AST node containing a path instead of an `Expr`.
- At the HIR level, `sym` is split into `SymStatic` and `SymFn` depending on whether the path resolves to a static during AST lowering (defaults to `SynFn` if `get_early_res` fails).
  - `SymFn` is just an `AnonConst`. It runs through typeck and we just collect the resulting type at the end. An error is emitted if the type is not a `FnDef`.
  - `SymStatic` directly holds a path and the `DefId` of the `static` that it is pointing to.
- The representation at the MIR level is mostly unchanged. There is a minor change to THIR where `SymFn` is a constant instead of an expression.
- At the codegen level we need to apply the target's symbol mangling to the result of `tcx.symbol_name()` depending on the target. This is done by calling the LLVM name mangler, which handles all of the details.
  - On Mach-O, all symbols have a leading underscore.
  - On x86 Windows, different mangling is used for cdecl, stdcall, fastcall and vectorcall.
  - No mangling is needed on other platforms.

r? `@nagisa`
cc `@eddyb`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.