@@ -3,6 +3,7 @@ use crate::llvm;
33use syntax_pos:: symbol:: Symbol ;
44use rustc:: session:: Session ;
55use rustc:: session:: config:: PrintRequest ;
6+ use rustc_data_structures:: fx:: FxHashSet ;
67use rustc_target:: spec:: { MergeFunctions , PanicStrategy } ;
78use libc:: c_int;
89use std:: ffi:: CString ;
@@ -51,43 +52,62 @@ unsafe fn configure_llvm(sess: &Session) {
5152
5253 llvm:: LLVMRustInstallFatalErrorHandler ( ) ;
5354
55+ fn llvm_arg_to_arg_name ( full_arg : & str ) -> & str {
56+ full_arg. trim ( ) . split ( |c : char | {
57+ c == '=' || c. is_whitespace ( )
58+ } ) . next ( ) . unwrap_or ( "" )
59+ }
60+
61+ let user_specified_args: FxHashSet < _ > = sess
62+ . opts
63+ . cg
64+ . llvm_args
65+ . iter ( )
66+ . map ( |s| llvm_arg_to_arg_name ( s) )
67+ . filter ( |s| s. len ( ) > 0 )
68+ . collect ( ) ;
69+
5470 {
55- let mut add = |arg : & str | {
56- let s = CString :: new ( arg) . unwrap ( ) ;
57- llvm_args. push ( s. as_ptr ( ) ) ;
58- llvm_c_strs. push ( s) ;
71+ // This adds the given argument to LLVM. Unless `force` is true
72+ // user specified arguments are *not* overridden.
73+ let mut add = |arg : & str , force : bool | {
74+ if force || !user_specified_args. contains ( llvm_arg_to_arg_name ( arg) ) {
75+ let s = CString :: new ( arg) . unwrap ( ) ;
76+ llvm_args. push ( s. as_ptr ( ) ) ;
77+ llvm_c_strs. push ( s) ;
78+ }
5979 } ;
60- add ( "rustc" ) ; // fake program name
61- if sess. time_llvm_passes ( ) { add ( "-time-passes" ) ; }
62- if sess. print_llvm_passes ( ) { add ( "-debug-pass=Structure" ) ; }
80+ add ( "rustc" , true ) ; // fake program name
81+ if sess. time_llvm_passes ( ) { add ( "-time-passes" , false ) ; }
82+ if sess. print_llvm_passes ( ) { add ( "-debug-pass=Structure" , false ) ; }
6383 if sess. opts . debugging_opts . disable_instrumentation_preinliner {
64- add ( "-disable-preinline" ) ;
84+ add ( "-disable-preinline" , false ) ;
6585 }
6686 if sess. opts . debugging_opts . generate_arange_section {
67- add ( "-generate-arange-section" ) ;
87+ add ( "-generate-arange-section" , false ) ;
6888 }
6989 if get_major_version ( ) >= 8 {
7090 match sess. opts . debugging_opts . merge_functions
7191 . unwrap_or ( sess. target . target . options . merge_functions ) {
7292 MergeFunctions :: Disabled |
7393 MergeFunctions :: Trampolines => { }
7494 MergeFunctions :: Aliases => {
75- add ( "-mergefunc-use-aliases" ) ;
95+ add ( "-mergefunc-use-aliases" , false ) ;
7696 }
7797 }
7898 }
7999
80100 if sess. target . target . target_os == "emscripten" &&
81101 sess. panic_strategy ( ) == PanicStrategy :: Unwind {
82- add ( "-enable-emscripten-cxx-exceptions" ) ;
102+ add ( "-enable-emscripten-cxx-exceptions" , false ) ;
83103 }
84104
85105 // HACK(eddyb) LLVM inserts `llvm.assume` calls to preserve align attributes
86106 // during inlining. Unfortunately these may block other optimizations.
87- add ( "-preserve-alignment-assumptions-during-inlining=false" ) ;
107+ add ( "-preserve-alignment-assumptions-during-inlining=false" , false ) ;
88108
89109 for arg in & sess. opts . cg . llvm_args {
90- add ( & ( * arg) ) ;
110+ add ( & ( * arg) , true ) ;
91111 }
92112 }
93113
0 commit comments