Skip to content

Commit

Permalink
Add Polly support. Use can be triggered via -Z polly, when rustc
Browse files Browse the repository at this point in the history
…uses an LLVM which includes polly.

Force LLVM rebuild on buildbots.
  • Loading branch information
DiamondLovesYou committed May 2, 2018
1 parent 5a662bf commit 4bcf25a
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 13 deletions.
8 changes: 8 additions & 0 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,10 @@
#optimize-tests = true
#debuginfo-tests = true

# Flag indicating whether tests are optimized with Polly. If optimize-tests is false,
# polly-tests will be false regardless of its value here.
#polly-tests = false

# Flag indicating whether codegen tests will be run or not. If you get an error
# saying that the FileCheck executable is missing, you may want to disable this.
#codegen-tests = true
Expand Down Expand Up @@ -346,6 +350,10 @@
# Whether to deny warnings in crates
#deny-warnings = true

# Use Polly on the rust compiler itself. If optimize is false, this will be
# false as well.
#polly-self = false

# =============================================================================
# Options for specific targets
#
Expand Down
11 changes: 10 additions & 1 deletion src/bootstrap/bin/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ fn main() {
("RUSTC_REAL", "RUSTC_LIBDIR")
};
let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
let stage = usize::from_str(stage.as_str()).expect("RUSTC_STAGE not a usize");
let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
let on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of));

Expand Down Expand Up @@ -152,7 +153,7 @@ fn main() {
// workaround undefined references to `rust_eh_unwind_resume` generated
// otherwise, see issue https://github.com/rust-lang/rust/issues/43095.
if crate_name == "panic_abort" ||
crate_name == "compiler_builtins" && stage != "0" {
crate_name == "compiler_builtins" && stage != 0 {
cmd.arg("-C").arg("panic=abort");
}

Expand Down Expand Up @@ -267,6 +268,14 @@ fn main() {
cmd.arg("--cfg").arg("parallel_queries");
}

let use_polly = match env::var("RUSTC_USE_POLLY") {
Ok(v) => v != "0",
Err(_) => false,
};
if use_polly && stage >= 1 {
cmd.arg("-Z").arg("polly");
}

let color = match env::var("RUSTC_COLOR") {
Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"),
Err(_) => 0,
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,10 @@ def update_submodules(self):
recorded_submodules[data[3]] = data[2]
for module in filtered_submodules:
self.update_submodule(module[0], module[1], recorded_submodules)
polly_path = "src/llvm/tools/polly"
if not os.path.exists(os.path.join(self.rust_root, polly_path)):
run(["git", "clone", "https://github.com/llvm-mirror/polly.git",
"src/llvm/tools/polly", "-b", "release_60"])
print("Submodules updated in %.2f seconds" % (time() - start_time))

def set_dev_environment(self):
Expand Down
14 changes: 13 additions & 1 deletion src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use native;
use tool;

use cache::{INTERNER, Interned};
use builder::{Step, RunConfig, ShouldRun, Builder};
use builder::{Step, RunConfig, ShouldRun, Builder, Kind};

#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Std {
Expand Down Expand Up @@ -553,6 +553,18 @@ pub fn rustc_cargo_env(builder: &Builder, cargo: &mut Command) {
if builder.config.rustc_parallel_queries {
cargo.env("RUSTC_PARALLEL_QUERIES", "1");
}

let use_polly = match builder.kind {
Kind::Test | Kind::Check => {
builder.config.rust_polly_tests
},
_ => builder.config.rust_polly_self
};
if use_polly {
cargo.env("RUSTC_USE_POLLY", "1");
} else {
cargo.env("RUSTC_USE_POLLY", "0");
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
Expand Down
16 changes: 16 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,12 @@ pub struct Config {
pub rustc_parallel_queries: bool,
pub rustc_default_linker: Option<String>,
pub rust_optimize_tests: bool,
pub rust_polly_tests: bool,
pub rust_debuginfo_tests: bool,
pub rust_dist_src: bool,
pub rust_codegen_backends: Vec<Interned<String>>,
pub rust_codegen_backends_dir: String,
pub rust_polly_self: bool,

pub build: Interned<String>,
pub hosts: Vec<Interned<String>>,
Expand Down Expand Up @@ -294,6 +296,7 @@ struct Rust {
rpath: Option<bool>,
optimize_tests: Option<bool>,
debuginfo_tests: Option<bool>,
polly_tests: Option<bool>,
codegen_tests: Option<bool>,
ignore_git: Option<bool>,
debug: Option<bool>,
Expand All @@ -306,6 +309,7 @@ struct Rust {
wasm_syscall: Option<bool>,
lld: Option<bool>,
deny_warnings: Option<bool>,
polly_self: Option<bool>,
}

/// TOML representation of how each build target is configured.
Expand Down Expand Up @@ -515,6 +519,10 @@ impl Config {
ignore_git = rust.ignore_git;
debug_jemalloc = rust.debug_jemalloc;
set(&mut config.rust_optimize_tests, rust.optimize_tests);
set(&mut config.rust_polly_tests, rust.polly_tests);
if !config.rust_optimize_tests {
config.rust_polly_tests = false;
}
set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests);
set(&mut config.codegen_tests, rust.codegen_tests);
set(&mut config.rust_rpath, rust.rpath);
Expand Down Expand Up @@ -545,6 +553,10 @@ impl Config {
Some(n) => config.rust_codegen_units = Some(n),
None => {}
}

config.rust_polly_self = rust
.polly_self
.unwrap_or(false);
}

if let Some(ref t) = toml.target {
Expand Down Expand Up @@ -602,6 +614,10 @@ impl Config {
config.rust_debug_assertions = debug_assertions.unwrap_or(default);
config.rust_optimize = optimize.unwrap_or(!default);

if !config.rust_optimize {
config.rust_polly_self = false;
}

let default = config.channel == "dev";
config.ignore_git = ignore_git.unwrap_or(default);

Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,9 @@ impl Step for Compiletest {
}
flags.push("-Zunstable-options".to_string());
flags.push(builder.config.cmd.rustc_args().join(" "));
if builder.config.rust_polly_self {
flags.push("-Zpolly".into());
}

if let Some(linker) = builder.linker(target) {
cmd.arg("--linker").arg(linker);
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"make the current crate share its generic instantiations"),
chalk: bool = (false, parse_bool, [TRACKED],
"enable the experimental Chalk-based trait solving engine"),
polly: bool = (false, parse_bool, [UNTRACKED], "Run the Polly polyhedral \
model optimization passes."),
}

pub fn default_lib_output() -> CrateType {
Expand Down
56 changes: 56 additions & 0 deletions src/librustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,53 @@ fn main() {
cfg.define("LLVM_RUSTLLVM", None);
}

let (enable_polly, polly_link_kind, polly_link_isl) = {
let mut cmd = Command::new(&llvm_config);
cmd.arg("--libdir");
let libdir = output(&mut cmd);
let libdir = libdir.lines().next().unwrap();
let libdir = Path::new(&libdir);
assert!(libdir.exists());

// We can't specify the full libname to rust, so the linker will always expect (on unix)
// LLVMPolly to be libLLVMPolly, which won't be present. I didn't realize this fact until
// after I wrote the following, but maybe this issue will be resolved in the future.
let allow_shared = false;
let mut found_static = false;
let mut found_shared = false;
for entry in libdir.read_dir().unwrap() {
if let Ok(entry) = entry {
if let Some(name) = entry.path().file_name() {
let name = name.to_str().unwrap();
if name.contains("Polly") {
if !found_static {
found_static = !name.contains("LLVM");
}
if !found_shared {
found_shared = name.contains("LLVM");
}
}
}
}
}

let found_static = found_static;
let found_shared = allow_shared && found_shared;
let enabled = found_static || found_shared;
let (kind, isl) = match (found_static, found_shared) {
(false, false) => ("", false),
(true, _) => ("static", true),
(false, true) => ("dylib", false),
};
(enabled, kind, isl)
};

build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm"));
cfg.file("../rustllvm/PassWrapper.cpp")
.file("../rustllvm/RustWrapper.cpp")
.file("../rustllvm/ArchiveWrapper.cpp")
.file("../rustllvm/Linker.cpp")
.define("ENABLE_POLLY", if enable_polly { "1" } else { "0" })
.cpp(true)
.cpp_link_stdlib(None) // we handle this below
.compile("rustllvm");
Expand Down Expand Up @@ -214,6 +256,20 @@ fn main() {
println!("cargo:rustc-link-lib={}={}", kind, name);
}

if enable_polly {
match polly_link_kind {
"dylib" => {
panic!("dynamically linking polly is not possible :(");
//println!("cargo:rustc-flags=-l:LLVMPolly")
},
_ => println!("cargo:rustc-link-lib={}=Polly", polly_link_kind),
}

if polly_link_isl {
println!("cargo:rustc-link-lib={}=PollyISL", polly_link_kind);
}
}

// LLVM ldflags
//
// If we're a cross-compile of LLVM then unfortunately we can't trust these
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1642,7 +1642,8 @@ extern "C" {
Singlethread: bool)
-> TargetMachineRef;
pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: ModuleRef);
pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: ModuleRef,
Polly: bool);
pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
M: ModuleRef,
DisableSimplifyLibCalls: bool);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ fn run_pass_manager(cgcx: &CodegenContext,
debug!("running the pass manager");
unsafe {
let pm = llvm::LLVMCreatePassManager();
llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod);
llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod, config.polly);
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
assert!(!pass.is_null());
llvm::LLVMRustAddPass(pm, pass);
Expand Down
22 changes: 15 additions & 7 deletions src/librustc_trans/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ pub struct ModuleConfig {
no_integrated_as: bool,
embed_bitcode: bool,
embed_bitcode_marker: bool,
pub polly: bool,
}

impl ModuleConfig {
Expand Down Expand Up @@ -281,7 +282,8 @@ impl ModuleConfig {
vectorize_loop: false,
vectorize_slp: false,
merge_functions: false,
inline_threshold: None
inline_threshold: None,
polly: false,
}
}

Expand Down Expand Up @@ -319,6 +321,8 @@ impl ModuleConfig {

self.merge_functions = sess.opts.optimize == config::OptLevel::Default ||
sess.opts.optimize == config::OptLevel::Aggressive;
self.polly = sess.opts.debugging_opts.polly && !self.no_prepopulate_passes &&
!sess.target.target.options.is_like_emscripten;
}
}

Expand Down Expand Up @@ -546,8 +550,8 @@ unsafe fn optimize(cgcx: &CodegenContext,

if !config.no_verify { assert!(addpass("verify")); }
if !config.no_prepopulate_passes {
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod, config.polly);
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod, config.polly);
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
with_llvm_pmb(llmod, &config, opt_level, &mut |b| {
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
Expand Down Expand Up @@ -645,11 +649,12 @@ unsafe fn codegen(cgcx: &CodegenContext,
unsafe fn with_codegen<F, R>(tm: TargetMachineRef,
llmod: ModuleRef,
no_builtins: bool,
polly: bool,
f: F) -> R
where F: FnOnce(PassManagerRef) -> R,
{
let cpm = llvm::LLVMCreatePassManager();
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod, polly);
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
f(cpm)
}
Expand Down Expand Up @@ -744,7 +749,8 @@ unsafe fn codegen(cgcx: &CodegenContext,
cursor.position() as size_t
}

with_codegen(tm, llmod, config.no_builtins, |cpm| {
with_codegen(tm, llmod, config.no_builtins, config.polly,
|cpm| {
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback);
llvm::LLVMDisposePassManager(cpm);
});
Expand All @@ -762,7 +768,8 @@ unsafe fn codegen(cgcx: &CodegenContext,
} else {
llmod
};
with_codegen(tm, llmod, config.no_builtins, |cpm| {
with_codegen(tm, llmod, config.no_builtins, config.polly,
|cpm| {
write_output_file(diag_handler, tm, cpm, llmod, &path,
llvm::FileType::AssemblyFile)
})?;
Expand All @@ -773,7 +780,8 @@ unsafe fn codegen(cgcx: &CodegenContext,
}

if write_obj {
with_codegen(tm, llmod, config.no_builtins, |cpm| {
with_codegen(tm, llmod, config.no_builtins, config.polly,
|cpm| {
write_output_file(diag_handler, tm, cpm, llmod, &obj_out,
llvm::FileType::ObjectFile)
})?;
Expand Down
22 changes: 21 additions & 1 deletion src/rustllvm/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder,
LLVMPassManagerBuilderRef)

#if ENABLE_POLLY
namespace polly {
void initializePollyPasses(llvm::PassRegistry &Registry);
void registerPollyPasses(llvm::legacy::PassManagerBase &PM);
}
#endif

extern "C" void LLVMInitializePasses() {
PassRegistry &Registry = *PassRegistry::getPassRegistry();
initializeCore(Registry);
Expand All @@ -73,6 +80,10 @@ extern "C" void LLVMInitializePasses() {
initializeInstCombine(Registry);
initializeInstrumentation(Registry);
initializeTarget(Registry);

#if ENABLE_POLLY
polly::initializePollyPasses(Registry);
#endif
}

enum class LLVMRustPassKind {
Expand Down Expand Up @@ -420,10 +431,19 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
// this function.
extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
LLVMPassManagerRef PMR,
LLVMModuleRef M) {
LLVMModuleRef M,
bool Polly) {
PassManagerBase *PM = unwrap(PMR);
PM->add(
createTargetTransformInfoWrapperPass(unwrap(TM)->getTargetIRAnalysis()));

#if ENABLE_POLLY
if(Polly) {
polly::registerPollyPasses(*PM);
}
#else
(void)Polly;
#endif
}

extern "C" void LLVMRustConfigurePassManagerBuilder(
Expand Down
Loading

0 comments on commit 4bcf25a

Please sign in to comment.