@@ -40,7 +40,7 @@ use crate::errors::{
4040 WithLlvmError , WriteBytecode ,
4141} ;
4242use crate :: llvm:: diagnostic:: OptimizationDiagnosticKind :: * ;
43- use crate :: llvm:: { self , DiagnosticInfo , PassManager } ;
43+ use crate :: llvm:: { self , DiagnosticInfo } ;
4444use crate :: type_:: Type ;
4545use crate :: { LlvmCodegenBackend , ModuleLlvm , base, common, llvm_util} ;
4646
@@ -54,7 +54,7 @@ pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> Fatal
5454fn write_output_file < ' ll > (
5555 dcx : DiagCtxtHandle < ' _ > ,
5656 target : & ' ll llvm:: TargetMachine ,
57- pm : & llvm :: PassManager < ' ll > ,
57+ no_builtins : bool ,
5858 m : & ' ll llvm:: Module ,
5959 output : & Path ,
6060 dwo_output : Option < & Path > ,
@@ -63,39 +63,42 @@ fn write_output_file<'ll>(
6363 verify_llvm_ir : bool ,
6464) -> Result < ( ) , FatalError > {
6565 debug ! ( "write_output_file output={:?} dwo_output={:?}" , output, dwo_output) ;
66- unsafe {
67- let output_c = path_to_c_string ( output) ;
68- let dwo_output_c;
69- let dwo_output_ptr = if let Some ( dwo_output) = dwo_output {
70- dwo_output_c = path_to_c_string ( dwo_output) ;
71- dwo_output_c. as_ptr ( )
72- } else {
73- std:: ptr:: null ( )
74- } ;
75- let result = llvm:: LLVMRustWriteOutputFile (
66+ let output_c = path_to_c_string ( output) ;
67+ let dwo_output_c;
68+ let dwo_output_ptr = if let Some ( dwo_output) = dwo_output {
69+ dwo_output_c = path_to_c_string ( dwo_output) ;
70+ dwo_output_c. as_ptr ( )
71+ } else {
72+ std:: ptr:: null ( )
73+ } ;
74+ let result = unsafe {
75+ let pm = llvm:: LLVMCreatePassManager ( ) ;
76+ llvm:: LLVMAddAnalysisPasses ( target, pm) ;
77+ llvm:: LLVMRustAddLibraryInfo ( pm, m, no_builtins) ;
78+ llvm:: LLVMRustWriteOutputFile (
7679 target,
7780 pm,
7881 m,
7982 output_c. as_ptr ( ) ,
8083 dwo_output_ptr,
8184 file_type,
8285 verify_llvm_ir,
83- ) ;
86+ )
87+ } ;
8488
85- // Record artifact sizes for self-profiling
86- if result == llvm:: LLVMRustResult :: Success {
87- let artifact_kind = match file_type {
88- llvm:: FileType :: ObjectFile => "object_file" ,
89- llvm:: FileType :: AssemblyFile => "assembly_file" ,
90- } ;
91- record_artifact_size ( self_profiler_ref, artifact_kind, output) ;
92- if let Some ( dwo_file) = dwo_output {
93- record_artifact_size ( self_profiler_ref, "dwo_file" , dwo_file) ;
94- }
89+ // Record artifact sizes for self-profiling
90+ if result == llvm:: LLVMRustResult :: Success {
91+ let artifact_kind = match file_type {
92+ llvm:: FileType :: ObjectFile => "object_file" ,
93+ llvm:: FileType :: AssemblyFile => "assembly_file" ,
94+ } ;
95+ record_artifact_size ( self_profiler_ref, artifact_kind, output) ;
96+ if let Some ( dwo_file) = dwo_output {
97+ record_artifact_size ( self_profiler_ref, "dwo_file" , dwo_file) ;
9598 }
96-
97- result. into_result ( ) . map_err ( |( ) | llvm_err ( dcx, LlvmError :: WriteOutput { path : output } ) )
9899 }
100+
101+ result. into_result ( ) . map_err ( |( ) | llvm_err ( dcx, LlvmError :: WriteOutput { path : output } ) )
99102}
100103
101104pub ( crate ) fn create_informational_target_machine (
@@ -325,13 +328,17 @@ pub(crate) fn save_temp_bitcode(
325328 if !cgcx. save_temps {
326329 return ;
327330 }
331+ let ext = format ! ( "{name}.bc" ) ;
332+ let cgu = Some ( & module. name [ ..] ) ;
333+ let path = cgcx. output_filenames . temp_path_ext ( & ext, cgu) ;
334+ write_bitcode_to_file ( module, & path)
335+ }
336+
337+ fn write_bitcode_to_file ( module : & ModuleCodegen < ModuleLlvm > , path : & Path ) {
328338 unsafe {
329- let ext = format ! ( "{name}.bc" ) ;
330- let cgu = Some ( & module. name [ ..] ) ;
331- let path = cgcx. output_filenames . temp_path_ext ( & ext, cgu) ;
332- let cstr = path_to_c_string ( & path) ;
339+ let path = path_to_c_string ( & path) ;
333340 let llmod = module. module_llvm . llmod ( ) ;
334- llvm:: LLVMWriteBitcodeToFile ( llmod, cstr . as_ptr ( ) ) ;
341+ llvm:: LLVMWriteBitcodeToFile ( llmod, path . as_ptr ( ) ) ;
335342 }
336343}
337344
@@ -676,7 +683,6 @@ pub(crate) unsafe fn optimize(
676683) -> Result < ( ) , FatalError > {
677684 let _timer = cgcx. prof . generic_activity_with_arg ( "LLVM_module_optimize" , & * module. name ) ;
678685
679- let llmod = module. module_llvm . llmod ( ) ;
680686 let llcx = & * module. module_llvm . llcx ;
681687 let _handlers = DiagnosticHandlers :: new ( cgcx, dcx, llcx, module, CodegenDiagnosticsStage :: Opt ) ;
682688
@@ -685,8 +691,7 @@ pub(crate) unsafe fn optimize(
685691
686692 if config. emit_no_opt_bc {
687693 let out = cgcx. output_filenames . temp_path_ext ( "no-opt.bc" , module_name) ;
688- let out = path_to_c_string ( & out) ;
689- unsafe { llvm:: LLVMWriteBitcodeToFile ( llmod, out. as_ptr ( ) ) } ;
694+ write_bitcode_to_file ( module, & out)
690695 }
691696
692697 // FIXME(ZuseZ4): support SanitizeHWAddress and prevent illegal/unsupported opts
@@ -755,31 +760,6 @@ pub(crate) unsafe fn codegen(
755760 create_msvc_imps ( cgcx, llcx, llmod) ;
756761 }
757762
758- // A codegen-specific pass manager is used to generate object
759- // files for an LLVM module.
760- //
761- // Apparently each of these pass managers is a one-shot kind of
762- // thing, so we create a new one for each type of output. The
763- // pass manager passed to the closure should be ensured to not
764- // escape the closure itself, and the manager should only be
765- // used once.
766- unsafe fn with_codegen < ' ll , F , R > (
767- tm : & ' ll llvm:: TargetMachine ,
768- llmod : & ' ll llvm:: Module ,
769- no_builtins : bool ,
770- f : F ,
771- ) -> R
772- where
773- F : FnOnce ( & ' ll mut PassManager < ' ll > ) -> R ,
774- {
775- unsafe {
776- let cpm = llvm:: LLVMCreatePassManager ( ) ;
777- llvm:: LLVMAddAnalysisPasses ( tm, cpm) ;
778- llvm:: LLVMRustAddLibraryInfo ( cpm, llmod, no_builtins) ;
779- f ( cpm)
780- }
781- }
782-
783763 // Note that if object files are just LLVM bitcode we write bitcode,
784764 // copy it to the .o file, and delete the bitcode if it wasn't
785765 // otherwise requested.
@@ -898,21 +878,17 @@ pub(crate) unsafe fn codegen(
898878 } else {
899879 llmod
900880 } ;
901- unsafe {
902- with_codegen ( tm, llmod, config. no_builtins , |cpm| {
903- write_output_file (
904- dcx,
905- tm,
906- cpm,
907- llmod,
908- & path,
909- None ,
910- llvm:: FileType :: AssemblyFile ,
911- & cgcx. prof ,
912- config. verify_llvm_ir ,
913- )
914- } ) ?;
915- }
881+ write_output_file (
882+ dcx,
883+ tm,
884+ config. no_builtins ,
885+ llmod,
886+ & path,
887+ None ,
888+ llvm:: FileType :: AssemblyFile ,
889+ & cgcx. prof ,
890+ config. verify_llvm_ir ,
891+ ) ?;
916892 }
917893
918894 match config. emit_obj {
@@ -936,21 +912,17 @@ pub(crate) unsafe fn codegen(
936912 ( _, SplitDwarfKind :: Split ) => Some ( dwo_out. as_path ( ) ) ,
937913 } ;
938914
939- unsafe {
940- with_codegen ( tm, llmod, config. no_builtins , |cpm| {
941- write_output_file (
942- dcx,
943- tm,
944- cpm,
945- llmod,
946- & obj_out,
947- dwo_out,
948- llvm:: FileType :: ObjectFile ,
949- & cgcx. prof ,
950- config. verify_llvm_ir ,
951- )
952- } ) ?;
953- }
915+ write_output_file (
916+ dcx,
917+ tm,
918+ config. no_builtins ,
919+ llmod,
920+ & obj_out,
921+ dwo_out,
922+ llvm:: FileType :: ObjectFile ,
923+ & cgcx. prof ,
924+ config. verify_llvm_ir ,
925+ ) ?;
954926 }
955927
956928 EmitObj :: Bitcode => {
@@ -1077,24 +1049,18 @@ unsafe fn embed_bitcode(
10771049 {
10781050 // We don't need custom section flags, create LLVM globals.
10791051 let llconst = common:: bytes_in_context ( llcx, bitcode) ;
1080- let llglobal = llvm:: LLVMAddGlobal (
1081- llmod,
1082- common:: val_ty ( llconst) ,
1083- c"rustc.embedded.module" . as_ptr ( ) ,
1084- ) ;
1085- llvm:: LLVMSetInitializer ( llglobal, llconst) ;
1052+ let llglobal =
1053+ llvm:: add_global ( llmod, common:: val_ty ( llconst) , c"rustc.embedded.module" ) ;
1054+ llvm:: set_initializer ( llglobal, llconst) ;
10861055
10871056 llvm:: set_section ( llglobal, bitcode_section_name ( cgcx) ) ;
10881057 llvm:: set_linkage ( llglobal, llvm:: Linkage :: PrivateLinkage ) ;
10891058 llvm:: LLVMSetGlobalConstant ( llglobal, llvm:: True ) ;
10901059
10911060 let llconst = common:: bytes_in_context ( llcx, cmdline. as_bytes ( ) ) ;
1092- let llglobal = llvm:: LLVMAddGlobal (
1093- llmod,
1094- common:: val_ty ( llconst) ,
1095- c"rustc.embedded.cmdline" . as_ptr ( ) ,
1096- ) ;
1097- llvm:: LLVMSetInitializer ( llglobal, llconst) ;
1061+ let llglobal =
1062+ llvm:: add_global ( llmod, common:: val_ty ( llconst) , c"rustc.embedded.cmdline" ) ;
1063+ llvm:: set_initializer ( llglobal, llconst) ;
10981064 let section = if cgcx. target_is_like_osx {
10991065 c"__LLVM,__cmdline"
11001066 } else if cgcx. target_is_like_aix {
@@ -1134,31 +1100,29 @@ fn create_msvc_imps(
11341100 // underscores added in front).
11351101 let prefix = if cgcx. target_arch == "x86" { "\x01 __imp__" } else { "\x01 __imp_" } ;
11361102
1137- unsafe {
1138- let ptr_ty = Type :: ptr_llcx ( llcx) ;
1139- let globals = base:: iter_globals ( llmod)
1140- . filter ( |& val| {
1141- llvm:: get_linkage ( val) == llvm:: Linkage :: ExternalLinkage
1142- && llvm:: LLVMIsDeclaration ( val) == 0
1143- } )
1144- . filter_map ( |val| {
1145- // Exclude some symbols that we know are not Rust symbols.
1146- let name = llvm:: get_value_name ( val) ;
1147- if ignored ( name) { None } else { Some ( ( val, name) ) }
1148- } )
1149- . map ( move |( val, name) | {
1150- let mut imp_name = prefix. as_bytes ( ) . to_vec ( ) ;
1151- imp_name. extend ( name) ;
1152- let imp_name = CString :: new ( imp_name) . unwrap ( ) ;
1153- ( imp_name, val)
1154- } )
1155- . collect :: < Vec < _ > > ( ) ;
1103+ let ptr_ty = Type :: ptr_llcx ( llcx) ;
1104+ let globals = base:: iter_globals ( llmod)
1105+ . filter ( |& val| {
1106+ llvm:: get_linkage ( val) == llvm:: Linkage :: ExternalLinkage && !llvm:: is_declaration ( val)
1107+ } )
1108+ . filter_map ( |val| {
1109+ // Exclude some symbols that we know are not Rust symbols.
1110+ let name = llvm:: get_value_name ( val) ;
1111+ if ignored ( name) { None } else { Some ( ( val, name) ) }
1112+ } )
1113+ . map ( move |( val, name) | {
1114+ let mut imp_name = prefix. as_bytes ( ) . to_vec ( ) ;
1115+ imp_name. extend ( name) ;
1116+ let imp_name = CString :: new ( imp_name) . unwrap ( ) ;
1117+ ( imp_name, val)
1118+ } )
1119+ . collect :: < Vec < _ > > ( ) ;
11561120
1157- for ( imp_name, val) in globals {
1158- let imp = llvm:: LLVMAddGlobal ( llmod, ptr_ty, imp_name. as_ptr ( ) ) ;
1159- llvm :: LLVMSetInitializer ( imp , val ) ;
1160- llvm:: set_linkage ( imp, llvm :: Linkage :: ExternalLinkage ) ;
1161- }
1121+ for ( imp_name, val) in globals {
1122+ let imp = llvm:: add_global ( llmod, ptr_ty, & imp_name) ;
1123+
1124+ llvm:: set_initializer ( imp, val ) ;
1125+ llvm :: set_linkage ( imp , llvm :: Linkage :: ExternalLinkage ) ;
11621126 }
11631127
11641128 // Use this function to exclude certain symbols from `__imp` generation.
0 commit comments