Skip to content

Commit 16cc121

Browse files
committed
Auto merge of #50044 - DiamondLovesYou:polly, r=<try>
Add Polly support It is always compiled and linked, but not used by default. Use can be triggered via `-Z polly=true` or at compiler build-time (see `config.toml.example`).
2 parents 491512b + 337b28c commit 16cc121

File tree

11 files changed

+116
-11
lines changed

11 files changed

+116
-11
lines changed

config.toml.example

+4
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,10 @@
346346
# Whether to deny warnings in crates
347347
#deny-warnings = true
348348

349+
# Use polyhedral optimizations by default. Note, enabling this on a build of
350+
# LLVM which lacks Polly (or only has a shared version) *won't* error.
351+
#use-polly-by-default = false
352+
349353
# =============================================================================
350354
# Options for specific targets
351355
#

src/bootstrap/bootstrap.py

+4
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,10 @@ def update_submodules(self):
690690
recorded_submodules[data[3]] = data[2]
691691
for module in filtered_submodules:
692692
self.update_submodule(module[0], module[1], recorded_submodules)
693+
polly_path = "src/llvm/tools/polly"
694+
if not os.path.exists(os.path.join(self.rust_root, polly_path)):
695+
run(["git", "clone", "https://github.com/llvm-mirror/polly.git",
696+
"src/llvm/tools/polly", "-b", "release_60"])
693697
print("Submodules updated in %.2f seconds" % (time() - start_time))
694698

695699
def set_dev_environment(self):

src/bootstrap/compile.rs

+3
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,9 @@ pub fn rustc_cargo_env(builder: &Builder, cargo: &mut Command) {
553553
if builder.config.rustc_parallel_queries {
554554
cargo.env("RUSTC_PARALLEL_QUERIES", "1");
555555
}
556+
if builder.config.rust_codegen_polly_by_default {
557+
cargo.env("RUSTC_FORCE_USE_POLLY", "1");
558+
}
556559
}
557560

558561
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]

src/bootstrap/config.rs

+6
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ pub struct Config {
103103
pub rust_dist_src: bool,
104104
pub rust_codegen_backends: Vec<Interned<String>>,
105105
pub rust_codegen_backends_dir: String,
106+
pub rust_codegen_polly_by_default: bool,
106107

107108
pub build: Interned<String>,
108109
pub hosts: Vec<Interned<String>>,
@@ -306,6 +307,7 @@ struct Rust {
306307
wasm_syscall: Option<bool>,
307308
lld: Option<bool>,
308309
deny_warnings: Option<bool>,
310+
use_polly_by_default: Option<bool>,
309311
}
310312

311313
/// TOML representation of how each build target is configured.
@@ -537,6 +539,10 @@ impl Config {
537539
Some(n) => config.rust_codegen_units = Some(n),
538540
None => {}
539541
}
542+
543+
config.rust_codegen_polly_by_default = rust
544+
.use_polly_by_default
545+
.unwrap_or(false);
540546
}
541547

542548
if let Some(ref t) = toml.target {

src/librustc/session/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
12911291
"make the current crate share its generic instantiations"),
12921292
chalk: bool = (false, parse_bool, [TRACKED],
12931293
"enable the experimental Chalk-based trait solving engine"),
1294+
polly: bool = (option_env!("RUSTC_FORCE_USE_POLLY").is_some(),
1295+
parse_bool, [UNTRACKED], "Run the Polly polyhedral \
1296+
model optimization passes."),
12941297
}
12951298

12961299
pub fn default_lib_output() -> CrateType {

src/librustc_llvm/build.rs

+56
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,53 @@ fn main() {
157157
cfg.define("LLVM_RUSTLLVM", None);
158158
}
159159

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

259+
if enable_polly {
260+
match polly_link_kind {
261+
"dylib" => {
262+
panic!("dynamically linking polly is not possible :(");
263+
//println!("cargo:rustc-flags=-l:LLVMPolly")
264+
},
265+
_ => println!("cargo:rustc-link-lib={}=Polly", polly_link_kind),
266+
}
267+
268+
if polly_link_isl {
269+
println!("cargo:rustc-link-lib={}=PollyISL", polly_link_kind);
270+
}
271+
}
272+
217273
// LLVM ldflags
218274
//
219275
// If we're a cross-compile of LLVM then unfortunately we can't trust these

src/librustc_llvm/ffi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1642,7 +1642,8 @@ extern "C" {
16421642
Singlethread: bool)
16431643
-> TargetMachineRef;
16441644
pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
1645-
pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: ModuleRef);
1645+
pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: ModuleRef,
1646+
Polly: bool);
16461647
pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
16471648
M: ModuleRef,
16481649
DisableSimplifyLibCalls: bool);

src/librustc_trans/back/lto.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ fn run_pass_manager(cgcx: &CodegenContext,
460460
debug!("running the pass manager");
461461
unsafe {
462462
let pm = llvm::LLVMCreatePassManager();
463-
llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod);
463+
llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod, config.polly);
464464
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
465465
assert!(!pass.is_null());
466466
llvm::LLVMRustAddPass(pm, pass);

src/librustc_trans/back/write.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ pub struct ModuleConfig {
250250
no_integrated_as: bool,
251251
embed_bitcode: bool,
252252
embed_bitcode_marker: bool,
253+
pub polly: bool,
253254
}
254255

255256
impl ModuleConfig {
@@ -281,7 +282,8 @@ impl ModuleConfig {
281282
vectorize_loop: false,
282283
vectorize_slp: false,
283284
merge_functions: false,
284-
inline_threshold: None
285+
inline_threshold: None,
286+
polly: false,
285287
}
286288
}
287289

@@ -319,6 +321,8 @@ impl ModuleConfig {
319321

320322
self.merge_functions = sess.opts.optimize == config::OptLevel::Default ||
321323
sess.opts.optimize == config::OptLevel::Aggressive;
324+
self.polly = sess.opts.debugging_opts.polly && !self.no_prepopulate_passes &&
325+
!sess.target.target.options.is_like_emscripten;
322326
}
323327
}
324328

@@ -546,8 +550,8 @@ unsafe fn optimize(cgcx: &CodegenContext,
546550

547551
if !config.no_verify { assert!(addpass("verify")); }
548552
if !config.no_prepopulate_passes {
549-
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
550-
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
553+
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod, config.polly);
554+
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod, config.polly);
551555
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
552556
with_llvm_pmb(llmod, &config, opt_level, &mut |b| {
553557
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
@@ -645,11 +649,12 @@ unsafe fn codegen(cgcx: &CodegenContext,
645649
unsafe fn with_codegen<F, R>(tm: TargetMachineRef,
646650
llmod: ModuleRef,
647651
no_builtins: bool,
652+
polly: bool,
648653
f: F) -> R
649654
where F: FnOnce(PassManagerRef) -> R,
650655
{
651656
let cpm = llvm::LLVMCreatePassManager();
652-
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
657+
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod, polly);
653658
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
654659
f(cpm)
655660
}
@@ -744,7 +749,8 @@ unsafe fn codegen(cgcx: &CodegenContext,
744749
cursor.position() as size_t
745750
}
746751

747-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
752+
with_codegen(tm, llmod, config.no_builtins, config.polly,
753+
|cpm| {
748754
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback);
749755
llvm::LLVMDisposePassManager(cpm);
750756
});
@@ -762,7 +768,8 @@ unsafe fn codegen(cgcx: &CodegenContext,
762768
} else {
763769
llmod
764770
};
765-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
771+
with_codegen(tm, llmod, config.no_builtins, config.polly,
772+
|cpm| {
766773
write_output_file(diag_handler, tm, cpm, llmod, &path,
767774
llvm::FileType::AssemblyFile)
768775
})?;
@@ -773,7 +780,8 @@ unsafe fn codegen(cgcx: &CodegenContext,
773780
}
774781

775782
if write_obj {
776-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
783+
with_codegen(tm, llmod, config.no_builtins, config.polly,
784+
|cpm| {
777785
write_output_file(diag_handler, tm, cpm, llmod, &obj_out,
778786
llvm::FileType::ObjectFile)
779787
})?;

src/rustllvm/PassWrapper.cpp

+21-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
6161
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder,
6262
LLVMPassManagerBuilderRef)
6363

64+
#if ENABLE_POLLY
65+
namespace polly {
66+
void initializePollyPasses(llvm::PassRegistry &Registry);
67+
void registerPollyPasses(llvm::legacy::PassManagerBase &PM);
68+
}
69+
#endif
70+
6471
extern "C" void LLVMInitializePasses() {
6572
PassRegistry &Registry = *PassRegistry::getPassRegistry();
6673
initializeCore(Registry);
@@ -73,6 +80,10 @@ extern "C" void LLVMInitializePasses() {
7380
initializeInstCombine(Registry);
7481
initializeInstrumentation(Registry);
7582
initializeTarget(Registry);
83+
84+
#if ENABLE_POLLY
85+
polly::initializePollyPasses(Registry);
86+
#endif
7687
}
7788

7889
enum class LLVMRustPassKind {
@@ -420,10 +431,19 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
420431
// this function.
421432
extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
422433
LLVMPassManagerRef PMR,
423-
LLVMModuleRef M) {
434+
LLVMModuleRef M,
435+
bool Polly) {
424436
PassManagerBase *PM = unwrap(PMR);
425437
PM->add(
426438
createTargetTransformInfoWrapperPass(unwrap(TM)->getTargetIRAnalysis()));
439+
440+
#if ENABLE_POLLY
441+
if(Polly) {
442+
polly::registerPollyPasses(*PM);
443+
}
444+
#else
445+
(void)Polly;
446+
#endif
427447
}
428448

429449
extern "C" void LLVMRustConfigurePassManagerBuilder(

src/rustllvm/llvm-rebuild-trigger

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
22
# The actual contents of this file do not matter, but to trigger a change on the
33
# build bots then the contents should be changed so git updates the mtime.
4-
2018-04-05
4+
2018-04-18

0 commit comments

Comments
 (0)