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

Add Polly support #50044

Closed
wants to merge 1 commit 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
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",
Copy link
Member

Choose a reason for hiding this comment

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

Can this not be a normal submodule placed in src/polly for example? I believe you can use LLVM_EXTERNAL_POLLY_SOURCE_DIR to tell llvm where to find it.

"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 {
Copy link
Member

Choose a reason for hiding this comment

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

builder.kind only records how x.py is invoked, i.e. if you use

./x.py test src/test/compile-fail ...

then librustc etc will be built with builder.config.rust_polly_tests instead of builder.config.rust_polly_self, even if it is a build artifact.

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