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 global_asm!() (RFC 1548) #40702

Merged
merged 10 commits into from
Apr 15, 2017
Merged

Implement global_asm!() (RFC 1548) #40702

merged 10 commits into from
Apr 15, 2017

Conversation

mrhota
Copy link
Contributor

@mrhota mrhota commented Mar 21, 2017

This is a first attempt. One (potential) problem I haven't solved is how to handle multiple usages of global_asm! in a module/crate. It looks like LLVMSetModuleInlineAsm overwrites module asm, and LLVMAppendModuleInlineAsm is not provided in LLVM C headers 😦

I can provide more detail as needed, but honestly, there's not a lot going on here.

r? @eddyb

CC @Amanieu @jackpot51

Tracking issue: #35119

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @pnkfelix (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@mrhota
Copy link
Contributor Author

mrhota commented Mar 21, 2017

I will rebase this evening.

@eddyb
Copy link
Member

eddyb commented Mar 21, 2017

cc @nagisa @michaelwoerister

@mattico
Copy link
Contributor

mattico commented Mar 21, 2017

If an LLVM API is not provided by the C API, you can add a C++ wrapper in rustllvm and the corresponding Rust types in librustc_llvm. Look at the rest of the file to see the conventions that are used (to_rust, from_rust, etc.)

@mrhota
Copy link
Contributor Author

mrhota commented Mar 21, 2017

Thank you @mattico!

@steveklabnik I updated the unstable-book, so you might want to look it over.

@mrhota mrhota changed the title [WIP] global_asm!() [WIP] Implement global_asm!() (RFC 1548) Mar 21, 2017
my_asm_func:
ret
__other_cancel:
jmp __cancel
Copy link
Contributor

Choose a reason for hiding this comment

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

This would need to be mangled, wouldn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah, yes, we need a #[no_mangle]. Thanks!

@mrhota
Copy link
Contributor Author

mrhota commented Mar 22, 2017

We have a feature-gate test and a couple codegen tests! We also have a new unstable-book page. My initial problems/questions have been resolved.

@mrhota mrhota changed the title [WIP] Implement global_asm!() (RFC 1548) Implement global_asm!() (RFC 1548) Mar 22, 2017
Copy link
Member

@Amanieu Amanieu left a comment

Choose a reason for hiding this comment

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

I think a test should be added which uses include_str! with global_asm!.

```rust,ignore
# #![feature(global_asm)]
# you also need relevant target_arch cfgs
global_asm!(include_str("something_neato.s"));
Copy link
Member

Choose a reason for hiding this comment

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

This should be include_str! (missing !).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks

@mrhota
Copy link
Contributor Author

mrhota commented Mar 23, 2017

r? @pnkfelix

@mrhota
Copy link
Contributor Author

mrhota commented Mar 23, 2017

@Amanieu we have a new test using include_str!. Hopefully it's what you had in mind.

@Amanieu
Copy link
Member

Amanieu commented Mar 23, 2017

@mrhota Yes, that's what I had in mind.

@mrhota
Copy link
Contributor Author

mrhota commented Mar 24, 2017

@eddyb @nagisa @michaelwoerister any thoughts here? not sure who should review

Copy link
Member

@nagisa nagisa left a comment

Choose a reason for hiding this comment

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

Seems good to me overall.

I’d like, however, more tests. Namely to ensure stuff like these compile. Compilation here is the important distinction, as codegen tests do not actually go through the assembler, and only generate LLVM-IR, which does not insure the actual codegen works.

// cfg-gating works properly
#[cfg(target_arch="x86")] global_asm! { ... }
#[cfg(target_arch="x86_64")] global_asm! { ... }

// codegen tests for all borderline T-1 architectures
global_asm!("foo blt foo") // arm
global_asm!("foo: j foo") // mips
global_asm!("foo: b foo") // ppc

// except according to those terms.

// ignore-arm
// ignore-aarch64
Copy link
Member

Choose a reason for hiding this comment

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

Since assembly is for x86, this list should be significantly longer.

Namely we also support: MIPS, PowerPC, SystemZ, wasm, asmjs, nacl, nvptx, avr, msp430 and probably more stuff I forgot to mention.

Copy link
Member

@nagisa nagisa Mar 24, 2017

Choose a reason for hiding this comment

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

A good approach would be to git grep '// ignore-' src/tests and add every single suffix that's seems unrelated to x86.

// except according to those terms.

// ignore-arm
// ignore-aarch64
Copy link
Member

Choose a reason for hiding this comment

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

Since assembly is for x86, this list should be significantly longer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I copied this from another codegen test, I think. I'll fill out the list.

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub struct GlobalAsm {
pub asm: Symbol,
pub asm_str_style: StrStyle,
Copy link
Member

Choose a reason for hiding this comment

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

Seems to be unused/unnecessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch

@mrhota
Copy link
Contributor Author

mrhota commented Mar 25, 2017

@nagisa I might be missing something, but what's the point of testing full-compile in addition to codegen? The real meat of this feature enables insertion of module asm into llvm-ir by using global_asm!, which the codegen tests ensure.

If we test full-compile, then we're just testing that LLVM does what it says it'll do with module asms. If the compile fails at that point, rustc is off the hook, since it's either an LLVM problem, or the programmer provided bad assembly.

global_asm!("put on your time travel trousers!");

should in fact go all the way through codegen, and should produce

... module asm "put on your time travel trousers!"

which will obviously fail to assemble, but that's not our problem. The assembly template provided to global_asm! is (semantically) completely inaccessible to rustc and LLVM.

But, again, the codegen tests ensure rustc faithfully has handed the provided assembly template to LLVM, which itself promises faithfully to deliver it to the assembler.

@nagisa
Copy link
Member

nagisa commented Mar 25, 2017

If the compile fails at that point, rustc is off the hook, since it's either an LLVM problem, or the programmer provided bad assembly.

This is irrelevant from the perspective of the end user – they use rustc, not LLVM. You can assign blame to some dependency, but the fact of dependencies not working propagates to the end products.

Now, I don’t feel strongly about this, since this is will be unstable for a foreseeable future, but such tests will have to materialise before this gets stabilised. Might as well materialise them right now, then, right?

EDIT: It might as well point out the fact of us having LLVM misconfigured in a way that it is unable to work with the module level assembly :)

@mrhota
Copy link
Contributor Author

mrhota commented Mar 26, 2017

@nagisa I'm at a loss; I have no idea why the builder keeps failing codegen tests since I added more // ignore-s. It passes locally.

@mrhota
Copy link
Contributor Author

mrhota commented Mar 27, 2017

r? @nikomatsakis you seemed to be somewhat interested in how this feature turns out

@bors
Copy link
Contributor

bors commented Mar 29, 2017

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

@nagisa
Copy link
Member

nagisa commented Mar 29, 2017

I'm at a loss; I have no idea why the builder keeps failing codegen tests since I added more // ignore-s. It passes locally.

I’ve got no idea why it fails either. I’ll make a mental note to try and build this locally, but am likely to forget.

@mrhota
Copy link
Contributor Author

mrhota commented Mar 30, 2017

@nagisa thanks. I ran the failing docker container's build on my mac and it passed. I ran the tests on my mac, too, and they pass.

@mrhota
Copy link
Contributor Author

mrhota commented Mar 30, 2017

@nagisa OK, resolved build failure. Was that the last thing on your checklist?

@Amanieu github indicates that you requested changes. I think I resolved the issues you mentioned, but I don't know if you manually have to check the box...

@Amanieu
Copy link
Member

Amanieu commented Mar 30, 2017

I don't see a box to check. Anyways, I'm happy with the changes.

@bors
Copy link
Contributor

bors commented Apr 13, 2017

💔 Test failed - status-appveyor

@TimNN
Copy link
Contributor

TimNN commented Apr 13, 2017

@bors retry

fatal: unable to access 'https://github.com/rust-lang/rust.git/': Unknown SSL protocol error in connection to github.com:443 ?!

@bors
Copy link
Contributor

bors commented Apr 13, 2017

⌛ Testing commit 63a0747 with merge a2e97b2...

@bors
Copy link
Contributor

bors commented Apr 13, 2017

💔 Test failed - status-appveyor

@mrhota
Copy link
Contributor Author

mrhota commented Apr 13, 2017

same SSL error on Windows

@alexcrichton
Copy link
Member

@bors: retry

@bors
Copy link
Contributor

bors commented Apr 13, 2017

⌛ Testing commit 63a0747 with merge a5d5852...

bors added a commit that referenced this pull request Apr 13, 2017
Implement global_asm!() (RFC 1548)

This is a first attempt. ~~One (potential) problem I haven't solved is how to handle multiple usages of `global_asm!` in a module/crate. It looks like `LLVMSetModuleInlineAsm` overwrites module asm, and `LLVMAppendModuleInlineAsm` is not provided in LLVM C headers 😦~~

I can provide more detail as needed, but honestly, there's not a lot going on here.

r? @eddyb

CC @Amanieu @jackpot51

Tracking issue: #35119
@bors
Copy link
Contributor

bors commented Apr 13, 2017

💔 Test failed - status-appveyor

@frewsxcv
Copy link
Member

That appveyor failure looks legit.

@mrhota
Copy link
Contributor Author

mrhota commented Apr 13, 2017

failures:
---- [run-pass] run-pass\simple_global_asm.rs stdout ----
	
error: compilation failed!
status: exit code: 101
command: PATH="C:\projects\rust\build\i686-pc-windows-gnu\stage2\bin;C:\projects\rust\build\i686-pc-windows-gnu\stage2-tools\i686-pc-windows-gnu\release\deps;C:\projects\rust\build\i686-pc-windows-gnu\stage2\lib\rustlib\i686-pc-windows-gnu\lib;C:\Program Files (x86)\Inno Setup 5;C:\Python27;C:\projects\rust\mingw32\bin;C:\msys64\usr\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\7-Zip;C:\Program Files\Microsoft\Web Platform Installer;C:\Tools\GitVersion;C:\Tools\PsTools;C:\Program Files\Git LFS;C:\Program Files (x86)\Subversion\bin;C:\Program Files\Microsoft SQL Server\120\Tools\Binn;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn;C:\Program Files\Microsoft SQL Server\120\DTS\Binn;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio;C:\Tools\WebDriver;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.4;C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssemblies;C:\Program Files (x86)\Microsoft SDKs\Azure\CLI\wbin;C:\Ruby193\bin;C:\Tools\NUnit\bin;C:\Tools\xUnit;C:\Tools\MSpec;C:\Tools\Coverity\bin;C:\Program Files (x86)\CMake\bin;C:\go\bin;C:\Program Files\Java\jdk1.8.0\bin;C:\Python27;C:\Program Files\nodejs;C:\Program Files (x86)\iojs;C:\Program Files\iojs;C:\Users\appveyor\AppData\Roaming\npm;C:\Program Files\Microsoft SQL Server\130\Tools\Binn;C:\Program Files (x86)\MSBuild\14.0\Bin;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\120;C:\Tools\NuGet;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files\Microsoft DNX\Dnvm;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn;C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn;C:\Program Files (x86)\Microsoft SQL Server\130\DTS\Binn;C:\Program Files\Microsoft SQL Server\130\DTS\Binn;C:\Program Files (x86)\Microsoft SQL Server\110\DTS\Binn;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn;C:\Program Files (x86)\Apache\Maven\bin;C:\Python27\Scripts;C:\Tools\NUnit3;C:\ProgramData\chocolatey\bin;C:\Program Files\Mercurial;C:\Program Files (x86)\Yarn\bin;C:\Program Files\LLVM\bin;C:\Program Files\dotnet;C:\Program Files\erl8.3\bin;C:\Tools\curl\bin;C:\Program Files\Microsoft Service Fabric\bin\Fabric\Fabric.Code;C:\Program Files\Microsoft SDKs\Service Fabric\Tools\ServiceFabricLocalClusterManager;C:\Program Files (x86)\nodejs;C:\Program Files\Git\cmd;C:\Program Files\Git\usr\bin;C:\Program Files\Amazon\AWSCLI;C:\Users\appveyor\AppData\Local\Yarn\.bin;C:\Users\appveyor\AppData\Roaming\npm;C:\Program Files\AppVeyor\BuildAgent;C:\projects\rust;C:\projects\rust\handle" C:\projects\rust\build\i686-pc-windows-gnu\stage2\bin\rustc.exe C:\projects\rust\src/test\run-pass\simple_global_asm.rs -L C:\projects\rust\build\i686-pc-windows-gnu\test\run-pass --target=i686-pc-windows-gnu --error-format json -L C:\projects\rust\build\i686-pc-windows-gnu\test\run-pass\simple_global_asm.stage2-i686-pc-windows-gnu.run-pass.libaux -C prefer-dynamic -o C:\projects\rust\build\i686-pc-windows-gnu\test\run-pass\simple_global_asm.stage2-i686-pc-windows-gnu.exe -Crpath -O -Lnative=C:\projects\rust\build\i686-pc-windows-gnu\native\rust-test-helpers
stdout:
------------------------------------------
------------------------------------------
stderr:
------------------------------------------
{"message":"linking with `gcc` failed: exit code: 1","code":null,"level":"error","spans":[],"children":[{"message":"\"gcc\" \"-Wl,--enable-long-section-names\" \"-fno-use-linker-plugin\" \"-Wl,--nxcompat\" \"-nostdlib\" \"-Wl,--large-address-aware\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\stage2\\\\lib\\\\rustlib\\\\i686-pc-windows-gnu\\\\lib\\\\crt2.o\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\stage2\\\\lib\\\\rustlib\\\\i686-pc-windows-gnu\\\\lib\\\\rsbegin.o\" \"-L\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\stage2\\\\lib\\\\rustlib\\\\i686-pc-windows-gnu\\\\lib\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\test\\\\run-pass\\\\simple_global_asm.0.o\" \"-o\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\test\\\\run-pass\\\\simple_global_asm.stage2-i686-pc-windows-gnu.exe\" \"-Wl,--gc-sections\" \"-nodefaultlibs\" \"-L\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\test\\\\run-pass\" \"-L\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\test\\\\run-pass\\\\simple_global_asm.stage2-i686-pc-windows-gnu.run-pass.libaux\" \"-L\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\native\\\\rust-test-helpers\" \"-L\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\stage2\\\\lib\\\\rustlib\\\\i686-pc-windows-gnu\\\\lib\" \"-L\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\stage2\\\\lib\\\\rustlib\\\\i686-pc-windows-gnu\\\\lib\" \"-l\" \"std-4d6881ec6132b951\" \"-Wl,-Bstatic\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\stage2\\\\lib\\\\rustlib\\\\i686-pc-windows-gnu\\\\lib\\\\libcompiler_builtins-7ac5a34e9b48514f.rlib\" \"-Wl,-Bdynamic\" \"-l\" \"advapi32\" \"-l\" \"ws2_32\" \"-l\" \"userenv\" \"-l\" \"shell32\" \"-lmingwex\" \"-lmingw32\" \"-lgcc\" \"-lmsvcrt\" \"-luser32\" \"-lkernel32\" \"C:\\\\projects\\\\rust\\\\build\\\\i686-pc-windows-gnu\\\\stage2\\\\lib\\\\rustlib\\\\i686-pc-windows-gnu\\\\lib\\\\rsend.o\"","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"C:\\projects\\rust\\build\\i686-pc-windows-gnu\\test\\run-pass\\simple_global_asm.0.o:(.text+0x15): undefined reference to `foo'\r\ncollect2.exe: error: ld returned 1 exit status\r\n","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":null}
{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":null}
------------------------------------------
thread '[run-pass] run-pass\simple_global_asm.rs' panicked at 'explicit panic', src\tools\compiletest\src\runtest.rs:2627
note: Run with `RUST_BACKTRACE=1` for a backtrace.
failures:
    [run-pass] run-pass\simple_global_asm.rs
test result: FAILED. 2632 passed; 1 failed; 17 ignored; 0 measured

@alexcrichton @nagisa any pointers? I don't have access to a MSYS_BITS=32, RUST_CONFIGURE_ARGS=--build=i686-pc-windows-gnu environment. Maybe there's something obvious I missed, but I don't see how foo should be undefined in src/test/run-pass/simple_global_asm.rs on that environment.

Also, note that codegen tests pass on that platform, which is to say global_asm's argument is faithfully passed to LLVM and written out in llvm-ir, which is the whole point of this feature. A test like this was my worry when, as I indicated to @nagisa before, this test is now only testing that platform's assembler and linker, not rustc. I'm now caught in an endless loop of fiddling with a test until it passes. That is, it's a pointless test.

@alexcrichton
Copy link
Member

The failure here is:

undefined reference to 'foo'

That's probably because of the way symbols are named across systems. I believe on some platforms (like OSX and Windows) you need a leading underscore (e.g. _foo in the asm) whereas others like Linux you can omit it.

@mrhota
Copy link
Contributor Author

mrhota commented Apr 13, 2017

@alexcrichton that seems to be it. Thanks!

@Mark-Simulacrum Mark-Simulacrum added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 14, 2017
@mrhota
Copy link
Contributor Author

mrhota commented Apr 14, 2017

@alexcrichton ready again...

I declared both foo and _foo in the assembly. Hopefully this will satisfy windows' linker:

    .global foo
    .global _foo
foo:
_foo:
    ret

@nikomatsakis
Copy link
Contributor

@bors r=nagisa

@bors
Copy link
Contributor

bors commented Apr 14, 2017

📌 Commit a35c4e3 has been approved by nagisa

frewsxcv added a commit to frewsxcv/rust that referenced this pull request Apr 14, 2017
Implement global_asm!() (RFC 1548)

This is a first attempt. ~~One (potential) problem I haven't solved is how to handle multiple usages of `global_asm!` in a module/crate. It looks like `LLVMSetModuleInlineAsm` overwrites module asm, and `LLVMAppendModuleInlineAsm` is not provided in LLVM C headers 😦~~

I can provide more detail as needed, but honestly, there's not a lot going on here.

r? @eddyb

CC @Amanieu @jackpot51

Tracking issue: rust-lang#35119
@bors
Copy link
Contributor

bors commented Apr 14, 2017

⌛ Testing commit a35c4e3 with merge ea2c4f5...

@frewsxcv
Copy link
Member

@bors retry reprioritizing

bors added a commit that referenced this pull request Apr 14, 2017
Rollup of 4 pull requests

- Successful merges: #40702, #41172, #41249, #41303
- Failed merges:
@bors
Copy link
Contributor

bors commented Apr 15, 2017

⌛ Testing commit a35c4e3 with merge f0ca5d4...

@bors bors merged commit a35c4e3 into rust-lang:master Apr 15, 2017
@mrhota mrhota deleted the global_asm branch April 15, 2017 02:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.