@@ -28,6 +28,8 @@ use std::iter::repeat;
28
28
use std:: net:: TcpStream ;
29
29
use std:: path:: { Path , PathBuf } ;
30
30
use std:: process:: { Command , Output , ExitStatus } ;
31
+ use std:: str;
32
+ use test:: MetricMap ;
31
33
32
34
pub fn run ( config : Config , testfile : & Path ) {
33
35
match & * config. target {
@@ -41,6 +43,11 @@ pub fn run(config: Config, testfile: &Path) {
41
43
_=> { }
42
44
}
43
45
46
+ let mut _mm = MetricMap :: new ( ) ;
47
+ run_metrics ( config, testfile, & mut _mm) ;
48
+ }
49
+
50
+ pub fn run_metrics ( config : Config , testfile : & Path , mm : & mut MetricMap ) {
44
51
if config. verbose {
45
52
// We're going to be dumping a lot of info. Start on a new line.
46
53
print ! ( "\n \n " ) ;
@@ -57,7 +64,7 @@ pub fn run(config: Config, testfile: &Path) {
57
64
Pretty => run_pretty_test ( & config, & props, & testfile) ,
58
65
DebugInfoGdb => run_debuginfo_gdb_test ( & config, & props, & testfile) ,
59
66
DebugInfoLldb => run_debuginfo_lldb_test ( & config, & props, & testfile) ,
60
- Codegen => run_codegen_test ( & config, & props, & testfile) ,
67
+ Codegen => run_codegen_test ( & config, & props, & testfile, mm ) ,
61
68
Rustdoc => run_rustdoc_test ( & config, & props, & testfile) ,
62
69
}
63
70
}
@@ -1678,15 +1685,26 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
1678
1685
}
1679
1686
}
1680
1687
1681
- // codegen tests (using FileCheck)
1688
+ // codegen tests (vs. clang)
1689
+
1690
+ fn append_suffix_to_stem ( p : & Path , suffix : & str ) -> PathBuf {
1691
+ if suffix. is_empty ( ) {
1692
+ p. to_path_buf ( )
1693
+ } else {
1694
+ let mut stem = p. file_stem ( ) . unwrap ( ) . to_os_string ( ) ;
1695
+ stem. push ( "-" ) ;
1696
+ stem. push ( suffix) ;
1697
+ p. with_file_name ( & stem)
1698
+ }
1699
+ }
1682
1700
1683
- fn compile_test_and_save_ir ( config : & Config , props : & TestProps ,
1701
+ fn compile_test_and_save_bitcode ( config : & Config , props : & TestProps ,
1684
1702
testfile : & Path ) -> ProcRes {
1685
1703
let aux_dir = aux_output_dir_name ( config, testfile) ;
1686
1704
// FIXME (#9639): This needs to handle non-utf8 paths
1687
1705
let mut link_args = vec ! ( "-L" . to_string( ) ,
1688
1706
aux_dir. to_str( ) . unwrap( ) . to_string( ) ) ;
1689
- let llvm_args = vec ! ( "--emit=llvm-ir " . to_string( ) ,
1707
+ let llvm_args = vec ! ( "--emit=llvm-bc,obj " . to_string( ) ,
1690
1708
"--crate-type=lib" . to_string( ) ) ;
1691
1709
link_args. extend ( llvm_args. into_iter ( ) ) ;
1692
1710
let args = make_compile_args ( config,
@@ -1699,34 +1717,121 @@ fn compile_test_and_save_ir(config: &Config, props: &TestProps,
1699
1717
compose_and_run_compiler ( config, props, testfile, args, None )
1700
1718
}
1701
1719
1702
- fn check_ir_with_filecheck ( config : & Config , testfile : & Path ) -> ProcRes {
1703
- let irfile = output_base_name ( config, testfile) . with_extension ( "ll" ) ;
1704
- let prog = config. llvm_bin_path . as_ref ( ) . unwrap ( ) . join ( "FileCheck" ) ;
1720
+ fn compile_cc_with_clang_and_save_bitcode ( config : & Config , _props : & TestProps ,
1721
+ testfile : & Path ) -> ProcRes {
1722
+ let bitcodefile = output_base_name ( config, testfile) . with_extension ( "bc" ) ;
1723
+ let bitcodefile = append_suffix_to_stem ( & bitcodefile, "clang" ) ;
1724
+ let testcc = testfile. with_extension ( "cc" ) ;
1725
+ let proc_args = ProcArgs {
1726
+ // FIXME (#9639): This needs to handle non-utf8 paths
1727
+ prog : config. clang_path . as_ref ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ,
1728
+ args : vec ! ( "-c" . to_string( ) ,
1729
+ "-emit-llvm" . to_string( ) ,
1730
+ "-o" . to_string( ) ,
1731
+ bitcodefile. to_str( ) . unwrap( ) . to_string( ) ,
1732
+ testcc. to_str( ) . unwrap( ) . to_string( ) )
1733
+ } ;
1734
+ compose_and_run ( config, testfile, proc_args, Vec :: new ( ) , "" , None , None )
1735
+ }
1736
+
1737
+ fn extract_function_from_bitcode ( config : & Config , _props : & TestProps ,
1738
+ fname : & str , testfile : & Path ,
1739
+ suffix : & str ) -> ProcRes {
1740
+ let bitcodefile = output_base_name ( config, testfile) . with_extension ( "bc" ) ;
1741
+ let bitcodefile = append_suffix_to_stem ( & bitcodefile, suffix) ;
1742
+ let extracted_bc = append_suffix_to_stem ( & bitcodefile, "extract" ) ;
1743
+ let prog = config. llvm_bin_path . as_ref ( ) . unwrap ( ) . join ( "llvm-extract" ) ;
1705
1744
let proc_args = ProcArgs {
1706
1745
// FIXME (#9639): This needs to handle non-utf8 paths
1707
1746
prog : prog. to_str ( ) . unwrap ( ) . to_string ( ) ,
1708
- args : vec ! ( format!( "-input-file={}" , irfile. to_str( ) . unwrap( ) ) ,
1709
- testfile. to_str( ) . unwrap( ) . to_string( ) )
1747
+ args : vec ! ( format!( "-func={}" , fname) ,
1748
+ format!( "-o={}" , extracted_bc. to_str( ) . unwrap( ) ) ,
1749
+ bitcodefile. to_str( ) . unwrap( ) . to_string( ) )
1710
1750
} ;
1711
1751
compose_and_run ( config, testfile, proc_args, Vec :: new ( ) , "" , None , None )
1712
1752
}
1713
1753
1714
- fn run_codegen_test ( config : & Config , props : & TestProps , testfile : & Path ) {
1754
+ fn disassemble_extract ( config : & Config , _props : & TestProps ,
1755
+ testfile : & Path , suffix : & str ) -> ProcRes {
1756
+ let bitcodefile = output_base_name ( config, testfile) . with_extension ( "bc" ) ;
1757
+ let bitcodefile = append_suffix_to_stem ( & bitcodefile, suffix) ;
1758
+ let extracted_bc = append_suffix_to_stem ( & bitcodefile, "extract" ) ;
1759
+ let extracted_ll = extracted_bc. with_extension ( "ll" ) ;
1760
+ let prog = config. llvm_bin_path . as_ref ( ) . unwrap ( ) . join ( "llvm-dis" ) ;
1761
+ let proc_args = ProcArgs {
1762
+ // FIXME (#9639): This needs to handle non-utf8 paths
1763
+ prog : prog. to_str ( ) . unwrap ( ) . to_string ( ) ,
1764
+ args : vec ! ( format!( "-o={}" , extracted_ll. to_str( ) . unwrap( ) ) ,
1765
+ extracted_bc. to_str( ) . unwrap( ) . to_string( ) )
1766
+ } ;
1767
+ compose_and_run ( config, testfile, proc_args, Vec :: new ( ) , "" , None , None )
1768
+ }
1769
+
1770
+
1771
+ fn count_extracted_lines ( p : & Path ) -> usize {
1772
+ let mut x = Vec :: new ( ) ;
1773
+ File :: open ( & p. with_extension ( "ll" ) ) . unwrap ( ) . read_to_end ( & mut x) . unwrap ( ) ;
1774
+ let x = str:: from_utf8 ( & x) . unwrap ( ) ;
1775
+ x. lines ( ) . count ( )
1776
+ }
1777
+
1778
+
1779
+ fn run_codegen_test ( config : & Config , props : & TestProps ,
1780
+ testfile : & Path , mm : & mut MetricMap ) {
1715
1781
1716
1782
if config. llvm_bin_path . is_none ( ) {
1717
1783
fatal ( "missing --llvm-bin-path" ) ;
1718
1784
}
1719
1785
1720
- let mut proc_res = compile_test_and_save_ir ( config, props, testfile) ;
1786
+ if config. clang_path . is_none ( ) {
1787
+ fatal ( "missing --clang-path" ) ;
1788
+ }
1789
+
1790
+ let mut proc_res = compile_test_and_save_bitcode ( config, props, testfile) ;
1791
+ if !proc_res. status . success ( ) {
1792
+ fatal_proc_rec ( "compilation failed!" , & proc_res) ;
1793
+ }
1794
+
1795
+ proc_res = extract_function_from_bitcode ( config, props, "test" , testfile, "" ) ;
1796
+ if !proc_res. status . success ( ) {
1797
+ fatal_proc_rec ( "extracting 'test' function failed" ,
1798
+ & proc_res) ;
1799
+ }
1800
+
1801
+ proc_res = disassemble_extract ( config, props, testfile, "" ) ;
1802
+ if !proc_res. status . success ( ) {
1803
+ fatal_proc_rec ( "disassembling extract failed" , & proc_res) ;
1804
+ }
1805
+
1806
+
1807
+ let mut proc_res = compile_cc_with_clang_and_save_bitcode ( config, props, testfile) ;
1721
1808
if !proc_res. status . success ( ) {
1722
1809
fatal_proc_rec ( "compilation failed!" , & proc_res) ;
1723
1810
}
1724
1811
1725
- proc_res = check_ir_with_filecheck ( config, testfile) ;
1812
+ proc_res = extract_function_from_bitcode ( config, props , "test" , testfile, "clang" ) ;
1726
1813
if !proc_res. status . success ( ) {
1727
- fatal_proc_rec ( "verification with 'FileCheck' failed" ,
1814
+ fatal_proc_rec ( "extracting 'test' function failed" ,
1728
1815
& proc_res) ;
1729
1816
}
1817
+
1818
+ proc_res = disassemble_extract ( config, props, testfile, "clang" ) ;
1819
+ if !proc_res. status . success ( ) {
1820
+ fatal_proc_rec ( "disassembling extract failed" , & proc_res) ;
1821
+ }
1822
+
1823
+ let base = output_base_name ( config, testfile) ;
1824
+ let base_extract = append_suffix_to_stem ( & base, "extract" ) ;
1825
+
1826
+ let base_clang = append_suffix_to_stem ( & base, "clang" ) ;
1827
+ let base_clang_extract = append_suffix_to_stem ( & base_clang, "extract" ) ;
1828
+
1829
+ let base_lines = count_extracted_lines ( & base_extract) ;
1830
+ let clang_lines = count_extracted_lines ( & base_clang_extract) ;
1831
+
1832
+ mm. insert_metric ( "clang-codegen-ratio" ,
1833
+ ( base_lines as f64 ) / ( clang_lines as f64 ) ,
1834
+ 0.001 ) ;
1730
1835
}
1731
1836
1732
1837
fn charset ( ) -> & ' static str {
0 commit comments