@@ -118,10 +118,14 @@ counted_array!(pub static ARGS: [ArgInfo<gcc::ArgData>; _] = [
118
118
take_arg!( "-fdebug-compilation-dir" , OsString , Separated , PassThrough ) ,
119
119
flag!( "-fmodules" , TooHardFlag ) ,
120
120
flag!( "-fno-color-diagnostics" , NoDiagnosticsColorFlag ) ,
121
+ flag!( "-fno-profile-instr-generate" , TooHardFlag ) ,
122
+ flag!( "-fno-profile-instr-use" , TooHardFlag ) ,
121
123
take_arg!( "-fplugin" , PathBuf , CanBeConcatenated ( '=' ) , ExtraHashFile ) ,
122
124
flag!( "-fprofile-instr-generate" , ProfileGenerate ) ,
123
- // Can be either -fprofile-instr-use or -fprofile-instr-use=path
124
- take_arg!( "-fprofile-instr-use" , OsString , Concatenated , TooHard ) ,
125
+ // Note: the PathBuf argument is optional
126
+ take_arg!( "-fprofile-instr-use" , PathBuf , Concatenated ( '=' ) , ClangProfileUse ) ,
127
+ // Note: this overrides the -fprofile-use option in gcc.rs.
128
+ take_arg!( "-fprofile-use" , PathBuf , Concatenated ( '=' ) , ClangProfileUse ) ,
125
129
take_arg!( "-fsanitize-blacklist" , PathBuf , Concatenated ( '=' ) , ExtraHashFile ) ,
126
130
take_arg!( "-gcc-toolchain" , OsString , Separated , PassThrough ) ,
127
131
take_arg!( "-include-pch" , PathBuf , CanBeSeparated , PreprocessorArgumentPath ) ,
@@ -132,6 +136,27 @@ counted_array!(pub static ARGS: [ArgInfo<gcc::ArgData>; _] = [
132
136
flag!( "-verify" , PreprocessorArgumentFlag ) ,
133
137
] ) ;
134
138
139
+ // Maps the `-fprofile-use` argument to the actual path of the
140
+ // .profdata file Clang will try to use.
141
+ pub ( crate ) fn resolve_profile_use_path ( arg : & Path , cwd : & Path ) -> PathBuf {
142
+ // Note that `arg` might be empty (if no argument was given to
143
+ // -fprofile-use), in which case `path` will be `cwd` after
144
+ // the next statement and "./default.profdata" at the end of the
145
+ // block. This matches Clang's behavior for when no argument is
146
+ // given.
147
+ let mut path = cwd. join ( arg) ;
148
+
149
+ assert ! ( !arg. as_os_str( ) . is_empty( ) || path == cwd) ;
150
+
151
+ // Clang allows specifying a directory here, in which case it
152
+ // will look for the file `default.profdata` in that directory.
153
+ if path. is_dir ( ) {
154
+ path. push ( "default.profdata" ) ;
155
+ }
156
+
157
+ path
158
+ }
159
+
135
160
#[ cfg( test) ]
136
161
mod test {
137
162
use super :: * ;
@@ -406,4 +431,104 @@ mod test {
406
431
let a = parses ! ( "-c" , "foo.c" , "-o" , "foo.o" ) ;
407
432
assert_eq ! ( a. color_mode, ColorMode :: Auto ) ;
408
433
}
434
+
435
+ #[ test]
436
+ fn test_parse_arguments_profile_instr_use ( ) {
437
+ let a = parses ! (
438
+ "-c" ,
439
+ "foo.c" ,
440
+ "-o" ,
441
+ "foo.o" ,
442
+ "-fprofile-instr-use=foo.profdata"
443
+ ) ;
444
+ assert_eq ! ( ovec![ "-fprofile-instr-use=foo.profdata" ] , a. common_args) ;
445
+ assert_eq ! (
446
+ ovec![ std:: env:: current_dir( ) . unwrap( ) . join( "foo.profdata" ) ] ,
447
+ a. extra_hash_files
448
+ ) ;
449
+ }
450
+
451
+ #[ test]
452
+ fn test_parse_arguments_profile_use ( ) {
453
+ let a = parses ! ( "-c" , "foo.c" , "-o" , "foo.o" , "-fprofile-use=xyz.profdata" ) ;
454
+
455
+ assert_eq ! ( ovec![ "-fprofile-use=xyz.profdata" ] , a. common_args) ;
456
+ assert_eq ! (
457
+ ovec![ std:: env:: current_dir( ) . unwrap( ) . join( "xyz.profdata" ) ] ,
458
+ a. extra_hash_files
459
+ ) ;
460
+ }
461
+
462
+ #[ test]
463
+ fn test_parse_arguments_profile_use_with_directory ( ) {
464
+ let a = parses ! ( "-c" , "foo.c" , "-o" , "foo.o" , "-fprofile-use=." ) ;
465
+
466
+ assert_eq ! ( ovec![ "-fprofile-use=." ] , a. common_args) ;
467
+ assert_eq ! (
468
+ ovec![ std:: env:: current_dir( ) . unwrap( ) . join( "default.profdata" ) ] ,
469
+ a. extra_hash_files
470
+ ) ;
471
+ }
472
+
473
+ #[ test]
474
+ fn test_parse_arguments_profile_use_with_no_argument ( ) {
475
+ let a = parses ! ( "-c" , "foo.c" , "-o" , "foo.o" , "-fprofile-use" ) ;
476
+
477
+ assert_eq ! ( ovec![ "-fprofile-use" ] , a. common_args) ;
478
+ assert_eq ! (
479
+ ovec![ std:: env:: current_dir( ) . unwrap( ) . join( "default.profdata" ) ] ,
480
+ a. extra_hash_files
481
+ ) ;
482
+ }
483
+
484
+ #[ test]
485
+ fn test_parse_arguments_pgo_cancellation ( ) {
486
+ assert_eq ! (
487
+ CompilerArguments :: CannotCache ( "-fno-profile-use" , None ) ,
488
+ parse_arguments_( stringvec![
489
+ "-c" ,
490
+ "foo.c" ,
491
+ "-o" ,
492
+ "foo.o" ,
493
+ "-fprofile-use" ,
494
+ "-fno-profile-use"
495
+ ] )
496
+ ) ;
497
+
498
+ assert_eq ! (
499
+ CompilerArguments :: CannotCache ( "-fno-profile-instr-use" , None ) ,
500
+ parse_arguments_( stringvec![
501
+ "-c" ,
502
+ "foo.c" ,
503
+ "-o" ,
504
+ "foo.o" ,
505
+ "-fprofile-instr-use" ,
506
+ "-fno-profile-instr-use"
507
+ ] )
508
+ ) ;
509
+
510
+ assert_eq ! (
511
+ CompilerArguments :: CannotCache ( "-fno-profile-generate" , None ) ,
512
+ parse_arguments_( stringvec![
513
+ "-c" ,
514
+ "foo.c" ,
515
+ "-o" ,
516
+ "foo.o" ,
517
+ "-fprofile-generate" ,
518
+ "-fno-profile-generate"
519
+ ] )
520
+ ) ;
521
+
522
+ assert_eq ! (
523
+ CompilerArguments :: CannotCache ( "-fno-profile-instr-generate" , None ) ,
524
+ parse_arguments_( stringvec![
525
+ "-c" ,
526
+ "foo.c" ,
527
+ "-o" ,
528
+ "foo.o" ,
529
+ "-fprofile-instr-generate" ,
530
+ "-fno-profile-instr-generate"
531
+ ] )
532
+ ) ;
533
+ }
409
534
}
0 commit comments