Skip to content

Commit

Permalink
Support caching Clang invocations with -fprofile-use and -fprofile-in…
Browse files Browse the repository at this point in the history
…str-use.
  • Loading branch information
michaelwoerister committed Feb 11, 2021
1 parent b3f4727 commit 1465cec
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 8 deletions.
41 changes: 40 additions & 1 deletion src/compiler/clang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl CCompilerImpl for Clang {
cwd,
(&gcc::ARGS[..], &ARGS[..]),
self.clangplusplus,
CCompilerKind::Clang,
)
}

Expand Down Expand Up @@ -118,7 +119,7 @@ counted_array!(pub static ARGS: [ArgInfo<gcc::ArgData>; _] = [
take_arg!("-fplugin", PathBuf, CanBeConcatenated('='), ExtraHashFile),
flag!("-fprofile-instr-generate", ProfileGenerate),
// Can be either -fprofile-instr-use or -fprofile-instr-use=path
take_arg!("-fprofile-instr-use", OsString, Concatenated, TooHard),
take_arg!("-fprofile-instr-use", PathBuf, Concatenated('='), ProfileUse),
take_arg!("-fsanitize-blacklist", PathBuf, Concatenated('='), ExtraHashFile),
take_arg!("-gcc-toolchain", OsString, Separated, PassThrough),
take_arg!("-include-pch", PathBuf, CanBeSeparated, PreprocessorArgumentPath),
Expand Down Expand Up @@ -403,4 +404,42 @@ mod test {
let a = parses!("-c", "foo.c", "-o", "foo.o");
assert_eq!(a.color_mode, ColorMode::Auto);
}

#[test]
fn test_parse_arguments_profile_instr_use() {
let a = parses!(
"-c",
"foo.c",
"-o",
"foo.o",
"-fprofile-instr-use=foo.profdata"
);
assert_eq!(ovec!["-fprofile-instr-use=foo.profdata"], a.common_args);
assert_eq!(
ovec![std::env::current_dir().unwrap().join("foo.profdata")],
a.extra_hash_files
);
}

#[test]
fn test_parse_arguments_profile_use() {
let a = parses!("-c", "foo.c", "-o", "foo.o", "-fprofile-use=xyz.profdata");

assert_eq!(ovec!["-fprofile-use=xyz.profdata"], a.common_args);
assert_eq!(
ovec![std::env::current_dir().unwrap().join("xyz.profdata")],
a.extra_hash_files
);
}

#[test]
fn test_parse_arguments_profile_use_with_directory() {
let a = parses!("-c", "foo.c", "-o", "foo.o", "-fprofile-use=.");

assert_eq!(ovec!["-fprofile-use=."], a.common_args);
assert_eq!(
ovec![std::env::current_dir().unwrap().join("default.profdata")],
a.extra_hash_files
);
}
}
39 changes: 34 additions & 5 deletions src/compiler/gcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ impl CCompilerImpl for GCC {
arguments: &[OsString],
cwd: &Path,
) -> CompilerArguments<ParsedArguments> {
parse_arguments(arguments, cwd, &ARGS[..], self.gplusplus)
parse_arguments(
arguments,
cwd,
&ARGS[..],
self.gplusplus,
CCompilerKind::GCC,
)
}

fn preprocess<T>(
Expand Down Expand Up @@ -119,6 +125,7 @@ ArgData! { pub
Language(OsString),
SplitDwarf,
ProfileGenerate,
ProfileUse(PathBuf),
TestCoverage,
Coverage,
ExtraHashFile(PathBuf),
Expand Down Expand Up @@ -169,7 +176,7 @@ counted_array!(pub static ARGS: [ArgInfo<ArgData>; _] = [
flag!("-fplugin=libcc1plugin", TooHardFlag),
flag!("-fprofile-arcs", ProfileGenerate),
flag!("-fprofile-generate", ProfileGenerate),
take_arg!("-fprofile-use", OsString, Concatenated, TooHard),
take_arg!("-fprofile-use", PathBuf, Concatenated('='), ProfileUse),
flag!("-frepo", TooHardFlag),
flag!("-fsyntax-only", TooHardFlag),
flag!("-ftest-coverage", TestCoverage),
Expand Down Expand Up @@ -214,6 +221,7 @@ pub fn parse_arguments<S>(
cwd: &Path,
arg_info: S,
plusplus: bool,
compiler_kind: CCompilerKind,
) -> CompilerArguments<ParsedArguments>
where
S: SearchableArgInfo<ArgData>,
Expand Down Expand Up @@ -275,6 +283,11 @@ where
OsString::from(arg.flag_str().expect("Compilation flag expected"));
}
Some(ProfileGenerate) => profile_generate = true,
Some(ProfileUse(_)) => {
if compiler_kind != CCompilerKind::Clang {
cannot_cache!(arg.flag_str().unwrap(), "only Clang supported".into())
}
}
Some(TestCoverage) => outputs_gcno = true,
Some(Coverage) => {
outputs_gcno = true;
Expand Down Expand Up @@ -341,6 +354,20 @@ where
| Some(Arch(_))
| Some(PassThrough(_))
| Some(PassThroughPath(_)) => &mut common_args,
Some(ProfileUse(path)) => {
debug_assert!(compiler_kind == CCompilerKind::Clang);

let mut path = cwd.join(path);

// Clang allows specifying a directory here, in which case it
// will look for the file `default.profdata` in that directory.
if path.is_dir() {
path.push("default.profdata");
}

extra_hash_files.push(path);
&mut common_args
}
Some(ExtraHashFile(path)) => {
extra_hash_files.push(cwd.join(path));
&mut common_args
Expand Down Expand Up @@ -376,6 +403,7 @@ where
let args = match arg.get_data() {
Some(SplitDwarf)
| Some(ProfileGenerate)
| Some(ProfileUse(_))
| Some(TestCoverage)
| Some(Coverage)
| Some(DoCompilation)
Expand Down Expand Up @@ -742,7 +770,7 @@ mod test {
plusplus: bool,
) -> CompilerArguments<ParsedArguments> {
let args = arguments.iter().map(OsString::from).collect::<Vec<_>>();
parse_arguments(&args, ".".as_ref(), &ARGS[..], plusplus)
parse_arguments(&args, ".".as_ref(), &ARGS[..], plusplus, CCompilerKind::GCC)
}

#[test]
Expand Down Expand Up @@ -1204,15 +1232,16 @@ mod test {

#[test]
fn test_parse_arguments_pgo() {
let only_clang_supported = || Some("only Clang supported".to_string());
assert_eq!(
CompilerArguments::CannotCache("-fprofile-use", None),
CompilerArguments::CannotCache("-fprofile-use", only_clang_supported()),
parse_arguments_(
stringvec!["-c", "foo.c", "-fprofile-use", "-o", "foo.o"],
false
)
);
assert_eq!(
CompilerArguments::CannotCache("-fprofile-use", None),
CompilerArguments::CannotCache("-fprofile-use", only_clang_supported()),
parse_arguments_(
stringvec!["-c", "foo.c", "-fprofile-use=file", "-o", "foo.o"],
false
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/msvc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ pub fn parse_arguments(
let mut args = match arg.get_data() {
Some(SplitDwarf) | Some(TestCoverage) | Some(Coverage) | Some(DoCompilation)
| Some(Language(_)) | Some(Output(_)) | Some(TooHardFlag) | Some(XClang(_))
| Some(TooHard(_)) => cannot_cache!(arg
| Some(TooHard(_)) | Some(ProfileUse(_)) => cannot_cache!(arg
.flag_str()
.unwrap_or("Can't handle complex arguments through clang",)),
None => match arg {
Expand All @@ -605,6 +605,7 @@ pub fn parse_arguments(
profile_generate = true;
&mut common_args
}

Some(ExtraHashFile(path)) => {
extra_hash_files.push(cwd.join(path));
&mut common_args
Expand Down
8 changes: 7 additions & 1 deletion src/compiler/nvcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ impl CCompilerImpl for NVCC {
arguments: &[OsString],
cwd: &Path,
) -> CompilerArguments<ParsedArguments> {
gcc::parse_arguments(arguments, cwd, (&gcc::ARGS[..], &ARGS[..]), false)
gcc::parse_arguments(
arguments,
cwd,
(&gcc::ARGS[..], &ARGS[..]),
false,
CCompilerKind::NVCC,
)
}

fn preprocess<T>(
Expand Down

0 comments on commit 1465cec

Please sign in to comment.