@@ -40,7 +40,7 @@ use crate::errors::{
40
40
WithLlvmError , WriteBytecode ,
41
41
} ;
42
42
use crate :: llvm:: diagnostic:: OptimizationDiagnosticKind :: * ;
43
- use crate :: llvm:: { self , DiagnosticInfo , PassManager } ;
43
+ use crate :: llvm:: { self , DiagnosticInfo } ;
44
44
use crate :: type_:: Type ;
45
45
use crate :: { LlvmCodegenBackend , ModuleLlvm , base, common, llvm_util} ;
46
46
@@ -54,7 +54,7 @@ pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> Fatal
54
54
fn write_output_file < ' ll > (
55
55
dcx : DiagCtxtHandle < ' _ > ,
56
56
target : & ' ll llvm:: TargetMachine ,
57
- pm : & llvm :: PassManager < ' ll > ,
57
+ no_builtins : bool ,
58
58
m : & ' ll llvm:: Module ,
59
59
output : & Path ,
60
60
dwo_output : Option < & Path > ,
@@ -63,39 +63,42 @@ fn write_output_file<'ll>(
63
63
verify_llvm_ir : bool ,
64
64
) -> Result < ( ) , FatalError > {
65
65
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 (
76
79
target,
77
80
pm,
78
81
m,
79
82
output_c. as_ptr ( ) ,
80
83
dwo_output_ptr,
81
84
file_type,
82
85
verify_llvm_ir,
83
- ) ;
86
+ )
87
+ } ;
84
88
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) ;
95
98
}
96
-
97
- result. into_result ( ) . map_err ( |( ) | llvm_err ( dcx, LlvmError :: WriteOutput { path : output } ) )
98
99
}
100
+
101
+ result. into_result ( ) . map_err ( |( ) | llvm_err ( dcx, LlvmError :: WriteOutput { path : output } ) )
99
102
}
100
103
101
104
pub ( crate ) fn create_informational_target_machine (
@@ -325,13 +328,17 @@ pub(crate) fn save_temp_bitcode(
325
328
if !cgcx. save_temps {
326
329
return ;
327
330
}
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 ) {
328
338
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) ;
333
340
let llmod = module. module_llvm . llmod ( ) ;
334
- llvm:: LLVMWriteBitcodeToFile ( llmod, cstr . as_ptr ( ) ) ;
341
+ llvm:: LLVMWriteBitcodeToFile ( llmod, path . as_ptr ( ) ) ;
335
342
}
336
343
}
337
344
@@ -676,7 +683,6 @@ pub(crate) unsafe fn optimize(
676
683
) -> Result < ( ) , FatalError > {
677
684
let _timer = cgcx. prof . generic_activity_with_arg ( "LLVM_module_optimize" , & * module. name ) ;
678
685
679
- let llmod = module. module_llvm . llmod ( ) ;
680
686
let llcx = & * module. module_llvm . llcx ;
681
687
let _handlers = DiagnosticHandlers :: new ( cgcx, dcx, llcx, module, CodegenDiagnosticsStage :: Opt ) ;
682
688
@@ -685,8 +691,7 @@ pub(crate) unsafe fn optimize(
685
691
686
692
if config. emit_no_opt_bc {
687
693
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)
690
695
}
691
696
692
697
// FIXME(ZuseZ4): support SanitizeHWAddress and prevent illegal/unsupported opts
@@ -755,31 +760,6 @@ pub(crate) unsafe fn codegen(
755
760
create_msvc_imps ( cgcx, llcx, llmod) ;
756
761
}
757
762
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
-
783
763
// Note that if object files are just LLVM bitcode we write bitcode,
784
764
// copy it to the .o file, and delete the bitcode if it wasn't
785
765
// otherwise requested.
@@ -898,21 +878,17 @@ pub(crate) unsafe fn codegen(
898
878
} else {
899
879
llmod
900
880
} ;
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
+ ) ?;
916
892
}
917
893
918
894
match config. emit_obj {
@@ -936,21 +912,17 @@ pub(crate) unsafe fn codegen(
936
912
( _, SplitDwarfKind :: Split ) => Some ( dwo_out. as_path ( ) ) ,
937
913
} ;
938
914
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
+ ) ?;
954
926
}
955
927
956
928
EmitObj :: Bitcode => {
@@ -1077,24 +1049,18 @@ unsafe fn embed_bitcode(
1077
1049
{
1078
1050
// We don't need custom section flags, create LLVM globals.
1079
1051
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) ;
1086
1055
1087
1056
llvm:: set_section ( llglobal, bitcode_section_name ( cgcx) ) ;
1088
1057
llvm:: set_linkage ( llglobal, llvm:: Linkage :: PrivateLinkage ) ;
1089
1058
llvm:: LLVMSetGlobalConstant ( llglobal, llvm:: True ) ;
1090
1059
1091
1060
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) ;
1098
1064
let section = if cgcx. target_is_like_osx {
1099
1065
c"__LLVM,__cmdline"
1100
1066
} else if cgcx. target_is_like_aix {
@@ -1134,31 +1100,29 @@ fn create_msvc_imps(
1134
1100
// underscores added in front).
1135
1101
let prefix = if cgcx. target_arch == "x86" { "\x01 __imp__" } else { "\x01 __imp_" } ;
1136
1102
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 < _ > > ( ) ;
1156
1120
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 ) ;
1162
1126
}
1163
1127
1164
1128
// Use this function to exclude certain symbols from `__imp` generation.
0 commit comments