Skip to content

Commit 445fcfb

Browse files
fix merge
2 parents 8ffd1ac + 9443c12 commit 445fcfb

File tree

15 files changed

+233
-123
lines changed

15 files changed

+233
-123
lines changed

crates/find_cuda_helper/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,24 @@ pub fn find_optix_root() -> Option<PathBuf> {
135135
.or_else(|| env::var("OPTIX_ROOT_DIR").ok())
136136
.map(PathBuf::from)
137137
}
138+
139+
#[cfg(target_os = "windows")]
140+
pub fn find_libnvvm_bin_dir() -> String {
141+
find_cuda_root()
142+
.expect("Failed to find CUDA ROOT, make sure the CUDA SDK is installed and CUDA_PATH or CUDA_ROOT are set!")
143+
.join("nvvm")
144+
.join("lib")
145+
.join("x64")
146+
.to_string_lossy()
147+
.into_owned()
148+
}
149+
150+
#[cfg(target_os = "linux")]
151+
pub fn find_libnvvm_bin_dir() -> String {
152+
find_cuda_root()
153+
.expect("Failed to find CUDA ROOT, make sure the CUDA SDK is installed and CUDA_PATH or CUDA_ROOT are set!")
154+
.join("nvvm")
155+
.join("lib64")
156+
.to_string_lossy()
157+
.into_owned()
158+
}

crates/nvvm/build.rs

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,6 @@
1-
use find_cuda_helper::find_cuda_root;
2-
3-
#[cfg(target_os = "windows")]
4-
fn lib_search_path() -> String {
5-
find_cuda_root()
6-
.expect("Failed to find CUDA ROOT, make sure the CUDA SDK is installed and CUDA_PATH or CUDA_ROOT are set!")
7-
.join("nvvm")
8-
.join("lib")
9-
.join("x64")
10-
.to_string_lossy()
11-
.into_owned()
12-
}
13-
14-
#[cfg(target_os = "linux")]
15-
fn lib_search_path() -> String {
16-
format!("{}/nvvm/lib64", std::env::var("CUDA_ROOT").unwrap())
17-
}
18-
19-
fn libnvvm_build() {
20-
println!("cargo:rustc-link-search={}", lib_search_path());
21-
println!("cargo:rustc-link-lib=dylib=nvvm");
22-
}
1+
use find_cuda_helper::find_libnvvm_bin_dir;
232

243
fn main() {
25-
libnvvm_build()
4+
println!("cargo:rustc-link-search={}", find_libnvvm_bin_dir());
5+
println!("cargo:rustc-link-lib=dylib=nvvm");
266
}

crates/optix_sys/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ fn main() {
1212
"Unable to find the OptiX SDK, make sure you installed it and
1313
that OPTIX_ROOT or OPTIX_ROOT_DIR are set",
1414
);
15+
1516
optix_include = optix_include.join("include");
1617

1718
let mut cuda_include = find_cuda_root().expect(

crates/rustc_codegen_nvvm/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ rustc_codegen_nvvm_macros = { version = "0.1", path = "../rustc_codegen_nvvm_mac
2323
[build-dependencies]
2424
build-helper = "0.1.1"
2525
cc = { version = "1.0", features = ["parallel"] }
26+
xz = "0.1.0"
27+
tar = "0.4.37"
28+
curl = "0.4.40"
2629

2730
[package.metadata.rust-analyzer]
2831
rustc_private = true

crates/rustc_codegen_nvvm/build.rs

Lines changed: 97 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ use std::{
66
process::{Command, Stdio},
77
};
88

9+
use curl::easy::Easy;
10+
use tar::Archive;
11+
use xz::read::XzDecoder;
12+
13+
static PREBUILT_LLVM_URL: &str =
14+
"https://github.com/RDambrosio016/rustc_codegen_nvvm-llvm/releases/download/LLVM-7.1.0/";
15+
16+
static REQUIRED_MAJOR_LLVM_VERSION: u8 = 7;
17+
918
fn main() {
1019
rustc_llvm_build();
1120

@@ -40,6 +49,74 @@ pub fn output(cmd: &mut Command) -> String {
4049
String::from_utf8(output.stdout).unwrap()
4150
}
4251

52+
fn target_to_llvm_prebuilt(target: &str) -> String {
53+
let base = match target {
54+
"x86_64-pc-windows-msvc" => "windows-x86_64",
55+
"x86_64-unknown-linux-gnu" => "linux-x86_64",
56+
_ => panic!("Unsupported target with no matching prebuilt LLVM: `{}`, install LLVM and set LLVM_CONFIG", target)
57+
};
58+
format!("{}.tar.xz", base)
59+
}
60+
61+
fn find_llvm_config(target: &str) -> PathBuf {
62+
// first, if LLVM_CONFIG is set then see if its llvm version if 7.x, if so, use that.
63+
let config_env = tracked_env_var_os("LLVM_CONFIG");
64+
// if LLVM_CONFIG is not set, try using llvm-config as a normal app in PATH.
65+
let path_to_try = config_env.unwrap_or_else(|| "llvm-config".into());
66+
67+
// if USE_PREBUILT_LLVM is set to 1 then download prebuilt llvm without trying llvm-config
68+
if tracked_env_var_os("USE_PREBUILT_LLVM") != Some("1".into()) {
69+
let cmd = Command::new(&path_to_try).arg("--version").output();
70+
71+
if let Ok(out) = cmd {
72+
let version = String::from_utf8(out.stdout).unwrap();
73+
if version.starts_with(&REQUIRED_MAJOR_LLVM_VERSION.to_string()) {
74+
return PathBuf::from(path_to_try);
75+
}
76+
}
77+
}
78+
79+
// otherwise, download prebuilt LLVM.
80+
println!("cargo:warning=LLVM not found, downloading prebuilt LLVM");
81+
let mut url = tracked_env_var_os("PREBUILT_LLVM_URL")
82+
.map(|x| x.to_string_lossy().to_string())
83+
.unwrap_or_else(|| PREBUILT_LLVM_URL.to_string());
84+
85+
let prebuilt_name = target_to_llvm_prebuilt(target);
86+
url = format!("{}{}", url, prebuilt_name);
87+
88+
let out = env::var("OUT_DIR").expect("OUT_DIR was not set");
89+
let mut easy = Easy::new();
90+
91+
easy.url(&url).unwrap();
92+
let _redirect = easy.follow_location(true).unwrap();
93+
let mut xz_encoded = Vec::with_capacity(20_000_000); // 20mb
94+
{
95+
let mut transfer = easy.transfer();
96+
transfer
97+
.write_function(|data| {
98+
xz_encoded.extend_from_slice(data);
99+
Ok(data.len())
100+
})
101+
.expect("Failed to download prebuilt LLVM");
102+
transfer
103+
.perform()
104+
.expect("Failed to download prebuilt LLVM");
105+
}
106+
107+
let decompressor = XzDecoder::new(xz_encoded.as_slice());
108+
let mut ar = Archive::new(decompressor);
109+
110+
ar.unpack(&out).expect("Failed to unpack LLVM to LLVM dir");
111+
let out_path = PathBuf::from(out).join(prebuilt_name.strip_suffix(".tar.xz").unwrap());
112+
113+
println!("cargo:rerun-if-changed={}", out_path.display());
114+
115+
out_path
116+
.join("bin")
117+
.join(format!("llvm-config{}", std::env::consts::EXE_SUFFIX))
118+
}
119+
43120
fn detect_llvm_link() -> (&'static str, &'static str) {
44121
// Force the link mode we want, preferring static by default, but
45122
// possibly overridden by `configure --enable-llvm-link-shared`.
@@ -57,62 +134,13 @@ pub fn tracked_env_var_os<K: AsRef<OsStr> + Display>(key: K) -> Option<OsString>
57134

58135
fn rustc_llvm_build() {
59136
let target = env::var("TARGET").expect("TARGET was not set");
60-
let llvm_config = tracked_env_var_os("LLVM_CONFIG")
61-
.map(|x| Some(PathBuf::from(x)))
62-
.unwrap_or_else(|| {
63-
if let Some(dir) = tracked_env_var_os("CARGO_TARGET_DIR").map(PathBuf::from) {
64-
let to_test = dir
65-
.parent()
66-
.unwrap()
67-
.parent()
68-
.unwrap()
69-
.join(&target)
70-
.join("llvm/bin/llvm-config");
71-
if Command::new(&to_test).output().is_ok() {
72-
return Some(to_test);
73-
}
74-
}
75-
None
76-
});
137+
let llvm_config = find_llvm_config(&target);
77138

78-
if let Some(llvm_config) = &llvm_config {
79-
println!("cargo:rerun-if-changed={}", llvm_config.display());
80-
}
81-
let llvm_config = llvm_config.unwrap_or_else(|| PathBuf::from("llvm-config"));
82-
83-
let optional_components = &[
84-
"x86",
85-
"arm",
86-
"aarch64",
87-
"amdgpu",
88-
"avr",
89-
"mips",
90-
"powerpc",
91-
"systemz",
92-
"jsbackend",
93-
"webassembly",
94-
"msp430",
95-
"sparc",
96-
"nvptx",
97-
"hexagon",
98-
"riscv",
99-
"bpf",
100-
];
101-
102-
let required_components = &[
103-
"ipo",
104-
"bitreader",
105-
"bitwriter",
106-
"linker",
107-
"asmparser",
108-
"lto",
109-
"coverage",
110-
"instrumentation",
111-
];
139+
let required_components = &["ipo", "bitreader", "bitwriter", "lto", "nvptx"];
112140

113141
let components = output(Command::new(&llvm_config).arg("--components"));
114142
let mut components = components.split_whitespace().collect::<Vec<_>>();
115-
components.retain(|c| optional_components.contains(c) || required_components.contains(c));
143+
components.retain(|c| required_components.contains(c));
116144

117145
for component in required_components {
118146
if !components.contains(component) {
@@ -134,6 +162,16 @@ fn rustc_llvm_build() {
134162
if flag.starts_with("-flto") {
135163
continue;
136164
}
165+
// ignore flags that aren't supported in gcc 8
166+
if flag == "-Wcovered-switch-default" {
167+
continue;
168+
}
169+
if flag == "-Wstring-conversion" {
170+
continue;
171+
}
172+
if flag == "-Werror=unguarded-availability-new" {
173+
continue;
174+
}
137175

138176
cfg.flag(flag);
139177
}
@@ -151,7 +189,7 @@ fn rustc_llvm_build() {
151189
build_helper::rerun_if_changed(Path::new("rustc_llvm_wrapper"));
152190
cfg.file("rustc_llvm_wrapper/RustWrapper.cpp")
153191
.file("rustc_llvm_wrapper/PassWrapper.cpp")
154-
.include("rustc_llvm_wrapper/rustllvm.h")
192+
.include("rustc_llvm_wrapper")
155193
.cpp(true)
156194
.cpp_link_stdlib(None) // we handle this below
157195
.compile("llvm-wrapper");
@@ -209,7 +247,7 @@ fn rustc_llvm_build() {
209247

210248
// Link in the system libraries that LLVM depends on
211249
#[cfg(not(target_os = "windows"))]
212-
link_llvm_system_libs(&llvm_config);
250+
link_llvm_system_libs(&llvm_config, required_components);
213251

214252
// LLVM ldflags
215253
//
@@ -298,10 +336,14 @@ fn rustc_llvm_build() {
298336
}
299337

300338
#[cfg(not(target_os = "windows"))]
301-
fn link_llvm_system_libs(llvm_config: &Path) {
339+
fn link_llvm_system_libs(llvm_config: &Path, components: &[&str]) {
302340
let mut cmd = Command::new(&llvm_config);
303341
cmd.arg("--system-libs");
304342

343+
for comp in components {
344+
cmd.arg(comp);
345+
}
346+
305347
for lib in output(&mut cmd).split_whitespace() {
306348
let name = if let Some(stripped) = lib.strip_prefix("-l") {
307349
stripped

crates/rustc_codegen_nvvm/rustc_llvm_wrapper/RustWrapper.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,22 @@ extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
187187
}
188188

189189
extern "C" LLVMValueRef
190-
LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty)
191-
{
190+
LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty, unsigned AddressSpace)
191+
{
192+
// Module *Mod = unwrap(M);
193+
// GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(Mod->getNamedValue(Name));
194+
// if (!GV)
195+
// {
196+
// GV = new GlobalVariable(unwrap(Ty), false, GlobalValue::ExternalLinkage,
197+
// nullptr, Name, GlobalValue::NotThreadLocal, AddressSpace);
198+
// }
199+
// Type *GVTy = GV->getType();
200+
// PointerType *PTy = PointerType::get(unwrap(Ty), GVTy->getPointerAddressSpace());
201+
// if (GVTy != PTy)
202+
// return wrap(ConstantExpr::getBitCast(GV, PTy));
203+
192204
return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
205+
// return wrap(GV);
193206
}
194207

195208
extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C)

crates/rustc_codegen_nvvm/src/abi.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_codegen_ssa::{traits::*, MemFlags};
1111
use rustc_middle::bug;
1212
use rustc_middle::ty::layout::LayoutOf;
1313
pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
14-
use rustc_middle::ty::{Ty, TyCtxt};
14+
use rustc_middle::ty::{Ty, TyCtxt, TyKind};
1515
pub use rustc_target::abi::call::*;
1616
use rustc_target::abi::call::{CastTarget, Reg, RegKind};
1717
use rustc_target::abi::{self, HasDataLayout, Int};
@@ -27,20 +27,27 @@ pub(crate) fn readjust_fn_abi<'tcx>(
2727
return fn_abi;
2828
}
2929
let readjust_arg_abi = |arg: &ArgAbi<'tcx, Ty<'tcx>>| {
30-
let mut arg = ArgAbi::new(&tcx, arg.layout, |_, _, _| ArgAttributes::new());
30+
let mut arg = ArgAbi {
31+
layout: arg.layout,
32+
mode: arg.mode,
33+
pad: arg.pad,
34+
};
3135

3236
// ignore zsts
3337
if arg.layout.is_zst() {
3438
arg.mode = PassMode::Ignore;
3539
}
3640

37-
// this should never happen since rustc has always passed slices as pairs for years but we override it just to make sure.
38-
// if rustc suddenly changes this we are in for a world of segfaults so if you are a rustc dev reading this, please dont, thanks :)
39-
if arg.layout.ty.is_slice() && !matches!(arg.mode, PassMode::Pair { .. }) {
40-
arg.mode = PassMode::Pair(ArgAttributes::new(), ArgAttributes::new());
41+
if let TyKind::Ref(_, ty, _) = arg.layout.ty.kind() {
42+
if matches!(ty.kind(), TyKind::Slice(_)) {
43+
let mut ptr_attrs = ArgAttributes::new();
44+
if let PassMode::Indirect { attrs, .. } = arg.mode {
45+
ptr_attrs.regular = attrs.regular;
46+
}
47+
arg.mode = PassMode::Pair(ptr_attrs, ArgAttributes::new());
48+
}
4149
}
4250

43-
// same as in slice's case
4451
if arg.layout.ty.is_array() && !matches!(arg.mode, PassMode::Direct { .. }) {
4552
arg.mode = PassMode::Direct(ArgAttributes::new());
4653
}

0 commit comments

Comments
 (0)