-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Build instruction profiler runtime as part of compiler-rt #38608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# `profile` | ||
|
||
The tracking issue for this feature is: None | ||
|
||
------------------------ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# `profiler_runtime` | ||
|
||
The tracking issue for this feature is: None. | ||
|
||
------------------------ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# `profiler_runtime_lib` | ||
|
||
This feature is internal to the Rust compiler and is not intended for general use. | ||
|
||
------------------------ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <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. | ||
|
||
//! 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"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <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_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)] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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| { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @japaric can you remind me why this is needed? Naively I'd expect that a crate would require the profiler runtime regardless of whether it links to std or not, but I forget why this clause is above. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I orignially copied that over from compiler_builtins. I think it's useful because a no_std crate may want to supply their own profiler builtins, e.g. to submit the results somewhere in a semihosting implementation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alexcrichton iirc, because the sanitizers only work with But since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah ok. @whitequark perhaps this clause (checking Is it really feasible for someone to write their own profiler builtins? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alexcrichton Sure, I'll remove it. I imagine someone would replace the libc calls in the stock profiler builtins with something else and then link to that, not write them from scratch. I am thinking of doing this for my embedded system work, incidentally. |
||
if data.name == "std" { | ||
uses_std = true; | ||
} | ||
}); | ||
|
||
if uses_std { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mentioned above, we can remove this clause, right? (just execute the code below if |
||
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); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that this is ever read, is it still needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's needed for a test. That's yet to be written.