Skip to content

Commit d51fa91

Browse files
Add Polly support. Use can be triggered via -Z polly, when rustc uses an LLVM which includes polly.
Force LLVM rebuild on buildbots.
1 parent e7f5d48 commit d51fa91

File tree

17 files changed

+170
-15
lines changed

17 files changed

+170
-15
lines changed

.gitmodules

+4-1
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,7 @@
6464
path = src/tools/clang
6565
url = https://github.com/rust-lang-nursery/clang.git
6666
branch = rust-release-80-v1
67-
67+
[submodule "src/polly"]
68+
path = src/polly
69+
url = https://github.com/llvm-mirror/polly.git
70+
branch = master

config.toml.example

+8
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@
337337
#optimize-tests = true
338338
#debuginfo-tests = true
339339

340+
# Flag indicating whether tests are optimized with Polly. If optimize-tests is false,
341+
# polly-tests will be false regardless of its value here.
342+
#polly-tests = false
343+
340344
# Flag indicating whether codegen tests will be run or not. If you get an error
341345
# saying that the FileCheck executable is missing, you may want to disable this.
342346
# Also see the target's llvm-filecheck option.
@@ -395,6 +399,10 @@
395399
# Whether to verify generated LLVM IR
396400
#verify-llvm-ir = false
397401

402+
# Use Polly on the rust compiler itself. If optimize is false, this will be
403+
# false as well.
404+
#polly-self = false
405+
398406
# Map all debuginfo paths for libstd and crates to `/rust/$sha/$crate/...`,
399407
# generally only set for releases
400408
#remap-debuginfo = false

src/bootstrap/bin/rustc.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ fn main() {
9191
("RUSTC_REAL", "RUSTC_LIBDIR")
9292
};
9393
let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
94+
let stage = usize::from_str(stage.as_str()).expect("RUSTC_STAGE not a usize");
9495
let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
9596
let on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of));
9697

@@ -159,7 +160,7 @@ fn main() {
159160
// workaround undefined references to `rust_eh_unwind_resume` generated
160161
// otherwise, see issue https://github.com/rust-lang/rust/issues/43095.
161162
if crate_name == "panic_abort" ||
162-
crate_name == "compiler_builtins" && stage != "0" {
163+
crate_name == "compiler_builtins" && stage != 0 {
163164
cmd.arg("-C").arg("panic=abort");
164165
}
165166

@@ -287,6 +288,14 @@ fn main() {
287288
cmd.arg("--cfg").arg("parallel_queries");
288289
}
289290

291+
let use_polly = match env::var("RUSTC_USE_POLLY") {
292+
Ok(v) => v != "0",
293+
Err(_) => false,
294+
};
295+
if use_polly && stage >= 1 {
296+
cmd.arg("-Z").arg("polly");
297+
}
298+
290299
if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none()
291300
{
292301
cmd.arg("-Dwarnings");

src/bootstrap/builder.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,18 @@ impl<'a> Builder<'a> {
11161116
cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1");
11171117
}
11181118

1119+
let use_polly = match cmd {
1120+
"test" | "bench" => {
1121+
self.config.rust_polly_tests
1122+
},
1123+
_ => self.config.rust_polly_self
1124+
};
1125+
if use_polly && stage > 1 {
1126+
cargo.env("RUSTC_USE_POLLY", "1");
1127+
} else {
1128+
cargo.env("RUSTC_USE_POLLY", "0");
1129+
}
1130+
11191131
for _ in 1..self.verbosity {
11201132
cargo.arg("-v");
11211133
}

src/bootstrap/config.rs

+16
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,14 @@ pub struct Config {
104104
pub rustc_parallel_queries: bool,
105105
pub rustc_default_linker: Option<String>,
106106
pub rust_optimize_tests: bool,
107+
pub rust_polly_tests: bool,
107108
pub rust_debuginfo_tests: bool,
108109
pub rust_dist_src: bool,
109110
pub rust_codegen_backends: Vec<Interned<String>>,
110111
pub rust_codegen_backends_dir: String,
111112
pub rust_verify_llvm_ir: bool,
112113
pub rust_remap_debuginfo: bool,
114+
pub rust_polly_self: bool,
113115

114116
pub build: Interned<String>,
115117
pub hosts: Vec<Interned<String>>,
@@ -309,6 +311,7 @@ struct Rust {
309311
rpath: Option<bool>,
310312
optimize_tests: Option<bool>,
311313
debuginfo_tests: Option<bool>,
314+
polly_tests: Option<bool>,
312315
codegen_tests: Option<bool>,
313316
ignore_git: Option<bool>,
314317
debug: Option<bool>,
@@ -327,6 +330,7 @@ struct Rust {
327330
backtrace_on_ice: Option<bool>,
328331
verify_llvm_ir: Option<bool>,
329332
remap_debuginfo: Option<bool>,
333+
polly_self: Option<bool>,
330334
}
331335

332336
/// TOML representation of how each build target is configured.
@@ -541,6 +545,10 @@ impl Config {
541545
ignore_git = rust.ignore_git;
542546
debug_jemalloc = rust.debug_jemalloc;
543547
set(&mut config.rust_optimize_tests, rust.optimize_tests);
548+
set(&mut config.rust_polly_tests, rust.polly_tests);
549+
if !config.rust_optimize_tests {
550+
config.rust_polly_tests = false;
551+
}
544552
set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests);
545553
set(&mut config.codegen_tests, rust.codegen_tests);
546554
set(&mut config.rust_rpath, rust.rpath);
@@ -580,6 +588,10 @@ impl Config {
580588
Some(n) => config.rust_codegen_units = Some(n),
581589
None => {}
582590
}
591+
592+
config.rust_polly_self = rust
593+
.polly_self
594+
.unwrap_or(false);
583595
}
584596

585597
if let Some(ref t) = toml.target {
@@ -644,6 +656,10 @@ impl Config {
644656
config.rust_debuginfo = debuginfo.unwrap_or(default);
645657
config.rust_debug_assertions = debug_assertions.unwrap_or(default);
646658

659+
if !config.rust_optimize {
660+
config.rust_polly_self = false;
661+
}
662+
647663
let default = config.channel == "dev";
648664
config.ignore_git = ignore_git.unwrap_or(default);
649665

src/bootstrap/native.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,17 @@ impl Step for Llvm {
148148
.define("LLVM_INCLUDE_DOCS", "OFF")
149149
.define("LLVM_INCLUDE_BENCHMARKS", "OFF")
150150
.define("LLVM_ENABLE_ZLIB", "OFF")
151-
.define("WITH_POLLY", "OFF")
152151
.define("LLVM_ENABLE_TERMINFO", "OFF")
153152
.define("LLVM_ENABLE_LIBEDIT", "OFF")
154153
.define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string())
155154
.define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
156155
.define("LLVM_DEFAULT_TARGET_TRIPLE", target);
157156

157+
if !self.emscripten {
158+
let polly_src = builder.src.join("src/polly");
159+
cfg.define("LLVM_EXTERNAL_POLLY_SOURCE_DIR", polly_src);
160+
}
161+
158162
if builder.config.llvm_thin_lto && !emscripten {
159163
cfg.define("LLVM_ENABLE_LTO", "Thin")
160164
.define("LLVM_ENABLE_LLD", "ON");

src/bootstrap/test.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,9 @@ impl Step for Compiletest {
10451045
}
10461046
flags.push("-Zunstable-options".to_string());
10471047
flags.push(builder.config.cmd.rustc_args().join(" "));
1048+
if builder.config.rust_polly_self {
1049+
flags.push("-Zpolly".into());
1050+
}
10481051

10491052
if let Some(linker) = builder.linker(target) {
10501053
cmd.arg("--linker").arg(linker);

src/ci/docker/dist-i686-linux/Dockerfile

+4
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ RUN ./build-headers.sh
8686
COPY scripts/sccache.sh /scripts/
8787
RUN sh /scripts/sccache.sh
8888

89+
# Polly needs `PATH_MAX`
90+
ENV CFLAGS="-DPATH_MAX=4096 ${CFLAGS}"
91+
ENV CXXFLAGS="-DPATH_MAX=4096 ${CXXFLAGS}"
92+
8993
ENV HOSTS=i686-unknown-linux-gnu
9094

9195
ENV RUST_CONFIGURE_ARGS \

src/ci/docker/dist-x86_64-linux/Dockerfile

+4
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ RUN ./build-headers.sh
8686
COPY scripts/sccache.sh /scripts/
8787
RUN sh /scripts/sccache.sh
8888

89+
# Polly needs `PATH_MAX`
90+
ENV CFLAGS="-DPATH_MAX=4096 ${CFLAGS}"
91+
ENV CXXFLAGS="-DPATH_MAX=4096 ${CXXFLAGS}"
92+
8993
ENV HOSTS=x86_64-unknown-linux-gnu
9094

9195
ENV RUST_CONFIGURE_ARGS \

src/librustc/session/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
13821382
"run the self profiler"),
13831383
profile_json: bool = (false, parse_bool, [UNTRACKED],
13841384
"output a json file with profiler results"),
1385+
polly: bool = (false, parse_bool, [UNTRACKED], "Run the Polly polyhedral \
1386+
model optimization passes."),
13851387
emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
13861388
"emits a section containing stack size metadata"),
13871389
plt: Option<bool> = (None, parse_opt_bool, [TRACKED],

src/librustc_codegen_llvm/back/lto.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ fn run_pass_manager(cgcx: &CodegenContext,
569569
debug!("running the pass manager");
570570
unsafe {
571571
let pm = llvm::LLVMCreatePassManager();
572-
llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod);
572+
llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod, config.polly);
573573

574574
if config.verify_llvm_ir {
575575
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);

src/librustc_codegen_llvm/back/write.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ pub struct ModuleConfig {
265265
no_integrated_as: bool,
266266
embed_bitcode: bool,
267267
embed_bitcode_marker: bool,
268+
pub polly: bool,
268269
}
269270

270271
impl ModuleConfig {
@@ -297,7 +298,8 @@ impl ModuleConfig {
297298
vectorize_loop: false,
298299
vectorize_slp: false,
299300
merge_functions: false,
300-
inline_threshold: None
301+
inline_threshold: None,
302+
polly: false,
301303
}
302304
}
303305

@@ -336,6 +338,8 @@ impl ModuleConfig {
336338

337339
self.merge_functions = sess.opts.optimize == config::OptLevel::Default ||
338340
sess.opts.optimize == config::OptLevel::Aggressive;
341+
self.polly = sess.opts.debugging_opts.polly && !self.no_prepopulate_passes &&
342+
!sess.target.target.options.is_like_emscripten;
339343
}
340344
}
341345

@@ -568,8 +572,8 @@ unsafe fn optimize(cgcx: &CodegenContext,
568572
|| config.obj_is_bitcode || config.emit_bc_compressed || config.embed_bitcode);
569573
let mut have_name_anon_globals_pass = false;
570574
if !config.no_prepopulate_passes {
571-
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
572-
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
575+
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod, config.polly);
576+
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod, config.polly);
573577
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
574578
let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal ||
575579
(cgcx.lto != Lto::Fat && cgcx.opts.debugging_opts.cross_lang_lto.enabled());
@@ -702,11 +706,12 @@ unsafe fn codegen(cgcx: &CodegenContext,
702706
unsafe fn with_codegen<'ll, F, R>(tm: &'ll llvm::TargetMachine,
703707
llmod: &'ll llvm::Module,
704708
no_builtins: bool,
709+
polly: bool,
705710
f: F) -> R
706711
where F: FnOnce(&'ll mut PassManager<'ll>) -> R,
707712
{
708713
let cpm = llvm::LLVMCreatePassManager();
709-
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
714+
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod, polly);
710715
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
711716
f(cpm)
712717
}
@@ -801,7 +806,8 @@ unsafe fn codegen(cgcx: &CodegenContext,
801806
cursor.position() as size_t
802807
}
803808

804-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
809+
with_codegen(tm, llmod, config.no_builtins, config.polly,
810+
|cpm| {
805811
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback);
806812
llvm::LLVMDisposePassManager(cpm);
807813
});
@@ -819,15 +825,17 @@ unsafe fn codegen(cgcx: &CodegenContext,
819825
} else {
820826
llmod
821827
};
822-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
828+
with_codegen(tm, llmod, config.no_builtins, config.polly,
829+
|cpm| {
823830
write_output_file(diag_handler, tm, cpm, llmod, &path,
824831
llvm::FileType::AssemblyFile)
825832
})?;
826833
timeline.record("asm");
827834
}
828835

829836
if write_obj {
830-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
837+
with_codegen(tm, llmod, config.no_builtins, config.polly,
838+
|cpm| {
831839
write_output_file(diag_handler, tm, cpm, llmod, &obj_out,
832840
llvm::FileType::ObjectFile)
833841
})?;
@@ -2221,7 +2229,8 @@ pub unsafe fn with_llvm_pmb(llmod: &llvm::Module,
22212229
llvm::LLVMPassManagerBuilderSetDisableUnrollLoops(builder, 1);
22222230
}
22232231

2224-
llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, config.no_builtins);
2232+
llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, config.no_builtins,
2233+
config.polly);
22252234

22262235
// Here we match what clang does (kinda). For O0 we only inline
22272236
// always-inline functions (but don't add lifetime intrinsics), at O1 we

src/librustc_codegen_llvm/llvm/ffi.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1470,10 +1470,12 @@ extern "C" {
14701470
EmitStackSizeSection: bool)
14711471
-> Option<&'static mut TargetMachine>;
14721472
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
1473-
pub fn LLVMRustAddAnalysisPasses(T: &'a TargetMachine, PM: &PassManager<'a>, M: &'a Module);
1473+
pub fn LLVMRustAddAnalysisPasses(T: &'a TargetMachine, PM: &PassManager<'a>, M: &'a Module,
1474+
Polly: bool);
14741475
pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder,
14751476
M: &'a Module,
1476-
DisableSimplifyLibCalls: bool);
1477+
DisableSimplifyLibCalls: bool,
1478+
Polly: bool);
14771479
pub fn LLVMRustConfigurePassManagerBuilder(PMB: &PassManagerBuilder,
14781480
OptLevel: CodeGenOptLevel,
14791481
MergeFunctions: bool,

src/librustc_llvm/build.rs

+57
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,54 @@ fn main() {
161161
cfg.define("LLVM_RUSTLLVM", None);
162162
}
163163

164+
let (enable_polly, polly_link_kind, polly_link_isl) = {
165+
let mut cmd = Command::new(&llvm_config);
166+
cmd.arg("--libdir");
167+
let libdir = output(&mut cmd);
168+
let libdir = libdir.lines().next().unwrap();
169+
let libdir = Path::new(&libdir);
170+
assert!(libdir.exists());
171+
172+
// We can't specify the full libname to rust, so the linker will always expect (on unix)
173+
// LLVMPolly to be libLLVMPolly, which won't be present. I didn't realize this fact until
174+
// after I wrote the following, but maybe this issue will be resolved in the future.
175+
let allow_shared = false;
176+
let mut found_static = false;
177+
let mut found_shared = false;
178+
for entry in libdir.read_dir().unwrap() {
179+
if let Ok(entry) = entry {
180+
if let Some(name) = entry.path().file_name() {
181+
let name = name.to_str().unwrap();
182+
if name.contains("Polly") {
183+
if !found_static {
184+
found_static = !name.contains("LLVM");
185+
}
186+
if !found_shared {
187+
found_shared = name.contains("LLVM");
188+
}
189+
}
190+
}
191+
}
192+
}
193+
194+
let found_static = found_static;
195+
let found_shared = allow_shared && found_shared;
196+
let enabled = !cfg!(feature = "emscripten") &&
197+
(found_static || found_shared);
198+
let (kind, isl) = match (found_static, found_shared) {
199+
(false, false) => ("", false),
200+
(true, _) => ("static", true),
201+
(false, true) => ("dylib", false),
202+
};
203+
(enabled, kind, isl)
204+
};
205+
164206
build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm"));
165207
cfg.file("../rustllvm/PassWrapper.cpp")
166208
.file("../rustllvm/RustWrapper.cpp")
167209
.file("../rustllvm/ArchiveWrapper.cpp")
168210
.file("../rustllvm/Linker.cpp")
211+
.define("ENABLE_POLLY", if enable_polly { "1" } else { "0" })
169212
.cpp(true)
170213
.cpp_link_stdlib(None) // we handle this below
171214
.compile("rustllvm");
@@ -218,6 +261,20 @@ fn main() {
218261
println!("cargo:rustc-link-lib={}={}", kind, name);
219262
}
220263

264+
if enable_polly {
265+
match polly_link_kind {
266+
"dylib" => {
267+
panic!("dynamically linking polly is not possible :(");
268+
//println!("cargo:rustc-flags=-l:LLVMPolly")
269+
},
270+
_ => println!("cargo:rustc-link-lib={}=Polly", polly_link_kind),
271+
}
272+
273+
if polly_link_isl {
274+
println!("cargo:rustc-link-lib={}=PollyISL", polly_link_kind);
275+
}
276+
}
277+
221278
// LLVM ldflags
222279
//
223280
// If we're a cross-compile of LLVM then unfortunately we can't trust these

0 commit comments

Comments
 (0)