@@ -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
@@ -661,7 +668,6 @@ pub(crate) unsafe fn optimize(
661668) -> Result < ( ) , FatalError > {
662669 let _timer = cgcx. prof . generic_activity_with_arg ( "LLVM_module_optimize" , & * module. name ) ;
663670
664- let llmod = module. module_llvm . llmod ( ) ;
665671 let llcx = & * module. module_llvm . llcx ;
666672 let _handlers = DiagnosticHandlers :: new ( cgcx, dcx, llcx, module, CodegenDiagnosticsStage :: Opt ) ;
667673
@@ -670,8 +676,7 @@ pub(crate) unsafe fn optimize(
670676
671677 if config. emit_no_opt_bc {
672678 let out = cgcx. output_filenames . temp_path_ext ( "no-opt.bc" , module_name) ;
673- let out = path_to_c_string ( & out) ;
674- unsafe { llvm:: LLVMWriteBitcodeToFile ( llmod, out. as_ptr ( ) ) } ;
679+ write_bitcode_to_file ( module, & out)
675680 }
676681
677682 // FIXME(ZuseZ4): support SanitizeHWAddress and prevent illegal/unsupported opts
@@ -744,31 +749,6 @@ pub(crate) unsafe fn codegen(
744749 create_msvc_imps ( cgcx, llcx, llmod) ;
745750 }
746751
747- // A codegen-specific pass manager is used to generate object
748- // files for an LLVM module.
749- //
750- // Apparently each of these pass managers is a one-shot kind of
751- // thing, so we create a new one for each type of output. The
752- // pass manager passed to the closure should be ensured to not
753- // escape the closure itself, and the manager should only be
754- // used once.
755- unsafe fn with_codegen < ' ll , F , R > (
756- tm : & ' ll llvm:: TargetMachine ,
757- llmod : & ' ll llvm:: Module ,
758- no_builtins : bool ,
759- f : F ,
760- ) -> R
761- where
762- F : FnOnce ( & ' ll mut PassManager < ' ll > ) -> R ,
763- {
764- unsafe {
765- let cpm = llvm:: LLVMCreatePassManager ( ) ;
766- llvm:: LLVMAddAnalysisPasses ( tm, cpm) ;
767- llvm:: LLVMRustAddLibraryInfo ( cpm, llmod, no_builtins) ;
768- f ( cpm)
769- }
770- }
771-
772752 // Note that if object files are just LLVM bitcode we write bitcode,
773753 // copy it to the .o file, and delete the bitcode if it wasn't
774754 // otherwise requested.
@@ -887,21 +867,17 @@ pub(crate) unsafe fn codegen(
887867 } else {
888868 llmod
889869 } ;
890- unsafe {
891- with_codegen ( tm, llmod, config. no_builtins , |cpm| {
892- write_output_file (
893- dcx,
894- tm,
895- cpm,
896- llmod,
897- & path,
898- None ,
899- llvm:: FileType :: AssemblyFile ,
900- & cgcx. prof ,
901- config. verify_llvm_ir ,
902- )
903- } ) ?;
904- }
870+ write_output_file (
871+ dcx,
872+ tm,
873+ config. no_builtins ,
874+ llmod,
875+ & path,
876+ None ,
877+ llvm:: FileType :: AssemblyFile ,
878+ & cgcx. prof ,
879+ config. verify_llvm_ir ,
880+ ) ?;
905881 }
906882
907883 match config. emit_obj {
@@ -925,21 +901,17 @@ pub(crate) unsafe fn codegen(
925901 ( _, SplitDwarfKind :: Split ) => Some ( dwo_out. as_path ( ) ) ,
926902 } ;
927903
928- unsafe {
929- with_codegen ( tm, llmod, config. no_builtins , |cpm| {
930- write_output_file (
931- dcx,
932- tm,
933- cpm,
934- llmod,
935- & obj_out,
936- dwo_out,
937- llvm:: FileType :: ObjectFile ,
938- & cgcx. prof ,
939- config. verify_llvm_ir ,
940- )
941- } ) ?;
942- }
904+ write_output_file (
905+ dcx,
906+ tm,
907+ config. no_builtins ,
908+ llmod,
909+ & obj_out,
910+ dwo_out,
911+ llvm:: FileType :: ObjectFile ,
912+ & cgcx. prof ,
913+ config. verify_llvm_ir ,
914+ ) ?;
943915 }
944916
945917 EmitObj :: Bitcode => {
@@ -1066,24 +1038,18 @@ unsafe fn embed_bitcode(
10661038 {
10671039 // We don't need custom section flags, create LLVM globals.
10681040 let llconst = common:: bytes_in_context ( llcx, bitcode) ;
1069- let llglobal = llvm:: LLVMAddGlobal (
1070- llmod,
1071- common:: val_ty ( llconst) ,
1072- c"rustc.embedded.module" . as_ptr ( ) ,
1073- ) ;
1074- llvm:: LLVMSetInitializer ( llglobal, llconst) ;
1041+ let llglobal =
1042+ llvm:: add_global ( llmod, common:: val_ty ( llconst) , c"rustc.embedded.module" ) ;
1043+ llvm:: set_initializer ( llglobal, llconst) ;
10751044
10761045 llvm:: set_section ( llglobal, bitcode_section_name ( cgcx) ) ;
10771046 llvm:: set_linkage ( llglobal, llvm:: Linkage :: PrivateLinkage ) ;
10781047 llvm:: LLVMSetGlobalConstant ( llglobal, llvm:: True ) ;
10791048
10801049 let llconst = common:: bytes_in_context ( llcx, cmdline. as_bytes ( ) ) ;
1081- let llglobal = llvm:: LLVMAddGlobal (
1082- llmod,
1083- common:: val_ty ( llconst) ,
1084- c"rustc.embedded.cmdline" . as_ptr ( ) ,
1085- ) ;
1086- llvm:: LLVMSetInitializer ( llglobal, llconst) ;
1050+ let llglobal =
1051+ llvm:: add_global ( llmod, common:: val_ty ( llconst) , c"rustc.embedded.cmdline" ) ;
1052+ llvm:: set_initializer ( llglobal, llconst) ;
10871053 let section = if cgcx. target_is_like_osx {
10881054 c"__LLVM,__cmdline"
10891055 } else if cgcx. target_is_like_aix {
@@ -1123,31 +1089,29 @@ fn create_msvc_imps(
11231089 // underscores added in front).
11241090 let prefix = if cgcx. target_arch == "x86" { "\x01 __imp__" } else { "\x01 __imp_" } ;
11251091
1126- unsafe {
1127- let ptr_ty = Type :: ptr_llcx ( llcx) ;
1128- let globals = base:: iter_globals ( llmod)
1129- . filter ( |& val| {
1130- llvm:: get_linkage ( val) == llvm:: Linkage :: ExternalLinkage
1131- && llvm:: LLVMIsDeclaration ( val) == 0
1132- } )
1133- . filter_map ( |val| {
1134- // Exclude some symbols that we know are not Rust symbols.
1135- let name = llvm:: get_value_name ( val) ;
1136- if ignored ( name) { None } else { Some ( ( val, name) ) }
1137- } )
1138- . map ( move |( val, name) | {
1139- let mut imp_name = prefix. as_bytes ( ) . to_vec ( ) ;
1140- imp_name. extend ( name) ;
1141- let imp_name = CString :: new ( imp_name) . unwrap ( ) ;
1142- ( imp_name, val)
1143- } )
1144- . collect :: < Vec < _ > > ( ) ;
1092+ let ptr_ty = Type :: ptr_llcx ( llcx) ;
1093+ let globals = base:: iter_globals ( llmod)
1094+ . filter ( |& val| {
1095+ llvm:: get_linkage ( val) == llvm:: Linkage :: ExternalLinkage && llvm:: is_declaration ( val)
1096+ } )
1097+ . filter_map ( |val| {
1098+ // Exclude some symbols that we know are not Rust symbols.
1099+ let name = llvm:: get_value_name ( val) ;
1100+ if ignored ( name) { None } else { Some ( ( val, name) ) }
1101+ } )
1102+ . map ( move |( val, name) | {
1103+ let mut imp_name = prefix. as_bytes ( ) . to_vec ( ) ;
1104+ imp_name. extend ( name) ;
1105+ let imp_name = CString :: new ( imp_name) . unwrap ( ) ;
1106+ ( imp_name, val)
1107+ } )
1108+ . collect :: < Vec < _ > > ( ) ;
11451109
1146- for ( imp_name, val) in globals {
1147- let imp = llvm:: LLVMAddGlobal ( llmod, ptr_ty, imp_name. as_ptr ( ) ) ;
1148- llvm :: LLVMSetInitializer ( imp , val ) ;
1149- llvm:: set_linkage ( imp, llvm :: Linkage :: ExternalLinkage ) ;
1150- }
1110+ for ( imp_name, val) in globals {
1111+ let imp = llvm:: add_global ( llmod, ptr_ty, & imp_name) ;
1112+
1113+ llvm:: set_initializer ( imp, val ) ;
1114+ llvm :: set_linkage ( imp , llvm :: Linkage :: ExternalLinkage ) ;
11511115 }
11521116
11531117 // Use this function to exclude certain symbols from `__imp` generation.
0 commit comments