Skip to content

Commit bdbee63

Browse files
committed
Separate out methods for running thin and fat LTO
1 parent a17de69 commit bdbee63

File tree

4 files changed

+74
-47
lines changed

4 files changed

+74
-47
lines changed

src/librustc_codegen_llvm/back/lto.rs

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,11 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {
4848
}
4949
}
5050

51-
/// Performs LTO, which in the case of full LTO means merging all modules into
52-
/// a single one and returning it for further optimizing. For ThinLTO, it will
53-
/// do the global analysis necessary and return two lists, one of the modules
54-
/// the need optimization and another for modules that can simply be copied over
55-
/// from the incr. comp. cache.
56-
pub(crate) fn run(cgcx: &CodegenContext<LlvmCodegenBackend>,
57-
modules: Vec<ModuleCodegen<ModuleLlvm>>,
58-
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
59-
timeline: &mut Timeline)
60-
-> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError>
51+
fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
52+
timeline: &mut Timeline,
53+
diag_handler: &Handler)
54+
-> Result<(Vec<CString>, Vec<(SerializedModule<ModuleBuffer>, CString)>), FatalError>
6155
{
62-
let diag_handler = cgcx.create_diag_handler();
6356
let export_threshold = match cgcx.lto {
6457
// We're just doing LTO for our one crate
6558
Lto::ThinLocal => SymbolExportLevel::Rust,
@@ -144,36 +137,56 @@ pub(crate) fn run(cgcx: &CodegenContext<LlvmCodegenBackend>,
144137
}
145138
}
146139

140+
Ok((symbol_white_list, upstream_modules))
141+
}
142+
143+
/// Performs fat LTO by merging all modules into a single one and returning it
144+
/// for further optimization.
145+
pub(crate) fn run_fat(cgcx: &CodegenContext<LlvmCodegenBackend>,
146+
modules: Vec<ModuleCodegen<ModuleLlvm>>,
147+
_cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
148+
timeline: &mut Timeline)
149+
-> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError>
150+
{
151+
let diag_handler = cgcx.create_diag_handler();
152+
let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?;
147153
let symbol_white_list = symbol_white_list.iter()
148154
.map(|c| c.as_ptr())
149155
.collect::<Vec<_>>();
150-
match cgcx.lto {
151-
Lto::Fat => {
152-
assert!(cached_modules.is_empty());
153-
let opt_jobs = fat_lto(cgcx,
154-
&diag_handler,
155-
modules,
156-
upstream_modules,
157-
&symbol_white_list,
158-
timeline);
159-
opt_jobs.map(|opt_jobs| (opt_jobs, vec![]))
160-
}
161-
Lto::Thin |
162-
Lto::ThinLocal => {
163-
if cgcx.opts.debugging_opts.cross_lang_lto.enabled() {
164-
unreachable!("We should never reach this case if the LTO step \
165-
is deferred to the linker");
166-
}
167-
thin_lto(cgcx,
168-
&diag_handler,
169-
modules,
170-
upstream_modules,
171-
cached_modules,
172-
&symbol_white_list,
173-
timeline)
174-
}
175-
Lto::No => unreachable!(),
156+
let opt_jobs = fat_lto(cgcx,
157+
&diag_handler,
158+
modules,
159+
upstream_modules,
160+
&symbol_white_list,
161+
timeline);
162+
opt_jobs.map(|opt_jobs| (opt_jobs, vec![]))
163+
}
164+
165+
/// Performs thin LTO by performing necessary global analysis and returning two
166+
/// lists, one of the modules that need optimization and another for modules that
167+
/// can simply be copied over from the incr. comp. cache.
168+
pub(crate) fn run_thin(cgcx: &CodegenContext<LlvmCodegenBackend>,
169+
modules: Vec<ModuleCodegen<ModuleLlvm>>,
170+
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
171+
timeline: &mut Timeline)
172+
-> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError>
173+
{
174+
let diag_handler = cgcx.create_diag_handler();
175+
let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?;
176+
let symbol_white_list = symbol_white_list.iter()
177+
.map(|c| c.as_ptr())
178+
.collect::<Vec<_>>();
179+
if cgcx.opts.debugging_opts.cross_lang_lto.enabled() {
180+
unreachable!("We should never reach this case if the LTO step \
181+
is deferred to the linker");
176182
}
183+
thin_lto(cgcx,
184+
&diag_handler,
185+
modules,
186+
upstream_modules,
187+
cached_modules,
188+
&symbol_white_list,
189+
timeline)
177190
}
178191

179192
fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,

src/librustc_codegen_llvm/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,21 @@ impl WriteBackendMethods for LlvmCodegenBackend {
176176
fn print_pass_timings(&self) {
177177
unsafe { llvm::LLVMRustPrintPassTimings(); }
178178
}
179-
fn run_lto(
179+
fn run_fat_lto(
180180
cgcx: &CodegenContext<Self>,
181181
modules: Vec<ModuleCodegen<Self::Module>>,
182182
cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
183183
timeline: &mut Timeline
184184
) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError> {
185-
back::lto::run(cgcx, modules, cached_modules, timeline)
185+
back::lto::run_fat(cgcx, modules, cached_modules, timeline)
186+
}
187+
fn run_thin_lto(
188+
cgcx: &CodegenContext<Self>,
189+
modules: Vec<ModuleCodegen<Self::Module>>,
190+
cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
191+
timeline: &mut Timeline
192+
) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError> {
193+
back::lto::run_thin(cgcx, modules, cached_modules, timeline)
186194
}
187195
unsafe fn optimize(
188196
cgcx: &CodegenContext<Self>,

src/librustc_codegen_ssa/back/write.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,11 @@ fn generate_lto_work<B: ExtraBackendMethods>(
264264

265265
let (lto_modules, copy_jobs) = if !needs_fat_lto.is_empty() {
266266
assert!(needs_thin_lto.is_empty());
267-
B::run_lto(cgcx, needs_fat_lto, import_only_modules, &mut timeline)
267+
B::run_fat_lto(cgcx, needs_fat_lto, import_only_modules, &mut timeline)
268268
.unwrap_or_else(|e| e.raise())
269269
} else {
270270
assert!(needs_fat_lto.is_empty());
271-
B::run_lto(cgcx, needs_thin_lto, import_only_modules, &mut timeline)
271+
B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules, &mut timeline)
272272
.unwrap_or_else(|e| e.raise())
273273
};
274274

src/librustc_codegen_ssa/traits/write.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,18 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
2424
type ThinData: Send + Sync;
2525
type ThinBuffer: ThinBufferMethods;
2626

27-
/// Performs LTO, which in the case of full LTO means merging all modules into
28-
/// a single one and returning it for further optimizing. For ThinLTO, it will
29-
/// do the global analysis necessary and return two lists, one of the modules
30-
/// the need optimization and another for modules that can simply be copied over
31-
/// from the incr. comp. cache.
32-
fn run_lto(
27+
/// Performs fat LTO by merging all modules into a single one and returning it
28+
/// for further optimization.
29+
fn run_fat_lto(
30+
cgcx: &CodegenContext<Self>,
31+
modules: Vec<ModuleCodegen<Self::Module>>,
32+
cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
33+
timeline: &mut Timeline,
34+
) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError>;
35+
/// Performs thin LTO by performing necessary global analysis and returning two
36+
/// lists, one of the modules that need optimization and another for modules that
37+
/// can simply be copied over from the incr. comp. cache.
38+
fn run_thin_lto(
3339
cgcx: &CodegenContext<Self>,
3440
modules: Vec<ModuleCodegen<Self::Module>>,
3541
cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,

0 commit comments

Comments
 (0)