From 42754ce710a777b38402b12728daf54d68ea2b50 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 13 Feb 2017 09:57:50 +0000 Subject: [PATCH 01/16] Add profiling support, through the rustc -Z profile flag. When -Z profile is passed, the GCDAProfiling LLVM pass is added to the pipeline, which uses debug information to instrument the IR. After compiling with -Z profile, the $(OUT_DIR)/$(CRATE_NAME).gcno file is created, containing initial profiling information. After running the program built, the $(OUT_DIR)/$(CRATE_NAME).gcda file is created, containing branch counters. The created *.gcno and *.gcda files can be processed using the "llvm-cov gcov" and "lcov" tools. The profiling data LLVM generates does not faithfully follow the GCC's format for *.gcno and *.gcda files, and so it will probably not work with other tools (such as gcov itself) that consume these files. --- configure | 1 + src/Cargo.lock | 9 +++ src/bootstrap/check.rs | 4 ++ src/bootstrap/config.rs | 4 ++ src/bootstrap/config.toml.example | 3 + src/bootstrap/lib.rs | 3 + src/doc/unstable-book/src/SUMMARY.md | 3 + .../src/compiler-flags/profile.md | 5 ++ .../src/language-features/profiler-runtime.md | 5 ++ .../library-features/profiler-runtime-lib.md | 5 ++ src/libprofiler_builtins/Cargo.toml | 18 ++++++ src/libprofiler_builtins/build.rs | 56 +++++++++++++++++++ src/libprofiler_builtins/lib.rs | 20 +++++++ src/librustc/middle/cstore.rs | 2 + src/librustc/session/config.rs | 2 + src/librustc_driver/driver.rs | 8 ++- src/librustc_llvm/ffi.rs | 4 ++ src/librustc_metadata/creader.rs | 28 ++++++++++ src/librustc_metadata/cstore.rs | 5 ++ src/librustc_metadata/cstore_impl.rs | 4 ++ src/librustc_trans/back/link.rs | 3 + src/librustc_trans/back/write.rs | 4 ++ src/librustc_trans/base.rs | 8 ++- src/librustc_trans/context.rs | 11 +++- src/librustc_trans/debuginfo/metadata.rs | 40 ++++++++++++- src/librustc_trans/debuginfo/mod.rs | 2 + src/libstd/Cargo.toml | 2 + src/libsyntax/feature_gate.rs | 11 ++++ src/rustllvm/RustWrapper.cpp | 4 ++ .../feature-gate-profiler-runtime.rs | 13 +++++ src/test/run-make/profile/Makefile | 7 +++ src/test/run-make/profile/test.rs | 11 ++++ 32 files changed, 296 insertions(+), 9 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/profile.md create mode 100644 src/doc/unstable-book/src/language-features/profiler-runtime.md create mode 100644 src/doc/unstable-book/src/library-features/profiler-runtime-lib.md create mode 100644 src/libprofiler_builtins/Cargo.toml create mode 100644 src/libprofiler_builtins/build.rs create mode 100644 src/libprofiler_builtins/lib.rs create mode 100644 src/test/compile-fail/feature-gate-profiler-runtime.rs create mode 100644 src/test/run-make/profile/Makefile create mode 100644 src/test/run-make/profile/test.rs diff --git a/configure b/configure index c5ecc2236894c..ced7377a23649 100755 --- a/configure +++ b/configure @@ -452,6 +452,7 @@ opt vendor 0 "enable usage of vendored Rust crates" opt sanitizers 0 "build the sanitizer runtimes (asan, lsan, msan, tsan)" opt dist-src 1 "when building tarballs enables building a source tarball" opt cargo-openssl-static 0 "static openssl in cargo" +opt profiler 0 "build the profiler runtime" # Optimization and debugging options. These may be overridden by the release channel, etc. opt_nosave optimize 1 "build optimized rust code" diff --git a/src/Cargo.lock b/src/Cargo.lock index 21b167f6d4273..696ba153c9a6a 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -355,6 +355,14 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "profiler_builtins" +version = "0.0.0" +dependencies = [ + "core 0.0.0", + "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pulldown-cmark" version = "0.0.8" @@ -833,6 +841,7 @@ dependencies = [ "libc 0.0.0", "panic_abort 0.0.0", "panic_unwind 0.0.0", + "profiler_builtins 0.0.0", "rand 0.0.0", "rustc_asan 0.0.0", "rustc_lsan 0.0.0", diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index d7457e0886943..47b1e06a5ff85 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -268,6 +268,10 @@ pub fn compiletest(build: &Build, cmd.env("SANITIZER_SUPPORT", "1"); } + if build.config.profiler { + cmd.env("PROFILER_SUPPORT", "1"); + } + cmd.arg("--adb-path").arg("adb"); cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); if target.contains("android") { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 34fbc33d981af..8133a869c250b 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -50,6 +50,7 @@ pub struct Config { pub full_bootstrap: bool, pub extended: bool, pub sanitizers: bool, + pub profiler: bool, // llvm codegen options pub llvm_assertions: bool, @@ -158,6 +159,7 @@ struct Build { extended: Option, verbose: Option, sanitizers: Option, + profiler: Option, openssl_static: Option, } @@ -311,6 +313,7 @@ impl Config { set(&mut config.extended, build.extended); set(&mut config.verbose, build.verbose); set(&mut config.sanitizers, build.sanitizers); + set(&mut config.profiler, build.profiler); set(&mut config.openssl_static, build.openssl_static); if let Some(ref install) = toml.install { @@ -462,6 +465,7 @@ impl Config { ("FULL_BOOTSTRAP", self.full_bootstrap), ("EXTENDED", self.extended), ("SANITIZERS", self.sanitizers), + ("PROFILER", self.profiler), ("DIST_SRC", self.rust_dist_src), ("CARGO_OPENSSL_STATIC", self.openssl_static), } diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index 0309eca0e5dea..93997027dbb89 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -147,6 +147,9 @@ # Build the sanitizer runtimes #sanitizers = false +# Build the profiler runtime +#profiler = false + # Indicates whether the OpenSSL linked into Cargo will be statically linked or # not. If static linkage is specified then the build system will download a # known-good version of OpenSSL, compile it, and link it to Cargo. diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 017d4015134d0..b0c0033fbe72f 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -667,6 +667,9 @@ impl Build { if self.config.backtrace { features.push_str(" backtrace"); } + if self.config.profiler { + features.push_str(" profiler"); + } return features } diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 0d0485dc872d7..27ee688a84fcd 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -2,6 +2,7 @@ - [Compiler flags](compiler-flags.md) - [linker_flavor](compiler-flags/linker-flavor.md) + - [profile](compiler-flags/profile.md) - [remap_path_prefix](compiler-flags/remap-path-prefix.md) - [Language features](language-features.md) - [abi_msp430_interrupt](language-features/abi-msp430-interrupt.md) @@ -71,6 +72,7 @@ - [plugin_registrar](language-features/plugin-registrar.md) - [prelude_import](language-features/prelude-import.md) - [proc_macro](language-features/proc-macro.md) + - [profiler_runtime](language-features/profiler-runtime.md) - [quote](language-features/quote.md) - [relaxed_adts](language-features/relaxed-adts.md) - [repr_align](language-features/repr-align.md) @@ -180,6 +182,7 @@ - [print](library-features/print.md) - [proc_macro_internals](library-features/proc-macro-internals.md) - [process_try_wait](library-features/process-try-wait.md) + - [profiler_runtime_lib](library-features/sanitizer-runtime-lib.md) - [question_mark_carrier](library-features/question-mark-carrier.md) - [rand](library-features/rand.md) - [range_contains](library-features/range-contains.md) diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md new file mode 100644 index 0000000000000..f9634c55c96e9 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/profile.md @@ -0,0 +1,5 @@ +# `profile` + +The tracking issue for this feature is: None + +------------------------ diff --git a/src/doc/unstable-book/src/language-features/profiler-runtime.md b/src/doc/unstable-book/src/language-features/profiler-runtime.md new file mode 100644 index 0000000000000..a9879c8d5a650 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/profiler-runtime.md @@ -0,0 +1,5 @@ +# `profiler_runtime` + +The tracking issue for this feature is: None. + +------------------------ diff --git a/src/doc/unstable-book/src/library-features/profiler-runtime-lib.md b/src/doc/unstable-book/src/library-features/profiler-runtime-lib.md new file mode 100644 index 0000000000000..a01f1e73ab404 --- /dev/null +++ b/src/doc/unstable-book/src/library-features/profiler-runtime-lib.md @@ -0,0 +1,5 @@ +# `profiler_runtime_lib` + +This feature is internal to the Rust compiler and is not intended for general use. + +------------------------ diff --git a/src/libprofiler_builtins/Cargo.toml b/src/libprofiler_builtins/Cargo.toml new file mode 100644 index 0000000000000..dbbc168e7ea35 --- /dev/null +++ b/src/libprofiler_builtins/Cargo.toml @@ -0,0 +1,18 @@ +[package] +authors = ["The Rust Project Developers"] +build = "build.rs" +name = "profiler_builtins" +version = "0.0.0" + +[lib] +name = "profiler_builtins" +path = "lib.rs" +test = false +bench = false +doc = false + +[dependencies] +core = { path = "../libcore" } + +[build-dependencies] +gcc = "0.3.27" diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs new file mode 100644 index 0000000000000..a9685ca7e1aa6 --- /dev/null +++ b/src/libprofiler_builtins/build.rs @@ -0,0 +1,56 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Compiles the profiler part of the `compiler-rt` library. +//! +//! See the build.rs for libcompiler_builtins crate for details. + +extern crate gcc; + +use std::env; +use std::path::Path; + +fn main() { + let target = env::var("TARGET").expect("TARGET was not set"); + let cfg = &mut gcc::Config::new(); + + if target.contains("msvc") { + // Don't pull in extra libraries on MSVC + cfg.flag("/Zl"); + } else { + // Turn off various features of gcc and such, mostly copying + // compiler-rt's build system already + cfg.flag("-fno-builtin"); + cfg.flag("-fvisibility=hidden"); + cfg.flag("-fomit-frame-pointer"); + cfg.flag("-ffreestanding"); + cfg.define("VISIBILITY_HIDDEN", None); + } + + let profile_sources = &["GCDAProfiling.c", + "InstrProfiling.c", + "InstrProfilingBuffer.c", + "InstrProfilingFile.c", + "InstrProfilingMerge.c", + "InstrProfilingMergeFile.c", + "InstrProfilingPlatformDarwin.c", + "InstrProfilingPlatformLinux.c", + "InstrProfilingPlatformOther.c", + "InstrProfilingRuntime.cc", + "InstrProfilingUtil.c", + "InstrProfilingValue.c", + "InstrProfilingWriter.c"]; + + for src in profile_sources { + cfg.file(Path::new("../compiler-rt/lib/profile").join(src)); + } + + cfg.compile("libprofiler-rt.a"); +} diff --git a/src/libprofiler_builtins/lib.rs b/src/libprofiler_builtins/lib.rs new file mode 100644 index 0000000000000..087cc444185b8 --- /dev/null +++ b/src/libprofiler_builtins/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![no_std] +#![cfg_attr(not(stage0), feature(profiler_runtime))] +#![cfg_attr(not(stage0), profiler_runtime)] +#![unstable(feature = "profiler_runtime_lib", + reason = "internal implementation detail of rustc right now", + issue = "0")] +#![crate_name = "profiler_builtins"] +#![crate_type = "rlib"] +#![allow(unused_features)] +#![feature(staged_api)] diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 0b43e65ddbf82..23d670b0f8a8c 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -220,6 +220,7 @@ pub trait CrateStore { fn is_panic_runtime(&self, cnum: CrateNum) -> bool; fn is_compiler_builtins(&self, cnum: CrateNum) -> bool; fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool; + fn is_profiler_runtime(&self, cnum: CrateNum) -> bool; fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy; fn extern_crate(&self, cnum: CrateNum) -> Option; /// The name of the crate as it is referred to in source code of the current @@ -356,6 +357,7 @@ impl CrateStore for DummyCrateStore { fn is_allocator(&self, cnum: CrateNum) -> bool { bug!("is_allocator") } fn is_panic_runtime(&self, cnum: CrateNum) -> bool { bug!("is_panic_runtime") } fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") } + fn is_profiler_runtime(&self, cnum: CrateNum) -> bool { bug!("is_profiler_runtime") } fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool { bug!("is_sanitizer_runtime") } fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy { bug!("panic_strategy") diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 0bb4cd69e0cd1..bf46a7bef2f9c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1025,6 +1025,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "add a source pattern to the file path remapping config"), remap_path_prefix_to: Vec = (vec![], parse_string_push, [TRACKED], "add a mapping target to the file path remapping config"), + profile: bool = (false, parse_bool, [TRACKED], + "insert profiling code"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index dab2a0758a217..900eb127711b9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -203,7 +203,8 @@ pub fn compile_input(sess: &Session, println!("Pre-trans"); tcx.print_debug_stats(); } - let trans = phase_4_translate_to_llvm(tcx, analysis, &incremental_hashes_map); + let trans = phase_4_translate_to_llvm(tcx, analysis, &incremental_hashes_map, + &outputs); if log_enabled!(::log::LogLevel::Info) { println!("Post-trans"); @@ -1029,7 +1030,8 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, /// be discarded. pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, analysis: ty::CrateAnalysis, - incremental_hashes_map: &IncrementalHashesMap) + incremental_hashes_map: &IncrementalHashesMap, + output_filenames: &OutputFilenames) -> trans::CrateTranslation { let time_passes = tcx.sess.time_passes(); @@ -1077,7 +1079,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let translation = time(time_passes, "translation", - move || trans::trans_crate(tcx, analysis, &incremental_hashes_map)); + move || trans::trans_crate(tcx, analysis, &incremental_hashes_map, output_filenames)); time(time_passes, "assert dep graph", diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 402166cc13fd9..a70e6e3cf13ff 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -587,7 +587,9 @@ extern "C" { pub fn LLVMIsUndef(Val: ValueRef) -> Bool; // Operations on metadata + pub fn LLVMMDStringInContext(C: ContextRef, Str: *const c_char, SLen: c_uint) -> ValueRef; pub fn LLVMMDNodeInContext(C: ContextRef, Vals: *const ValueRef, Count: c_uint) -> ValueRef; + pub fn LLVMAddNamedMetadataOperand(M: ModuleRef, Name: *const c_char, Val: ValueRef); // Operations on scalar constants pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) -> ValueRef; @@ -1328,6 +1330,8 @@ extern "C" { pub fn LLVMRustAddModuleFlag(M: ModuleRef, name: *const c_char, value: u32); + pub fn LLVMRustMetadataAsValue(C: ContextRef, MD: MetadataRef) -> ValueRef; + pub fn LLVMRustDIBuilderCreate(M: ModuleRef) -> DIBuilderRef; pub fn LLVMRustDIBuilderDispose(Builder: DIBuilderRef); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 966e814e33790..b4aad1abcd1d3 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -870,6 +870,33 @@ impl<'a> CrateLoader<'a> { } } + fn inject_profiler_runtime(&mut self) { + if self.sess.opts.debugging_opts.profile { + let mut uses_std = false; + self.cstore.iter_crate_data(|_, data| { + if data.name == "std" { + uses_std = true; + } + }); + + if uses_std { + info!("loading profiler"); + + let symbol = Symbol::intern("profiler_builtins"); + let dep_kind = DepKind::Implicit; + let (_, data) = + self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP, + PathKind::Crate, dep_kind); + + // Sanity check the loaded crate to ensure it is indeed a profiler runtime + if !data.is_profiler_runtime() { + self.sess.err(&format!("the crate `profiler_builtins` is not \ + a profiler runtime")); + } + } + } + } + fn inject_allocator_crate(&mut self) { // Make sure that we actually need an allocator, if none of our // dependencies need one then we definitely don't! @@ -1071,6 +1098,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { // inject the sanitizer runtime before the allocator runtime because all // sanitizers force the use of the `alloc_system` allocator self.inject_sanitizer_runtime(); + self.inject_profiler_runtime(); self.inject_allocator_crate(); self.inject_panic_runtime(krate); diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 72ad1d75a5615..577400d95bee9 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -308,6 +308,11 @@ impl CrateMetadata { attr::contains_name(&attrs, "sanitizer_runtime") } + pub fn is_profiler_runtime(&self) -> bool { + let attrs = self.get_item_attrs(CRATE_DEF_INDEX); + attr::contains_name(&attrs, "profiler_runtime") + } + pub fn is_no_builtins(&self) -> bool { let attrs = self.get_item_attrs(CRATE_DEF_INDEX); attr::contains_name(&attrs, "no_builtins") diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 36b993aad69bb..d11dbe3e8b85f 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -275,6 +275,10 @@ impl CrateStore for cstore::CStore { self.get_crate_data(cnum).is_sanitizer_runtime() } + fn is_profiler_runtime(&self, cnum: CrateNum) -> bool { + self.get_crate_data(cnum).is_profiler_runtime() + } + fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy { self.get_crate_data(cnum).panic_strategy() } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index e42e69d2a76e2..7c53ea92581c8 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1074,6 +1074,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker, // symbols from the dylib. let src = sess.cstore.used_crate_source(cnum); match data[cnum.as_usize() - 1] { + _ if sess.cstore.is_profiler_runtime(cnum) => { + add_static_crate(cmd, sess, tmpdir, crate_type, cnum); + } _ if sess.cstore.is_sanitizer_runtime(cnum) => { link_sanitizer_runtime(cmd, sess, tmpdir, cnum); } diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index ccb3f7ac882aa..26f7488b18ea4 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -699,6 +699,10 @@ pub fn run_passes(sess: &Session, } } + if sess.opts.debugging_opts.profile { + modules_config.passes.push("insert-gcov-profiling".to_owned()) + } + modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize)); modules_config.opt_size = Some(get_llvm_opt_size(sess.opts.optimize)); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 56ff5ebb069ea..34f1db0e42fc9 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -42,7 +42,7 @@ use rustc::dep_graph::AssertDepGraphSafe; use rustc::middle::cstore::LinkMeta; use rustc::hir::map as hir_map; use rustc::util::common::time; -use session::config::{self, NoDebugInfo}; +use session::config::{self, NoDebugInfo, OutputFilenames}; use rustc_incremental::IncrementalHashesMap; use session::{self, DataTypeKind, Session}; use abi; @@ -1053,7 +1053,8 @@ pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet { pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, analysis: ty::CrateAnalysis, - incremental_hashes_map: &IncrementalHashesMap) + incremental_hashes_map: &IncrementalHashesMap, + output_filenames: &OutputFilenames) -> CrateTranslation { // Be careful with this krate: obviously it gives access to the // entire contents of the krate. So if you push any subtasks of @@ -1070,7 +1071,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let shared_ccx = SharedCrateContext::new(tcx, exported_symbols, - check_overflow); + check_overflow, + output_filenames); // Translate the metadata. let (metadata_llcx, metadata_llmod, metadata) = time(tcx.sess.time_passes(), "write metadata", || { diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 90cda2f5cad3d..dfc961555518d 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -27,6 +27,7 @@ use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::{LayoutTyper, TyLayout}; use session::config::NoDebugInfo; +use session::config::OutputFilenames; use session::Session; use session::config; use util::nodemap::{NodeSet, DefIdMap, FxHashMap}; @@ -83,6 +84,8 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> { check_overflow: bool, use_dll_storage_attrs: bool, + + output_filenames: &'a OutputFilenames, } /// The local portion of a `CrateContext`. There is one `LocalCrateContext` @@ -266,7 +269,8 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>, exported_symbols: NodeSet, - check_overflow: bool) + check_overflow: bool, + output_filenames: &'b OutputFilenames) -> SharedCrateContext<'b, 'tcx> { // An interesting part of Windows which MSVC forces our hand on (and // apparently MinGW didn't) is the usage of `dllimport` and `dllexport` @@ -319,6 +323,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { tcx: tcx, check_overflow: check_overflow, use_dll_storage_attrs: use_dll_storage_attrs, + output_filenames: output_filenames, } } @@ -353,6 +358,10 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { pub fn use_dll_storage_attrs(&self) -> bool { self.use_dll_storage_attrs } + + pub fn output_filenames(&self) -> &OutputFilenames { + self.output_filenames + } } impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> { diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 188f8ee336637..310c07662b3e5 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -39,10 +39,12 @@ use rustc::ty::{self, AdtKind, Ty}; use rustc::ty::layout::{self, LayoutTyper}; use session::config; use util::nodemap::FxHashMap; +use rustc::util::common::path2cstr; use libc::{c_uint, c_longlong}; use std::ffi::CString; use std::ptr; +use std::path::Path; use syntax::ast; use syntax::symbol::{Interner, InternedString, Symbol}; use syntax_pos::{self, Span}; @@ -788,7 +790,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext, let file_metadata = llvm::LLVMRustDIBuilderCreateFile( debug_context.builder, compile_unit_name, work_dir.as_ptr()); - return llvm::LLVMRustDIBuilderCreateCompileUnit( + let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit( debug_context.builder, DW_LANG_RUST, file_metadata, @@ -796,12 +798,46 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext, sess.opts.optimize != config::OptLevel::No, flags.as_ptr() as *const _, 0, - split_name.as_ptr() as *const _) + split_name.as_ptr() as *const _); + + let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext, + unit_metadata); + + let gcov_cu_info = [ + // Ideally we would be using the three-element form of !llvm.gcov metadata, + // which allows us to specify gcno/gcda files explicitly, but that's only + // available in LLVM 3.9+; so we rely on LLVM chopping off the extension + // and replacing it with gcno/gcda, instead. + path_to_mdstring(debug_context.llcontext, + &scc.output_filenames().with_extension("gcno")), + // path_to_mdstring(debug_context.llcontext, + // &scc.output_filenames().with_extension("gcda")), + cu_desc_metadata, + ]; + let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext, + gcov_cu_info.as_ptr(), + gcov_cu_info.len() as c_uint); + + let llvm_gcov_ident = CString::new("llvm.gcov").unwrap(); + llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, + llvm_gcov_ident.as_ptr(), + gcov_metadata); + + return unit_metadata; }; fn fallback_path(scc: &SharedCrateContext) -> CString { CString::new(scc.tcx().crate_name(LOCAL_CRATE).to_string()).unwrap() } + + fn path_to_mdstring(llcx: llvm::ContextRef, path: &Path) -> llvm::ValueRef { + let path_str = path2cstr(path); + unsafe { + llvm::LLVMMDStringInContext(llcx, + path_str.as_ptr(), + path_str.as_bytes().len() as c_uint) + } + } } struct MetadataCreationResult { diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index ebe42a2b9082d..b78cb4071e5ab 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -67,6 +67,7 @@ const DW_TAG_arg_variable: c_uint = 0x101; /// A context object for maintaining all state needed by the debuginfo module. pub struct CrateDebugContext<'tcx> { llcontext: ContextRef, + llmod: ModuleRef, builder: DIBuilderRef, created_files: RefCell>, created_enum_disr_types: RefCell>, @@ -87,6 +88,7 @@ impl<'tcx> CrateDebugContext<'tcx> { let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; CrateDebugContext { llcontext: llcontext, + llmod: llmod, builder: builder, created_files: RefCell::new(FxHashMap()), created_enum_disr_types: RefCell::new(FxHashMap()), diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 717892be2abad..f268214e5d16f 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -20,6 +20,7 @@ core = { path = "../libcore" } libc = { path = "../rustc/libc_shim" } rand = { path = "../librand" } compiler_builtins = { path = "../libcompiler_builtins" } +profiler_builtins = { path = "../libprofiler_builtins", optional = true } std_unicode = { path = "../libstd_unicode" } unwind = { path = "../libunwind" } @@ -43,3 +44,4 @@ debug-jemalloc = ["alloc_jemalloc/debug"] jemalloc = ["alloc_jemalloc"] force_alloc_system = [] panic-unwind = ["panic_unwind"] +profiler = ["profiler_builtins"] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b6a2c983fd4d7..9101cf7e98bff 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -331,6 +331,10 @@ declare_features! ( // rustc internal (active, sanitizer_runtime, "1.17.0", None), + // Used to identify crates that contain the profiler runtime + // rustc internal + (active, profiler_runtime, "1.18.0", None), + // `extern "x86-interrupt" fn()` (active, abi_x86_interrupt, "1.17.0", Some(40180)), @@ -693,6 +697,13 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG identify crates that contain the runtime of a \ sanitizer and will never be stable", cfg_fn!(sanitizer_runtime))), + ("profiler_runtime", Whitelisted, Gated(Stability::Unstable, + "profiler_runtime", + "the `#[profiler_runtime]` attribute is used to \ + identify the `profiler_builtins` crate which \ + contains the profiler runtime and will never be \ + stable", + cfg_fn!(profiler_runtime))), ("allow_internal_unstable", Normal, Gated(Stability::Unstable, "allow_internal_unstable", diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index c24867224ea86..0a485632bb3db 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -466,6 +466,10 @@ extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name, unwrap(M)->addModuleFlag(Module::Warning, Name, Value); } +extern "C" void LLVMRustMetadataAsValue(LLVMContextRef C, LLVMRustMetadataRef MD) { + wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD))); +} + extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) { return new DIBuilder(*unwrap(M)); } diff --git a/src/test/compile-fail/feature-gate-profiler-runtime.rs b/src/test/compile-fail/feature-gate-profiler-runtime.rs new file mode 100644 index 0000000000000..c6b2cb2eb0772 --- /dev/null +++ b/src/test/compile-fail/feature-gate-profiler-runtime.rs @@ -0,0 +1,13 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![profiler_runtime] //~ ERROR the `#[profiler_runtime]` attribute is + +fn main() {} diff --git a/src/test/run-make/profile/Makefile b/src/test/run-make/profile/Makefile new file mode 100644 index 0000000000000..94a2a30869b5e --- /dev/null +++ b/src/test/run-make/profile/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: + $(RUSTC) -g -Z profile test.rs + $(call RUN,test) || exit 1 + [ -e "$(TMPDIR)/test.gcno" ] || (echo "No .gcno file"; exit 1) + [ -e "$(TMPDIR)/test.gcda" ] || (echo "No .gcda file"; exit 1) diff --git a/src/test/run-make/profile/test.rs b/src/test/run-make/profile/test.rs new file mode 100644 index 0000000000000..046d27a9f0fe5 --- /dev/null +++ b/src/test/run-make/profile/test.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() {} From 60524c55e9150892913272737b77bbcc2fd29a02 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Sun, 4 Jun 2017 17:12:47 +0100 Subject: [PATCH 02/16] Stop checking uses_std --- src/librustc_metadata/creader.rs | 33 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 5d1462c502ae4..45633e995502d 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -908,27 +908,18 @@ impl<'a> CrateLoader<'a> { fn inject_profiler_runtime(&mut self) { if self.sess.opts.debugging_opts.profile { - let mut uses_std = false; - self.cstore.iter_crate_data(|_, data| { - if data.name == "std" { - uses_std = true; - } - }); - - if uses_std { - info!("loading profiler"); - - let symbol = Symbol::intern("profiler_builtins"); - let dep_kind = DepKind::Implicit; - let (_, data) = - self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP, - PathKind::Crate, dep_kind); - - // Sanity check the loaded crate to ensure it is indeed a profiler runtime - if !data.is_profiler_runtime(&self.sess.dep_graph) { - self.sess.err(&format!("the crate `profiler_builtins` is not \ - a profiler runtime")); - } + info!("loading profiler"); + + let symbol = Symbol::intern("profiler_builtins"); + let dep_kind = DepKind::Implicit; + let (_, data) = + self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP, + PathKind::Crate, dep_kind); + + // Sanity check the loaded crate to ensure it is indeed a profiler runtime + if !data.is_profiler_runtime(&self.sess.dep_graph) { + self.sess.err(&format!("the crate `profiler_builtins` is not \ + a profiler runtime")); } } } From a1ca5f689fbb36ab6f691446390ec80a90a0556a Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Sun, 4 Jun 2017 17:50:25 +0100 Subject: [PATCH 03/16] Add llvm.gcov metadata only if profiler is enabled --- src/librustc_trans/debuginfo/metadata.rs | 46 ++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index d9b99e0eb6831..32fd2bac85f4c 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -806,28 +806,30 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext, 0, split_name.as_ptr() as *const _); - let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext, - unit_metadata); - - let gcov_cu_info = [ - // Ideally we would be using the three-element form of !llvm.gcov metadata, - // which allows us to specify gcno/gcda files explicitly, but that's only - // available in LLVM 3.9+; so we rely on LLVM chopping off the extension - // and replacing it with gcno/gcda, instead. - path_to_mdstring(debug_context.llcontext, - &scc.output_filenames().with_extension("gcno")), - // path_to_mdstring(debug_context.llcontext, - // &scc.output_filenames().with_extension("gcda")), - cu_desc_metadata, - ]; - let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext, - gcov_cu_info.as_ptr(), - gcov_cu_info.len() as c_uint); - - let llvm_gcov_ident = CString::new("llvm.gcov").unwrap(); - llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, - llvm_gcov_ident.as_ptr(), - gcov_metadata); + if sess.opts.debugging_opts.profile { + let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext, + unit_metadata); + + let gcov_cu_info = [ + // Ideally we would be using the three-element form of !llvm.gcov metadata, + // which allows us to specify gcno/gcda files explicitly, but that's only + // available in LLVM 3.9+; so we rely on LLVM chopping off the extension + // and replacing it with gcno/gcda, instead. + path_to_mdstring(debug_context.llcontext, + &scc.output_filenames().with_extension("gcno")), + // path_to_mdstring(debug_context.llcontext, + // &scc.output_filenames().with_extension("gcda")), + cu_desc_metadata, + ]; + let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext, + gcov_cu_info.as_ptr(), + gcov_cu_info.len() as c_uint); + + let llvm_gcov_ident = CString::new("llvm.gcov").unwrap(); + llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, + llvm_gcov_ident.as_ptr(), + gcov_metadata); + } return unit_metadata; }; From 0b0a5ac032d121f89bae2e9906d70be771e39887 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Sun, 4 Jun 2017 19:05:03 +0100 Subject: [PATCH 04/16] Run profiler test only if built with profiler support --- src/test/run-make/profile/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/run-make/profile/Makefile b/src/test/run-make/profile/Makefile index 94a2a30869b5e..7300bfc955363 100644 --- a/src/test/run-make/profile/Makefile +++ b/src/test/run-make/profile/Makefile @@ -1,7 +1,9 @@ -include ../tools.mk all: +ifeq ($(PROFILER_SUPPORT),1) $(RUSTC) -g -Z profile test.rs $(call RUN,test) || exit 1 [ -e "$(TMPDIR)/test.gcno" ] || (echo "No .gcno file"; exit 1) [ -e "$(TMPDIR)/test.gcda" ] || (echo "No .gcda file"; exit 1) +endif From 8b7826ffb9b7fad61591421f58c1ddc3a2bdaf6e Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Sun, 4 Jun 2017 19:53:42 +0100 Subject: [PATCH 05/16] Use the three-element variant of the 'llvm.gcov' metadata --- src/librustc_trans/debuginfo/metadata.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 32fd2bac85f4c..95ceec610eaa3 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -811,14 +811,10 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext, unit_metadata); let gcov_cu_info = [ - // Ideally we would be using the three-element form of !llvm.gcov metadata, - // which allows us to specify gcno/gcda files explicitly, but that's only - // available in LLVM 3.9+; so we rely on LLVM chopping off the extension - // and replacing it with gcno/gcda, instead. path_to_mdstring(debug_context.llcontext, &scc.output_filenames().with_extension("gcno")), - // path_to_mdstring(debug_context.llcontext, - // &scc.output_filenames().with_extension("gcda")), + path_to_mdstring(debug_context.llcontext, + &scc.output_filenames().with_extension("gcda")), cu_desc_metadata, ]; let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext, From 26ad8d4ad304a4aaaeab4bbc51ed5cbd733d13ba Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Mon, 5 Jun 2017 23:56:59 +0100 Subject: [PATCH 06/16] Enable profiler on all builders --- src/ci/run.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ci/run.sh b/src/ci/run.sh index 549e804603c07..7885a5b22434e 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -32,6 +32,7 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-openssl-static" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-clean-rebuild" +RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-profiling" if [ "$DIST_SRC" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src" From 84d1626e517346e2a603788b8026c17e754f4144 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Tue, 6 Jun 2017 00:39:07 +0100 Subject: [PATCH 07/16] Add basic documentation for the profile feature --- .../unstable-book/src/compiler-flags/profile.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md index f9634c55c96e9..1c4ae5207ff52 100644 --- a/src/doc/unstable-book/src/compiler-flags/profile.md +++ b/src/doc/unstable-book/src/compiler-flags/profile.md @@ -3,3 +3,19 @@ The tracking issue for this feature is: None ------------------------ + +This feature allows the generation of code coverage reports. + +Set the compiler flags `-Ccodegen-units=1 -Clink-dead-code -Cpasses=insert-gcov-profiling -Zno-landing-pads` to enable gcov profiling. + +For example: +```Bash +cargo new testgcov --bin +cd testgcov +export RUSTFLAGS="-Ccodegen-units=1 -Clink-dead-code -Cpasses=insert-gcov-profiling -Zno-landing-pads" +cargo build +cargo run +``` + +Once you've built and run your program, files with the `gcno` (after build) and `gcda` (after execution) extensions will be created. +You can parse them with [llvm-cov gcov](http://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](https://github.com/marco-c/grcov). From 13b3c34e4bf38ad6e6f0453ab84029faf5dd5058 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Tue, 6 Jun 2017 00:42:09 +0100 Subject: [PATCH 08/16] Spell profiler option correctly... --- src/ci/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index 7885a5b22434e..763d6684463c2 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -32,7 +32,7 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-openssl-static" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-clean-rebuild" -RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-profiling" +RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-profiler" if [ "$DIST_SRC" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src" From 95c6fc49441d5387c5495da4eb7b40537c218c1a Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Tue, 6 Jun 2017 11:10:34 +0100 Subject: [PATCH 09/16] Suggest 'profile' flag --- src/doc/unstable-book/src/compiler-flags/profile.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md index 1c4ae5207ff52..3b4f34e67c53b 100644 --- a/src/doc/unstable-book/src/compiler-flags/profile.md +++ b/src/doc/unstable-book/src/compiler-flags/profile.md @@ -6,13 +6,13 @@ The tracking issue for this feature is: None This feature allows the generation of code coverage reports. -Set the compiler flags `-Ccodegen-units=1 -Clink-dead-code -Cpasses=insert-gcov-profiling -Zno-landing-pads` to enable gcov profiling. +Set the `-Zprofile` compiler flag in order to enable gcov profiling. For example: ```Bash cargo new testgcov --bin cd testgcov -export RUSTFLAGS="-Ccodegen-units=1 -Clink-dead-code -Cpasses=insert-gcov-profiling -Zno-landing-pads" +export RUSTFLAGS="-Zprofile" cargo build cargo run ``` From 4c908a9d37d1ed173e4226c3b71e9f05b7260c39 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Tue, 6 Jun 2017 18:09:33 +0100 Subject: [PATCH 10/16] Enable profiler selectively on some builders --- .travis.yml | 6 +++--- appveyor.yml | 8 +++++--- src/ci/docker/dist-i686-linux/Dockerfile | 3 ++- src/ci/docker/dist-x86_64-linux/Dockerfile | 3 ++- src/ci/docker/x86_64-gnu/Dockerfile | 2 +- src/ci/run.sh | 1 - 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9ef759b3f80ae..cf7134f873a5e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,7 +54,7 @@ matrix: # version that we're using, 8.2, cannot compile LLVM for OSX 10.7. - env: > RUST_CHECK_TARGET=check - RUST_CONFIGURE_ARGS="--build=x86_64-apple-darwin --enable-sanitizers" + RUST_CONFIGURE_ARGS="--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler" SRC=. RUSTC_RETRY_LINKER_ON_SEGFAULT=1 SCCACHE_ERROR_LOG=/tmp/sccache.log @@ -87,7 +87,7 @@ matrix: # OSX 10.7 and `xcode7` is the latest Xcode able to compile LLVM for 10.7. - env: > RUST_CHECK_TARGET=dist - RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-extended" + RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-extended --enable-profiler" SRC=. DEPLOY=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1 @@ -101,7 +101,7 @@ matrix: - *osx_install_sccache - env: > RUST_CHECK_TARGET=dist - RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended --enable-sanitizers" + RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended --enable-sanitizers --enable-profiler" SRC=. DEPLOY=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1 diff --git a/appveyor.yml b/appveyor.yml index 96de1d90f25e6..d4f805de5de3f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ environment: matrix: # 32/64 bit MSVC tests - MSYS_BITS: 64 - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler SCRIPT: python x.py test - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc --target=i586-pc-windows-msvc @@ -48,16 +48,18 @@ environment: - RUST_CONFIGURE_ARGS: > --build=x86_64-pc-windows-msvc --enable-extended + --enable-profiler SCRIPT: python x.py dist DEPLOY: 1 - RUST_CONFIGURE_ARGS: > --build=i686-pc-windows-msvc --target=i586-pc-windows-msvc --enable-extended + --enable-profiler SCRIPT: python x.py dist DEPLOY: 1 - MSYS_BITS: 32 - RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-extended + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-extended --enable-profiler SCRIPT: python x.py dist MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z @@ -65,7 +67,7 @@ environment: DEPLOY: 1 - MSYS_BITS: 64 SCRIPT: python x.py dist - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-extended + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-extended --enable-profiler MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 diff --git a/src/ci/docker/dist-i686-linux/Dockerfile b/src/ci/docker/dist-i686-linux/Dockerfile index a3c08e93ed158..9145e9dfc8d1a 100644 --- a/src/ci/docker/dist-i686-linux/Dockerfile +++ b/src/ci/docker/dist-i686-linux/Dockerfile @@ -90,7 +90,8 @@ ENV HOSTS=i686-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ --host=$HOSTS \ --enable-extended \ - --enable-sanitizers + --enable-sanitizers \ + --enable-profiler ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS # This is the only builder which will create source tarballs diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile index e2e42836dcdaf..78b62839a35d5 100644 --- a/src/ci/docker/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/dist-x86_64-linux/Dockerfile @@ -90,7 +90,8 @@ ENV HOSTS=x86_64-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ --host=$HOSTS \ --enable-extended \ - --enable-sanitizers + --enable-sanitizers \ + --enable-profiler ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS # This is the only builder which will create source tarballs diff --git a/src/ci/docker/x86_64-gnu/Dockerfile b/src/ci/docker/x86_64-gnu/Dockerfile index de85e1ff36af8..0bbbded57f27d 100644 --- a/src/ci/docker/x86_64-gnu/Dockerfile +++ b/src/ci/docker/x86_64-gnu/Dockerfile @@ -22,5 +22,5 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini rm dumb-init_*.deb ENTRYPOINT ["/usr/bin/dumb-init", "--"] -ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --enable-sanitizers +ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --enable-sanitizers --enable-profiler ENV SCRIPT python2.7 ../x.py test diff --git a/src/ci/run.sh b/src/ci/run.sh index 763d6684463c2..549e804603c07 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -32,7 +32,6 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-openssl-static" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-clean-rebuild" -RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-profiler" if [ "$DIST_SRC" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src" From ce56daf37b7b5b101db7ef895e6be4586d80d08e Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Wed, 7 Jun 2017 12:50:50 +0100 Subject: [PATCH 11/16] Don't enable profiler on MinGW targets, as compiler-rt can't currently be compiled with MinGW --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d4f805de5de3f..4711f34f830e6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -59,7 +59,7 @@ environment: SCRIPT: python x.py dist DEPLOY: 1 - MSYS_BITS: 32 - RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-extended --enable-profiler + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-extended SCRIPT: python x.py dist MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z @@ -67,7 +67,7 @@ environment: DEPLOY: 1 - MSYS_BITS: 64 SCRIPT: python x.py dist - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-extended --enable-profiler + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-extended MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 From 900ba559b637b6d99bc95e6f0d270543713096fd Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Mon, 12 Jun 2017 23:08:08 +0100 Subject: [PATCH 12/16] Compile WindowsMMap too on MSVC --- src/libprofiler_builtins/build.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index a9685ca7e1aa6..4397d2ebb21e6 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -21,9 +21,24 @@ fn main() { let target = env::var("TARGET").expect("TARGET was not set"); let cfg = &mut gcc::Config::new(); + let mut profile_sources = vec!["GCDAProfiling.c", + "InstrProfiling.c", + "InstrProfilingBuffer.c", + "InstrProfilingFile.c", + "InstrProfilingMerge.c", + "InstrProfilingMergeFile.c", + "InstrProfilingPlatformDarwin.c", + "InstrProfilingPlatformLinux.c", + "InstrProfilingPlatformOther.c", + "InstrProfilingRuntime.cc", + "InstrProfilingUtil.c", + "InstrProfilingValue.c", + "InstrProfilingWriter.c"]; + if target.contains("msvc") { // Don't pull in extra libraries on MSVC cfg.flag("/Zl"); + profile_sources.push("WindowsMMap.c"); } else { // Turn off various features of gcc and such, mostly copying // compiler-rt's build system already @@ -34,20 +49,6 @@ fn main() { cfg.define("VISIBILITY_HIDDEN", None); } - let profile_sources = &["GCDAProfiling.c", - "InstrProfiling.c", - "InstrProfilingBuffer.c", - "InstrProfilingFile.c", - "InstrProfilingMerge.c", - "InstrProfilingMergeFile.c", - "InstrProfilingPlatformDarwin.c", - "InstrProfilingPlatformLinux.c", - "InstrProfilingPlatformOther.c", - "InstrProfilingRuntime.cc", - "InstrProfilingUtil.c", - "InstrProfilingValue.c", - "InstrProfilingWriter.c"]; - for src in profile_sources { cfg.file(Path::new("../compiler-rt/lib/profile").join(src)); } From 8748bdd353e7d8744fdbb3c1c1b2e6c7f424b065 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Mon, 12 Jun 2017 23:08:57 +0100 Subject: [PATCH 13/16] Redefine strdup, open, fdopen as _strdup, _open, _fdopen to avoid linking errors on MSVC --- src/libprofiler_builtins/build.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index 4397d2ebb21e6..1ee284ff4dabf 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -39,6 +39,9 @@ fn main() { // Don't pull in extra libraries on MSVC cfg.flag("/Zl"); profile_sources.push("WindowsMMap.c"); + cfg.define("strdup", Some("_strdup")); + cfg.define("open", Some("_open")); + cfg.define("fdopen", Some("_fdopen")); } else { // Turn off various features of gcc and such, mostly copying // compiler-rt's build system already From d7039fb2b95d5b1976bb18818347e460832f42bf Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Mon, 12 Jun 2017 23:10:28 +0100 Subject: [PATCH 14/16] Fill in tracking issue for the profile feature --- src/doc/unstable-book/src/compiler-flags/profile.md | 2 +- src/doc/unstable-book/src/language-features/profiler-runtime.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md index 3b4f34e67c53b..66d14fd09978f 100644 --- a/src/doc/unstable-book/src/compiler-flags/profile.md +++ b/src/doc/unstable-book/src/compiler-flags/profile.md @@ -1,6 +1,6 @@ # `profile` -The tracking issue for this feature is: None +The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524). ------------------------ diff --git a/src/doc/unstable-book/src/language-features/profiler-runtime.md b/src/doc/unstable-book/src/language-features/profiler-runtime.md index a9879c8d5a650..aee86f63952a5 100644 --- a/src/doc/unstable-book/src/language-features/profiler-runtime.md +++ b/src/doc/unstable-book/src/language-features/profiler-runtime.md @@ -1,5 +1,5 @@ # `profiler_runtime` -The tracking issue for this feature is: None. +The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524). ------------------------ From dba9f84dc464e6e9ff89cc0882660dc192244b17 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Tue, 13 Jun 2017 20:21:58 +0100 Subject: [PATCH 15/16] Fix gcc version required by libprofiler_builtins --- src/libprofiler_builtins/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libprofiler_builtins/Cargo.toml b/src/libprofiler_builtins/Cargo.toml index dbbc168e7ea35..a60db3136797a 100644 --- a/src/libprofiler_builtins/Cargo.toml +++ b/src/libprofiler_builtins/Cargo.toml @@ -15,4 +15,4 @@ doc = false core = { path = "../libcore" } [build-dependencies] -gcc = "0.3.27" +gcc = "0.3.50" From 5c084fd8edd986d8a4bd9ff37b303f8777623a56 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Tue, 13 Jun 2017 20:22:43 +0100 Subject: [PATCH 16/16] Add libprofiler_builtins to the list of paths for the rust-src component --- src/bootstrap/dist.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 26d44ae7693ad..ebf602373c965 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -570,6 +570,7 @@ pub fn rust_src(build: &Build) { "src/libgetopts", "src/compiler-rt", "src/jemalloc", + "src/libprofiler_builtins", ]; let std_src_dirs_exclude = [ "src/compiler-rt/test",