@@ -22,6 +22,7 @@ use rustc_hir::attrs::Linkage;
2222use rustc_middle:: dep_graph;
2323use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrs , SanitizerFnAttrs } ;
2424use rustc_middle:: mono:: Visibility ;
25+ use rustc_middle:: query:: { QueryHashHelper , QueryHelper } ;
2526use rustc_middle:: ty:: TyCtxt ;
2627use rustc_session:: config:: { DebugInfo , Offload } ;
2728use rustc_span:: Symbol ;
@@ -62,122 +63,146 @@ pub(crate) fn compile_codegen_unit(
6263 let start_time = Instant :: now ( ) ;
6364
6465 let dep_node = tcx. codegen_unit ( cgu_name) . codegen_dep_node ( tcx) ;
65- let ( module, _) = tcx. dep_graph . with_task (
66- dep_node,
67- tcx,
68- cgu_name,
69- module_codegen,
70- Some ( dep_graph:: hash_result) ,
71- ) ;
72- let time_to_codegen = start_time. elapsed ( ) ;
7366
74- // We assume that the cost to run LLVM on a CGU is proportional to
75- // the time we needed for codegenning it.
76- let cost = time_to_codegen. as_nanos ( ) as u64 ;
67+ #[ derive( Default ) ]
68+ struct CompileCguHashHelper ;
7769
78- fn module_codegen ( tcx : TyCtxt < ' _ > , cgu_name : Symbol ) -> ModuleCodegen < ModuleLlvm > {
79- let cgu = tcx. codegen_unit ( cgu_name) ;
80- let _prof_timer =
81- tcx. prof . generic_activity_with_arg_recorder ( "codegen_module" , |recorder| {
82- recorder. record_arg ( cgu_name. to_string ( ) ) ;
83- recorder. record_arg ( cgu. size_estimate ( ) . to_string ( ) ) ;
84- } ) ;
85- // Instantiate monomorphizations without filling out definitions yet...
86- let llvm_module = ModuleLlvm :: new ( tcx, cgu_name. as_str ( ) ) ;
87- {
88- let mut cx = CodegenCx :: new ( tcx, cgu, & llvm_module) ;
89-
90- // Declare and store globals shared by all offload kernels
91- //
92- // These globals are left in the LLVM-IR host module so all kernels can access them.
93- // They are necessary for correct offload execution. We do this here to simplify the
94- // `offload` intrinsic, avoiding the need for tracking whether it's the first
95- // intrinsic call or not.
96- let has_host_offload = cx
97- . sess ( )
98- . opts
99- . unstable_opts
100- . offload
101- . iter ( )
102- . any ( |o| matches ! ( o, Offload :: Host ( _) | Offload :: Test ) ) ;
103- if has_host_offload && !cx. sess ( ) . target . is_like_gpu {
104- cx. offload_globals . replace ( Some ( OffloadGlobals :: declare ( & cx) ) ) ;
105- }
70+ impl QueryHashHelper < ModuleCodegen < ModuleLlvm > > for CompileCguHashHelper {
71+ const NO_HASH : bool = false ;
10672
107- let mono_items = cx. codegen_unit . items_in_deterministic_order ( cx. tcx ) ;
108- for & ( mono_item, data) in & mono_items {
109- mono_item. predefine :: < Builder < ' _ , ' _ , ' _ > > (
110- & mut cx,
111- cgu_name. as_str ( ) ,
112- data. linkage ,
113- data. visibility ,
114- ) ;
115- }
73+ fn hash_value_fn (
74+ hcx : & mut rustc_middle:: ich:: StableHashingContext < ' _ > ,
75+ result : & ModuleCodegen < ModuleLlvm > ,
76+ ) -> rustc_data_structures:: fingerprint:: Fingerprint {
77+ dep_graph:: hash_result ( hcx, result)
78+ }
79+ }
11680
117- // ... and now that we have everything pre-defined, fill out those definitions.
118- for & ( mono_item, item_data) in & mono_items {
119- mono_item. define :: < Builder < ' _ , ' _ , ' _ > > ( & mut cx, cgu_name. as_str ( ) , item_data) ;
120- }
81+ impl < ' tcx > QueryHelper < ' tcx , Symbol , ModuleCodegen < ModuleLlvm > > for CompileCguHashHelper {
82+ fn try_load_from_disk_fn (
83+ _: TyCtxt < ' tcx > ,
84+ _: dep_graph:: SerializedDepNodeIndex ,
85+ ) -> Option < ModuleCodegen < ModuleLlvm > > {
86+ unimplemented ! ( )
87+ }
12188
122- // If this codegen unit contains the main function, also create the
123- // wrapper here
124- if let Some ( entry) =
125- maybe_create_entry_wrapper :: < Builder < ' _ , ' _ , ' _ > > ( & cx, cx. codegen_unit )
89+ fn will_cache_on_disk_for_key ( _: Symbol ) -> bool {
90+ unimplemented ! ( )
91+ }
92+
93+ fn invoke_provider_fn ( tcx : TyCtxt < ' tcx > , cgu_name : Symbol ) -> ModuleCodegen < ModuleLlvm > {
94+ // Module codegen
95+ let cgu = tcx. codegen_unit ( cgu_name) ;
96+ let _prof_timer =
97+ tcx. prof . generic_activity_with_arg_recorder ( "codegen_module" , |recorder| {
98+ recorder. record_arg ( cgu_name. to_string ( ) ) ;
99+ recorder. record_arg ( cgu. size_estimate ( ) . to_string ( ) ) ;
100+ } ) ;
101+ // Instantiate monomorphizations without filling out definitions yet...
102+ let llvm_module = ModuleLlvm :: new ( tcx, cgu_name. as_str ( ) ) ;
126103 {
127- let attrs = attributes:: sanitize_attrs ( & cx, tcx, SanitizerFnAttrs :: default ( ) ) ;
128- attributes:: apply_to_llfn ( entry, llvm:: AttributePlace :: Function , & attrs) ;
129- }
104+ let mut cx = CodegenCx :: new ( tcx, cgu, & llvm_module) ;
105+
106+ // Declare and store globals shared by all offload kernels
107+ //
108+ // These globals are left in the LLVM-IR host module so all kernels can access them.
109+ // They are necessary for correct offload execution. We do this here to simplify the
110+ // `offload` intrinsic, avoiding the need for tracking whether it's the first
111+ // intrinsic call or not.
112+ let has_host_offload = cx
113+ . sess ( )
114+ . opts
115+ . unstable_opts
116+ . offload
117+ . iter ( )
118+ . any ( |o| matches ! ( o, Offload :: Host ( _) | Offload :: Test ) ) ;
119+ if has_host_offload && !cx. sess ( ) . target . is_like_gpu {
120+ cx. offload_globals . replace ( Some ( OffloadGlobals :: declare ( & cx) ) ) ;
121+ }
130122
131- // Define Objective-C module info and module flags. Note, the module info will
132- // also be added to the `llvm.compiler.used` variable, created later.
133- //
134- // These are only necessary when we need the linker to do its Objective-C-specific
135- // magic. We could theoretically do it unconditionally, but at a slight cost to linker
136- // performance in the common case where it's unnecessary.
137- if !cx. objc_classrefs . borrow ( ) . is_empty ( ) || !cx. objc_selrefs . borrow ( ) . is_empty ( ) {
138- if cx. objc_abi_version ( ) == 1 {
139- cx. define_objc_module_info ( ) ;
123+ let mono_items = cx. codegen_unit . items_in_deterministic_order ( cx. tcx ) ;
124+ for & ( mono_item, data) in & mono_items {
125+ mono_item. predefine :: < Builder < ' _ , ' _ , ' _ > > (
126+ & mut cx,
127+ cgu_name. as_str ( ) ,
128+ data. linkage ,
129+ data. visibility ,
130+ ) ;
140131 }
141- cx. add_objc_module_flags ( ) ;
142- }
143132
144- // Finalize code coverage by injecting the coverage map. Note, the coverage map will
145- // also be added to the `llvm.compiler.used` variable, created next.
146- if cx. sess ( ) . instrument_coverage ( ) {
147- cx. coverageinfo_finalize ( ) ;
148- }
133+ // ... and now that we have everything pre-defined, fill out those definitions.
134+ for & ( mono_item, item_data) in & mono_items {
135+ mono_item. define :: < Builder < ' _ , ' _ , ' _ > > ( & mut cx, cgu_name. as_str ( ) , item_data) ;
136+ }
149137
150- // Create the llvm.used variable.
151- if !cx. used_statics . is_empty ( ) {
152- cx. create_used_variable_impl ( c"llvm.used" , & cx. used_statics ) ;
153- }
138+ // If this codegen unit contains the main function, also create the
139+ // wrapper here
140+ if let Some ( entry) =
141+ maybe_create_entry_wrapper :: < Builder < ' _ , ' _ , ' _ > > ( & cx, cx. codegen_unit )
142+ {
143+ let attrs = attributes:: sanitize_attrs ( & cx, tcx, SanitizerFnAttrs :: default ( ) ) ;
144+ attributes:: apply_to_llfn ( entry, llvm:: AttributePlace :: Function , & attrs) ;
145+ }
154146
155- // Create the llvm.compiler.used variable.
156- {
157- let compiler_used_statics = cx. compiler_used_statics . borrow ( ) ;
158- if !compiler_used_statics. is_empty ( ) {
159- cx. create_used_variable_impl ( c"llvm.compiler.used" , & compiler_used_statics) ;
147+ // Define Objective-C module info and module flags. Note, the module info will
148+ // also be added to the `llvm.compiler.used` variable, created later.
149+ //
150+ // These are only necessary when we need the linker to do its Objective-C-specific
151+ // magic. We could theoretically do it unconditionally, but at a slight cost to linker
152+ // performance in the common case where it's unnecessary.
153+ if !cx. objc_classrefs . borrow ( ) . is_empty ( ) || !cx. objc_selrefs . borrow ( ) . is_empty ( ) {
154+ if cx. objc_abi_version ( ) == 1 {
155+ cx. define_objc_module_info ( ) ;
156+ }
157+ cx. add_objc_module_flags ( ) ;
160158 }
161- }
162159
163- // Run replace-all-uses-with for statics that need it. This must
164- // happen after the llvm.used variables are created.
165- for & ( old_g, new_g) in cx. statics_to_rauw ( ) . borrow ( ) . iter ( ) {
166- unsafe {
167- llvm:: LLVMReplaceAllUsesWith ( old_g, new_g) ;
168- llvm:: LLVMDeleteGlobal ( old_g) ;
160+ // Finalize code coverage by injecting the coverage map. Note, the coverage map will
161+ // also be added to the `llvm.compiler.used` variable, created next.
162+ if cx. sess ( ) . instrument_coverage ( ) {
163+ cx. coverageinfo_finalize ( ) ;
164+ }
165+
166+ // Create the llvm.used variable.
167+ if !cx. used_statics . is_empty ( ) {
168+ cx. create_used_variable_impl ( c"llvm.used" , & cx. used_statics ) ;
169+ }
170+
171+ // Create the llvm.compiler.used variable.
172+ {
173+ let compiler_used_statics = cx. compiler_used_statics . borrow ( ) ;
174+ if !compiler_used_statics. is_empty ( ) {
175+ cx. create_used_variable_impl ( c"llvm.compiler.used" , & compiler_used_statics) ;
176+ }
177+ }
178+
179+ // Run replace-all-uses-with for statics that need it. This must
180+ // happen after the llvm.used variables are created.
181+ for & ( old_g, new_g) in cx. statics_to_rauw ( ) . borrow ( ) . iter ( ) {
182+ unsafe {
183+ llvm:: LLVMReplaceAllUsesWith ( old_g, new_g) ;
184+ llvm:: LLVMDeleteGlobal ( old_g) ;
185+ }
169186 }
170- }
171187
172- // Finalize debuginfo
173- if cx. sess ( ) . opts . debuginfo != DebugInfo :: None {
174- cx. debuginfo_finalize ( ) ;
188+ // Finalize debuginfo
189+ if cx. sess ( ) . opts . debuginfo != DebugInfo :: None {
190+ cx. debuginfo_finalize ( ) ;
191+ }
175192 }
176- }
177193
178- ModuleCodegen :: new_regular ( cgu_name. to_string ( ) , llvm_module)
194+ ModuleCodegen :: new_regular ( cgu_name. to_string ( ) , llvm_module)
195+ }
179196 }
180197
198+ let ( module, _) =
199+ tcx. dep_graph . with_task :: < _ , _ , CompileCguHashHelper > ( dep_node, tcx, cgu_name) ;
200+ let time_to_codegen = start_time. elapsed ( ) ;
201+
202+ // We assume that the cost to run LLVM on a CGU is proportional to
203+ // the time we needed for codegenning it.
204+ let cost = time_to_codegen. as_nanos ( ) as u64 ;
205+
181206 ( module, cost)
182207}
183208
0 commit comments