auto merge of #16367 : epdtry/rust/parallel-codegen, r=alexcrichton
This branch adds support for running LLVM optimization and codegen on different parts of a crate in parallel. Instead of translating the crate into a single LLVM compilation unit, `rustc` now distributes items in the crate among several compilation units, and spawns worker threads to optimize and codegen each compilation unit independently. This improves compile times on multicore machines, at the cost of worse performance in the compiled code. The intent is to speed up build times during development without sacrificing too much optimization. On the machine I tested this on, `librustc` build time with `-O` went from 265 seconds (master branch, single-threaded) to 115s (this branch, with 4 threads), a speedup of 2.3x. For comparison, the build time without `-O` was 90s (single-threaded). Bootstrapping `rustc` using 4 threads gets a 1.6x speedup over the default settings (870s vs. 1380s), and building `librustc` with the resulting stage2 compiler takes 1.3x as long as the master branch (44s vs. 55s, single threaded, ignoring time spent in LLVM codegen). The user-visible changes from this branch are two new codegen flags: * `-C codegen-units=N`: Distribute items across `N` compilation units. * `-C codegen-threads=N`: Spawn `N` worker threads for running optimization and codegen. (It is possible to set `codegen-threads` larger than `codegen-units`, but this is not very useful.) Internal changes to the compiler are described in detail on the individual commit messages. Note: The first commit on this branch is copied from #16359, which this branch depends on. r? @nick29581
This commit is contained in:
commit
4bea7b3ed0
56 changed files with 2966 additions and 1176 deletions
14
src/test/auxiliary/sepcomp-extern-lib.rs
Normal file
14
src/test/auxiliary/sepcomp-extern-lib.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn foo() -> uint {
|
||||
1234
|
||||
}
|
||||
17
src/test/auxiliary/sepcomp_cci_lib.rs
Normal file
17
src/test/auxiliary/sepcomp_cci_lib.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[inline]
|
||||
pub fn cci_fn() -> uint {
|
||||
1200
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub static CCI_STATIC: uint = 34;
|
||||
31
src/test/auxiliary/sepcomp_lib.rs
Normal file
31
src/test/auxiliary/sepcomp_lib.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -C codegen-units=3 --crate-type=rlib,dylib
|
||||
|
||||
pub mod a {
|
||||
pub fn one() -> uint {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
pub mod b {
|
||||
pub fn two() -> uint {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
pub mod c {
|
||||
use a::one;
|
||||
use b::two;
|
||||
pub fn three() -> uint {
|
||||
one() + two()
|
||||
}
|
||||
}
|
||||
28
src/test/compile-fail/sepcomp-lib-lto.rs
Normal file
28
src/test/compile-fail/sepcomp-lib-lto.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Make sure we give a sane error message when the user requests LTO with a
|
||||
// library built with -C codegen-units > 1.
|
||||
|
||||
// aux-build:sepcomp_lib.rs
|
||||
// compile-flags: -Z lto
|
||||
// error-pattern:missing compressed bytecode
|
||||
// no-prefer-dynamic
|
||||
|
||||
extern crate sepcomp_lib;
|
||||
use sepcomp_lib::a::one;
|
||||
use sepcomp_lib::b::two;
|
||||
use sepcomp_lib::c::three;
|
||||
|
||||
fn main() {
|
||||
assert_eq!(one(), 1);
|
||||
assert_eq!(two(), 2);
|
||||
assert_eq!(three(), 3);
|
||||
}
|
||||
|
|
@ -5,40 +5,69 @@ all:
|
|||
$(call REMOVE_RLIBS,bar)
|
||||
$(call REMOVE_DYLIBS,bar)
|
||||
rm $(TMPDIR)/$(call STATICLIB_GLOB,bar)
|
||||
# Check that $(TMPDIR) is empty.
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --crate-type=bin
|
||||
rm $(TMPDIR)/$(call BIN,bar)
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --emit=asm,ir,bc,obj,link
|
||||
rm $(TMPDIR)/bar.ll
|
||||
rm $(TMPDIR)/bar.bc
|
||||
rm $(TMPDIR)/bar.s
|
||||
rm $(TMPDIR)/bar.o
|
||||
rm $(TMPDIR)/$(call BIN,bar)
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --emit=asm -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --emit=bc -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --emit=ir -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --emit=obj -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --emit=link -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/$(call BIN,foo)
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/$(call BIN,foo) # FIXME 13794
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/$(call BIN,foo)
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
||||
$(RUSTC) foo.rs --emit=asm,ir,bc,obj,link --crate-type=staticlib
|
||||
rm $(TMPDIR)/bar.ll
|
||||
rm $(TMPDIR)/bar.s
|
||||
rm $(TMPDIR)/bar.o
|
||||
rm $(TMPDIR)/$(call STATICLIB_GLOB,bar)
|
||||
$(RUSTC) foo.rs --emit=asm -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
$(RUSTC) foo.rs --emit=bc -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
$(RUSTC) foo.rs --emit=ir -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
$(RUSTC) foo.rs --emit=obj -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
$(RUSTC) foo.rs --emit=link -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/$(call BIN,foo)
|
||||
$(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
$(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/$(call BIN,foo) # FIXME 13794
|
||||
$(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/foo
|
||||
$(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/foo
|
||||
rm $(TMPDIR)/$(call BIN,foo)
|
||||
mv $(TMPDIR)/bar.bc $(TMPDIR)/foo.bc
|
||||
# Don't check that the $(TMPDIR) is empty - we left `foo.bc` for later
|
||||
# comparison.
|
||||
|
||||
$(RUSTC) foo.rs --emit=bc,link --crate-type=rlib
|
||||
cmp $(TMPDIR)/foo.bc $(TMPDIR)/bar.bc
|
||||
rm $(TMPDIR)/bar.bc
|
||||
rm $(TMPDIR)/foo.bc
|
||||
$(call REMOVE_RLIBS,bar)
|
||||
[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
|
||||
|
|
|
|||
10
src/test/run-make/sepcomp-cci-copies/Makefile
Normal file
10
src/test/run-make/sepcomp-cci-copies/Makefile
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
-include ../tools.mk
|
||||
|
||||
# Check that cross-crate inlined items are inlined in all compilation units
|
||||
# that refer to them, and not in any other compilation units.
|
||||
|
||||
all:
|
||||
$(RUSTC) cci_lib.rs
|
||||
$(RUSTC) foo.rs --emit=ir -C codegen-units=3
|
||||
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ .*cci_fn)" -eq "2" ]
|
||||
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c CCI_STATIC.*=.*constant)" -eq "2" ]
|
||||
19
src/test/run-make/sepcomp-cci-copies/cci_lib.rs
Normal file
19
src/test/run-make/sepcomp-cci-copies/cci_lib.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[inline]
|
||||
pub fn cci_fn() -> uint {
|
||||
1234
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub static CCI_STATIC: uint = 2345;
|
||||
36
src/test/run-make/sepcomp-cci-copies/foo.rs
Normal file
36
src/test/run-make/sepcomp-cci-copies/foo.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate cci_lib;
|
||||
use cci_lib::{cci_fn, CCI_STATIC};
|
||||
|
||||
fn call1() -> uint {
|
||||
cci_fn() + CCI_STATIC
|
||||
}
|
||||
|
||||
mod a {
|
||||
use cci_lib::cci_fn;
|
||||
pub fn call2() -> uint {
|
||||
cci_fn()
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
use cci_lib::CCI_STATIC;
|
||||
pub fn call3() -> uint {
|
||||
CCI_STATIC
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
call1();
|
||||
a::call2();
|
||||
b::call3();
|
||||
}
|
||||
13
src/test/run-make/sepcomp-inlining/Makefile
Normal file
13
src/test/run-make/sepcomp-inlining/Makefile
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
-include ../tools.mk
|
||||
|
||||
# Test that #[inline(always)] functions still get inlined across compilation
|
||||
# unit boundaries. Compilation should produce three IR files, with each one
|
||||
# containing a definition of the inlined function. Also, the non-#[inline]
|
||||
# function should be defined in only one compilation unit.
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs --emit=ir -C codegen-units=3
|
||||
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ i32\ .*inlined)" -eq "1" ]
|
||||
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ available_externally\ i32\ .*inlined)" -eq "2" ]
|
||||
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ i32\ .*normal)" -eq "1" ]
|
||||
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c declare\ i32\ .*normal)" -eq "2" ]
|
||||
35
src/test/run-make/sepcomp-inlining/foo.rs
Normal file
35
src/test/run-make/sepcomp-inlining/foo.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[inline]
|
||||
fn inlined() -> u32 {
|
||||
1234
|
||||
}
|
||||
|
||||
fn normal() -> u32 {
|
||||
2345
|
||||
}
|
||||
|
||||
mod a {
|
||||
pub fn f() -> u32 {
|
||||
::inlined() + ::normal()
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
pub fn f() -> u32 {
|
||||
::inlined() + ::normal()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
a::f();
|
||||
b::f();
|
||||
}
|
||||
9
src/test/run-make/sepcomp-separate/Makefile
Normal file
9
src/test/run-make/sepcomp-separate/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
-include ../tools.mk
|
||||
|
||||
# Test that separate compilation actually puts code into separate compilation
|
||||
# units. `foo.rs` defines `magic_fn` in three different modules, which should
|
||||
# wind up in three different compilation units.
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs --emit=ir -C codegen-units=3
|
||||
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ .*magic_fn)" -eq "3" ]
|
||||
27
src/test/run-make/sepcomp-separate/foo.rs
Normal file
27
src/test/run-make/sepcomp-separate/foo.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn magic_fn() -> uint {
|
||||
1234
|
||||
}
|
||||
|
||||
mod a {
|
||||
pub fn magic_fn() -> uint {
|
||||
2345
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
pub fn magic_fn() -> uint {
|
||||
3456
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
41
src/test/run-pass/sepcomp-cci.rs
Normal file
41
src/test/run-pass/sepcomp-cci.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -C codegen-units=3
|
||||
// aux-build:sepcomp_cci_lib.rs
|
||||
|
||||
// Test accessing cross-crate inlined items from multiple compilation units.
|
||||
|
||||
extern crate sepcomp_cci_lib;
|
||||
use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
|
||||
|
||||
fn call1() -> uint {
|
||||
cci_fn() + CCI_STATIC
|
||||
}
|
||||
|
||||
mod a {
|
||||
use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
|
||||
pub fn call2() -> uint {
|
||||
cci_fn() + CCI_STATIC
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
|
||||
pub fn call3() -> uint {
|
||||
cci_fn() + CCI_STATIC
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(call1(), 1234);
|
||||
assert_eq!(a::call2(), 1234);
|
||||
assert_eq!(b::call3(), 1234);
|
||||
}
|
||||
42
src/test/run-pass/sepcomp-extern.rs
Normal file
42
src/test/run-pass/sepcomp-extern.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -C codegen-units=3
|
||||
// aux-build:sepcomp-extern-lib.rs
|
||||
|
||||
// Test accessing external items from multiple compilation units.
|
||||
|
||||
#[link(name = "sepcomp-extern-lib")]
|
||||
extern {
|
||||
#[allow(ctypes)]
|
||||
fn foo() -> uint;
|
||||
}
|
||||
|
||||
fn call1() -> uint {
|
||||
unsafe { foo() }
|
||||
}
|
||||
|
||||
mod a {
|
||||
pub fn call2() -> uint {
|
||||
unsafe { ::foo() }
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
pub fn call3() -> uint {
|
||||
unsafe { ::foo() }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(call1(), 1234);
|
||||
assert_eq!(a::call2(), 1234);
|
||||
assert_eq!(b::call3(), 1234);
|
||||
}
|
||||
41
src/test/run-pass/sepcomp-fns-backwards.rs
Normal file
41
src/test/run-pass/sepcomp-fns-backwards.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -C codegen-units=3
|
||||
|
||||
// Test references to items that haven't been translated yet.
|
||||
|
||||
// Generate some code in the first compilation unit before declaring any
|
||||
// modules. This ensures that the first module doesn't go into the same
|
||||
// compilation unit as the top-level module.
|
||||
fn pad() -> uint { 0 }
|
||||
|
||||
mod b {
|
||||
pub fn three() -> uint {
|
||||
::one() + ::a::two()
|
||||
}
|
||||
}
|
||||
|
||||
mod a {
|
||||
pub fn two() -> uint {
|
||||
::one() + ::one()
|
||||
}
|
||||
}
|
||||
|
||||
fn one() -> uint {
|
||||
1
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(one(), 1);
|
||||
assert_eq!(a::two(), 2);
|
||||
assert_eq!(b::three(), 3);
|
||||
}
|
||||
|
||||
38
src/test/run-pass/sepcomp-fns.rs
Normal file
38
src/test/run-pass/sepcomp-fns.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -C codegen-units=3
|
||||
|
||||
// Test basic separate compilation functionality. The functions should be able
|
||||
// to call each other even though they will be placed in different compilation
|
||||
// units.
|
||||
|
||||
// Generate some code in the first compilation unit before declaring any
|
||||
// modules. This ensures that the first module doesn't go into the same
|
||||
// compilation unit as the top-level module.
|
||||
fn one() -> uint { 1 }
|
||||
|
||||
mod a {
|
||||
pub fn two() -> uint {
|
||||
::one() + ::one()
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
pub fn three() -> uint {
|
||||
::one() + ::a::two()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(one(), 1);
|
||||
assert_eq!(a::two(), 2);
|
||||
assert_eq!(b::three(), 3);
|
||||
}
|
||||
24
src/test/run-pass/sepcomp-lib.rs
Normal file
24
src/test/run-pass/sepcomp-lib.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:sepcomp_lib.rs
|
||||
|
||||
// Test linking against a library built with -C codegen-units > 1
|
||||
|
||||
extern crate sepcomp_lib;
|
||||
use sepcomp_lib::a::one;
|
||||
use sepcomp_lib::b::two;
|
||||
use sepcomp_lib::c::three;
|
||||
|
||||
fn main() {
|
||||
assert_eq!(one(), 1);
|
||||
assert_eq!(two(), 2);
|
||||
assert_eq!(three(), 3);
|
||||
}
|
||||
39
src/test/run-pass/sepcomp-statics.rs
Normal file
39
src/test/run-pass/sepcomp-statics.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -C codegen-units=3
|
||||
|
||||
// Test references to static items across compilation units.
|
||||
|
||||
fn pad() -> uint { 0 }
|
||||
|
||||
static ONE: uint = 1;
|
||||
|
||||
mod b {
|
||||
// Separate compilation always switches to the LLVM module with the fewest
|
||||
// instructions. Make sure we have some instructions in this module so
|
||||
// that `a` and `b` don't go into the same compilation unit.
|
||||
fn pad() -> uint { 0 }
|
||||
|
||||
pub static THREE: uint = ::ONE + ::a::TWO;
|
||||
}
|
||||
|
||||
mod a {
|
||||
fn pad() -> uint { 0 }
|
||||
|
||||
pub static TWO: uint = ::ONE + ::ONE;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(ONE, 1);
|
||||
assert_eq!(a::TWO, 2);
|
||||
assert_eq!(b::THREE, 3);
|
||||
}
|
||||
|
||||
38
src/test/run-pass/sepcomp-unwind.rs
Normal file
38
src/test/run-pass/sepcomp-unwind.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -C codegen-units=3
|
||||
|
||||
// Test unwinding through multiple compilation units.
|
||||
|
||||
// According to acrichto, in the distant past `ld -r` (which is used during
|
||||
// linking when codegen-units > 1) was known to produce object files with
|
||||
// damaged unwinding tables. This may be related to GNU binutils bug #6893
|
||||
// ("Partial linking results in corrupt .eh_frame_hdr"), but I'm not certain.
|
||||
// In any case, this test should let us know if enabling parallel codegen ever
|
||||
// breaks unwinding.
|
||||
|
||||
fn pad() -> uint { 0 }
|
||||
|
||||
mod a {
|
||||
pub fn f() {
|
||||
fail!();
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
pub fn g() {
|
||||
::a::f();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
std::task::try(proc() { ::b::g() }).unwrap_err();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue