Skip to content

Commit 3c5d320

Browse files
Support caching Clang invocations with -fprofile-use and -fprofile-instr-use.
1 parent b3f4727 commit 3c5d320

File tree

4 files changed

+95
-10
lines changed

4 files changed

+95
-10
lines changed

src/compiler/clang.rs

+55-3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ impl CCompilerImpl for Clang {
5454
cwd,
5555
(&gcc::ARGS[..], &ARGS[..]),
5656
self.clangplusplus,
57+
CCompilerKind::Clang,
5758
)
5859
}
5960

@@ -103,7 +104,7 @@ impl CCompilerImpl for Clang {
103104
}
104105
}
105106

106-
counted_array!(pub static ARGS: [ArgInfo<gcc::ArgData>; _] = [
107+
pub static ARGS: &[ArgInfo<gcc::ArgData>] = &[
107108
take_arg!("--serialize-diagnostics", OsString, Separated, PassThrough),
108109
take_arg!("--target", OsString, Separated, PassThrough),
109110
take_arg!("-Xclang", OsString, Separated, XClang),
@@ -118,7 +119,7 @@ counted_array!(pub static ARGS: [ArgInfo<gcc::ArgData>; _] = [
118119
take_arg!("-fplugin", PathBuf, CanBeConcatenated('='), ExtraHashFile),
119120
flag!("-fprofile-instr-generate", ProfileGenerate),
120121
// Can be either -fprofile-instr-use or -fprofile-instr-use=path
121-
take_arg!("-fprofile-instr-use", OsString, Concatenated, TooHard),
122+
take_arg!("-fprofile-instr-use", PathBuf, Concatenated('='), ProfileUse),
122123
take_arg!("-fsanitize-blacklist", PathBuf, Concatenated('='), ExtraHashFile),
123124
take_arg!("-gcc-toolchain", OsString, Separated, PassThrough),
124125
take_arg!("-include-pch", PathBuf, CanBeSeparated, PreprocessorArgumentPath),
@@ -127,7 +128,7 @@ counted_array!(pub static ARGS: [ArgInfo<gcc::ArgData>; _] = [
127128
take_arg!("-plugin-arg", OsString, Concatenated('-'), PassThrough),
128129
take_arg!("-target", OsString, Separated, PassThrough),
129130
flag!("-verify", PreprocessorArgumentFlag),
130-
]);
131+
];
131132

132133
#[cfg(test)]
133134
mod test {
@@ -403,4 +404,55 @@ mod test {
403404
let a = parses!("-c", "foo.c", "-o", "foo.o");
404405
assert_eq!(a.color_mode, ColorMode::Auto);
405406
}
407+
408+
#[test]
409+
fn test_parse_arguments_profile_instr_use() {
410+
let a = parses!(
411+
"-c",
412+
"foo.c",
413+
"-o",
414+
"foo.o",
415+
"-fprofile-instr-use=foo.profdata"
416+
);
417+
assert_eq!(ovec!["-fprofile-instr-use=foo.profdata"], a.common_args);
418+
assert_eq!(
419+
ovec![std::env::current_dir().unwrap().join("foo.profdata")],
420+
a.extra_hash_files
421+
);
422+
}
423+
424+
#[test]
425+
fn test_parse_arguments_profile_use() {
426+
let a = parses!(
427+
"-c",
428+
"foo.c",
429+
"-o",
430+
"foo.o",
431+
"-fprofile-use=xyz.profdata"
432+
);
433+
434+
assert_eq!(ovec!["-fprofile-use=xyz.profdata"], a.common_args);
435+
assert_eq!(
436+
ovec![std::env::current_dir().unwrap().join("xyz.profdata")],
437+
a.extra_hash_files
438+
);
439+
}
440+
441+
#[test]
442+
fn test_parse_arguments_profile_use_with_directory() {
443+
let a = parses!(
444+
"-c",
445+
"foo.c",
446+
"-o",
447+
"foo.o",
448+
"-fprofile-use=."
449+
);
450+
451+
assert_eq!(ovec!["-fprofile-use=."], a.common_args);
452+
assert_eq!(
453+
ovec![std::env::current_dir().unwrap().join("default.profdata")],
454+
a.extra_hash_files
455+
);
456+
}
457+
406458
}

src/compiler/gcc.rs

+31-5
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl CCompilerImpl for GCC {
4646
arguments: &[OsString],
4747
cwd: &Path,
4848
) -> CompilerArguments<ParsedArguments> {
49-
parse_arguments(arguments, cwd, &ARGS[..], self.gplusplus)
49+
parse_arguments(arguments, cwd, &ARGS[..], self.gplusplus, CCompilerKind::GCC)
5050
}
5151

5252
fn preprocess<T>(
@@ -119,6 +119,7 @@ ArgData! { pub
119119
Language(OsString),
120120
SplitDwarf,
121121
ProfileGenerate,
122+
ProfileUse(PathBuf),
122123
TestCoverage,
123124
Coverage,
124125
ExtraHashFile(PathBuf),
@@ -169,7 +170,7 @@ counted_array!(pub static ARGS: [ArgInfo<ArgData>; _] = [
169170
flag!("-fplugin=libcc1plugin", TooHardFlag),
170171
flag!("-fprofile-arcs", ProfileGenerate),
171172
flag!("-fprofile-generate", ProfileGenerate),
172-
take_arg!("-fprofile-use", OsString, Concatenated, TooHard),
173+
take_arg!("-fprofile-use", PathBuf, Concatenated('='), ProfileUse),
173174
flag!("-frepo", TooHardFlag),
174175
flag!("-fsyntax-only", TooHardFlag),
175176
flag!("-ftest-coverage", TestCoverage),
@@ -214,6 +215,7 @@ pub fn parse_arguments<S>(
214215
cwd: &Path,
215216
arg_info: S,
216217
plusplus: bool,
218+
compiler_kind: CCompilerKind,
217219
) -> CompilerArguments<ParsedArguments>
218220
where
219221
S: SearchableArgInfo<ArgData>,
@@ -275,6 +277,14 @@ where
275277
OsString::from(arg.flag_str().expect("Compilation flag expected"));
276278
}
277279
Some(ProfileGenerate) => profile_generate = true,
280+
Some(ProfileUse(_)) => {
281+
if compiler_kind != CCompilerKind::Clang {
282+
cannot_cache!(
283+
arg.flag_str().unwrap(),
284+
"only Clang supported".into()
285+
)
286+
}
287+
},
278288
Some(TestCoverage) => outputs_gcno = true,
279289
Some(Coverage) => {
280290
outputs_gcno = true;
@@ -341,6 +351,20 @@ where
341351
| Some(Arch(_))
342352
| Some(PassThrough(_))
343353
| Some(PassThroughPath(_)) => &mut common_args,
354+
Some(ProfileUse(path)) => {
355+
debug_assert!(compiler_kind == CCompilerKind::Clang);
356+
357+
let mut path = cwd.join(path);
358+
359+
// Clang allows specifying a directory here, in which case it
360+
// will look for the file `default.profdata` in that directory.
361+
if path.is_dir() {
362+
path.push("default.profdata");
363+
}
364+
365+
extra_hash_files.push(path);
366+
&mut common_args
367+
}
344368
Some(ExtraHashFile(path)) => {
345369
extra_hash_files.push(cwd.join(path));
346370
&mut common_args
@@ -376,6 +400,7 @@ where
376400
let args = match arg.get_data() {
377401
Some(SplitDwarf)
378402
| Some(ProfileGenerate)
403+
| Some(ProfileUse(_))
379404
| Some(TestCoverage)
380405
| Some(Coverage)
381406
| Some(DoCompilation)
@@ -742,7 +767,7 @@ mod test {
742767
plusplus: bool,
743768
) -> CompilerArguments<ParsedArguments> {
744769
let args = arguments.iter().map(OsString::from).collect::<Vec<_>>();
745-
parse_arguments(&args, ".".as_ref(), &ARGS[..], plusplus)
770+
parse_arguments(&args, ".".as_ref(), &ARGS[..], plusplus, CCompilerKind::GCC)
746771
}
747772

748773
#[test]
@@ -1204,15 +1229,16 @@ mod test {
12041229

12051230
#[test]
12061231
fn test_parse_arguments_pgo() {
1232+
let only_clang_supported = || Some("only Clang supported".to_string());
12071233
assert_eq!(
1208-
CompilerArguments::CannotCache("-fprofile-use", None),
1234+
CompilerArguments::CannotCache("-fprofile-use", only_clang_supported()),
12091235
parse_arguments_(
12101236
stringvec!["-c", "foo.c", "-fprofile-use", "-o", "foo.o"],
12111237
false
12121238
)
12131239
);
12141240
assert_eq!(
1215-
CompilerArguments::CannotCache("-fprofile-use", None),
1241+
CompilerArguments::CannotCache("-fprofile-use", only_clang_supported()),
12161242
parse_arguments_(
12171243
stringvec!["-c", "foo.c", "-fprofile-use=file", "-o", "foo.o"],
12181244
false

src/compiler/msvc.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ pub fn parse_arguments(
587587
let mut args = match arg.get_data() {
588588
Some(SplitDwarf) | Some(TestCoverage) | Some(Coverage) | Some(DoCompilation)
589589
| Some(Language(_)) | Some(Output(_)) | Some(TooHardFlag) | Some(XClang(_))
590-
| Some(TooHard(_)) => cannot_cache!(arg
590+
| Some(TooHard(_)) | Some(ProfileUse(_)) => cannot_cache!(arg
591591
.flag_str()
592592
.unwrap_or("Can't handle complex arguments through clang",)),
593593
None => match arg {
@@ -605,6 +605,7 @@ pub fn parse_arguments(
605605
profile_generate = true;
606606
&mut common_args
607607
}
608+
608609
Some(ExtraHashFile(path)) => {
609610
extra_hash_files.push(cwd.join(path));
610611
&mut common_args

src/compiler/nvcc.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,13 @@ impl CCompilerImpl for NVCC {
4747
arguments: &[OsString],
4848
cwd: &Path,
4949
) -> CompilerArguments<ParsedArguments> {
50-
gcc::parse_arguments(arguments, cwd, (&gcc::ARGS[..], &ARGS[..]), false)
50+
gcc::parse_arguments(
51+
arguments,
52+
cwd,
53+
(&gcc::ARGS[..], &ARGS[..]),
54+
false,
55+
CCompilerKind::NVCC
56+
)
5157
}
5258

5359
fn preprocess<T>(

0 commit comments

Comments
 (0)