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

[WIP][RFC] initial support for PTX generation #34195

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bootstrap/build/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub fn llvm(build: &Build, target: &str) {
.out_dir(&dst)
.profile(if build.config.llvm_optimize {"Release"} else {"Debug"})
.define("LLVM_ENABLE_ASSERTIONS", assertions)
.define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC")
.define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC;NVPTX")
Copy link
Member

Choose a reason for hiding this comment

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

Out of curiosity, and just to confirm, this doesn't increase our binary sizes by like 100M or compile times by like 10 minutes, right? That is, this should in theory be a relatively small backend?

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 don't have any precise measurement but:

# Nightly of 2016-06-08
$ du -h $(rustc --print sysroot)/lib
28K     /home/japaric/.multirust/toolchains/nightly-2016-06-08-x86_64-unknown-linux-gnu/lib/rustlib/etc
147M    /home/japaric/.multirust/toolchains/nightly-2016-06-08-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib
147M    /home/japaric/.multirust/toolchains/nightly-2016-06-08-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu
147M    /home/japaric/.multirust/toolchains/nightly-2016-06-08-x86_64-unknown-linux-gnu/lib/rustlib
254M    /home/japaric/.multirust/toolchains/nightly-2016-06-08-x86_64-unknown-linux-gnu/lib

# This PR on top of that nightly (Note: stage1)
$ du -h build/x86_64-unknown-linux-gnu/stage1/lib
155M    build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib
155M    build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu
155M    build/x86_64-unknown-linux-gnu/stage1/lib/rustlib
253M    build/x86_64-unknown-linux-gnu/stage1/lib

Also the LLVM static libraries are rather small:

$ ls -hs build/x86_64-unknown-linux-gnu/llvm/lib/*PTX*
160K build/x86_64-unknown-linux-gnu/llvm/lib/libLLVMNVPTXAsmPrinter.a
2.3M build/x86_64-unknown-linux-gnu/llvm/lib/libLLVMNVPTXCodeGen.a
384K build/x86_64-unknown-linux-gnu/llvm/lib/libLLVMNVPTXDesc.a
8.0K build/x86_64-unknown-linux-gnu/llvm/lib/libLLVMNVPTXInfo.a

No data on compile times.

.define("LLVM_INCLUDE_EXAMPLES", "OFF")
.define("LLVM_INCLUDE_TESTS", "OFF")
.define("LLVM_INCLUDE_DOCS", "OFF")
Expand Down
19 changes: 19 additions & 0 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,4 +602,23 @@ extern "rust-intrinsic" {
/// on MSVC it's `*mut [usize; 2]`. For more information see the compiler's
/// source as well as std's catch implementation.
pub fn try(f: fn(*mut u8), data: *mut u8, local_ptr: *mut u8) -> i32;

}

#[cfg(not(stage0))]
#[cfg(arch = "nvptx")]
extern "rust-intrinsic" {
pub fn thread_idx_x() -> i32;
pub fn thread_idx_y() -> i32;
pub fn thread_idx_z() -> i32;
pub fn block_idx_x() -> i32;
pub fn block_idx_y() -> i32;
pub fn block_idx_z() -> i32;
pub fn block_dim_x() -> i32;
pub fn block_dim_y() -> i32;
pub fn block_dim_z() -> i32;
pub fn grid_dim_x() -> i32;
pub fn grid_dim_y() -> i32;
pub fn grid_dim_z() -> i32;
pub fn syncthreads();
}
4 changes: 3 additions & 1 deletion src/librustc_back/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ supported_targets! {
("i586-pc-windows-msvc", i586_pc_windows_msvc),

("le32-unknown-nacl", le32_unknown_nacl),
("asmjs-unknown-emscripten", asmjs_unknown_emscripten)
("asmjs-unknown-emscripten", asmjs_unknown_emscripten),
("nvptx-unknown-unknown", nvptx_unknown_unknown),
("nvptx64-unknown-unknown", nvptx64_unknown_unknown)
}

/// Everything `rustc` knows about how to compile for a specific target.
Expand Down
36 changes: 36 additions & 0 deletions src/librustc_back/target/nvptx64_unknown_unknown.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::{Target, TargetOptions};

pub fn target() -> Target {
let opts = TargetOptions {
linker: "".to_string(),
ar: "".to_string(),

cpu: "sm_20".to_string(),
dynamic_linking: false,
executables: false,
no_compiler_rt: true,
allow_asm: false,
.. Default::default()
};
Target {
llvm_target: "nvptx64-unknown-unknown".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
target_os: "none".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
data_layout: "e-i64:64-v16:16-v32:32-n16:32:64".to_string(),
arch: "nvptx".to_string(),
options: opts,
}
}
36 changes: 36 additions & 0 deletions src/librustc_back/target/nvptx_unknown_unknown.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::{Target, TargetOptions};

pub fn target() -> Target {
let opts = TargetOptions {
linker: "".to_string(),
ar: "".to_string(),

cpu: "sm_20".to_string(),
dynamic_linking: false,
executables: false,
no_compiler_rt: true,
allow_asm: false,
.. Default::default()
};
Target {
llvm_target: "nvptx-unknown-unknown".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "32".to_string(),
target_os: "none".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
data_layout: "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64".to_string(),
arch: "nvptx".to_string(),
options: opts,
}
}
2 changes: 1 addition & 1 deletion src/librustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn main() {
let host = env::var("HOST").unwrap();
let is_crossed = target != host;

let optional_components = ["x86", "arm", "aarch64", "mips", "powerpc", "pnacl"];
let optional_components = ["x86", "arm", "aarch64", "mips", "powerpc", "pnacl", "nvptx"];

// FIXME: surely we don't need all these components, right? Stuff like mcjit
// or interpreter the compiler itself never uses.
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2407,6 +2407,11 @@ pub fn initialize_available_targets() {
LLVMInitializeMipsTargetMC,
LLVMInitializeMipsAsmPrinter,
LLVMInitializeMipsAsmParser);
init_target!(llvm_component = "nvptx",
LLVMInitializeNVPTXTargetInfo,
LLVMInitializeNVPTXTarget,
LLVMInitializeNVPTXTargetMC,
LLVMInitializeNVPTXAsmPrinter);
init_target!(llvm_component = "powerpc",
LLVMInitializePowerPCTargetInfo,
LLVMInitializePowerPCTarget,
Expand Down
13 changes: 13 additions & 0 deletions src/librustc_trans/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,19 @@ fn declare_intrinsic(ccx: &CrateContext, key: &str) -> Option<ValueRef> {
ifn!("llvm.localrecover", fn(i8p, i8p, t_i32) -> i8p);
ifn!("llvm.x86.seh.recoverfp", fn(i8p, i8p) -> i8p);

ifn!("llvm.cuda.syncthreads", fn() -> void);
ifn!("llvm.nvvm.read.ptx.sreg.tid.x", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.tid.y", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.tid.z", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.ctaid.x", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.ctaid.y", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.ctaid.z", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.ntid.x", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.ntid.y", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.ntid.z", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.nctaid.x", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.nctaid.y", fn() -> t_i32);
ifn!("llvm.nvvm.read.ptx.sreg.nctaid.z", fn() -> t_i32);
ifn!("llvm.assume", fn(i1) -> void);

if ccx.sess().opts.debuginfo != NoDebugInfo {
Expand Down
13 changes: 13 additions & 0 deletions src/librustc_trans/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option<ValueRef> {
"roundf32" => "llvm.round.f32",
"roundf64" => "llvm.round.f64",
"assume" => "llvm.assume",
"thread_idx_x" => "llvm.nvvm.read.ptx.sreg.tid.x",
"thread_idx_y" => "llvm.nvvm.read.ptx.sreg.tid.y",
"thread_idx_z" => "llvm.nvvm.read.ptx.sreg.tid.z",
"block_idx_x" => "llvm.nvvm.read.ptx.sreg.ctaid.x",
"block_idx_y" => "llvm.nvvm.read.ptx.sreg.ctaid.y",
"block_idx_z" => "llvm.nvvm.read.ptx.sreg.ctaid.z",
"block_dim_x" => "llvm.nvvm.read.ptx.sreg.ntid.x",
"block_dim_y" => "llvm.nvvm.read.ptx.sreg.ntid.y",
"block_dim_z" => "llvm.nvvm.read.ptx.sreg.ntid.z",
"grid_dim_x" => "llvm.nvvm.read.ptx.sreg.nctaid.x",
"grid_dim_y" => "llvm.nvvm.read.ptx.sreg.nctaid.y",
"grid_dim_z" => "llvm.nvvm.read.ptx.sreg.nctaid.z",
"syncthreads" => "llvm.cuda.syncthreads",
_ => return None
};
Some(ccx.get_intrinsic(&llvm_name))
Expand Down
9 changes: 9 additions & 0 deletions src/librustc_typeck/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,15 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) {
(0, vec![tcx.mk_fn_ptr(fn_ty), mut_u8, mut_u8], tcx.types.i32)
}

"thread_idx_x" | "thread_idx_y" | "thread_idx_z" |
"block_idx_x" | "block_idx_y" | "block_idx_z" |
"block_dim_x" | "block_dim_y" | "block_dim_z" |
"grid_dim_x" | "grid_dim_y" | "grid_dim_z" => {
(0, vec![], tcx.types.i32)
}

"syncthreads" => (0, vec![], tcx.mk_nil()),

ref other => {
span_err!(tcx.sess, it.span, E0093,
"unrecognized intrinsic function: `{}`", *other);
Expand Down