Correctly handle the relocation model for LTO
This commit is contained in:
parent
423701a3cf
commit
0d47dc0cf0
4 changed files with 42 additions and 21 deletions
|
@ -35,6 +35,7 @@ use rustc_middle::bug;
|
|||
use rustc_middle::dep_graph::WorkProduct;
|
||||
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
|
||||
use rustc_session::config::{CrateType, Lto};
|
||||
use rustc_target::spec::RelocModel;
|
||||
use tempfile::{TempDir, tempdir};
|
||||
|
||||
use crate::back::write::save_temp_bitcode;
|
||||
|
@ -632,7 +633,13 @@ pub unsafe fn optimize_thin_module(
|
|||
}
|
||||
};
|
||||
let module = ModuleCodegen {
|
||||
module_llvm: GccContext { context, should_combine_object_files, temp_dir: None },
|
||||
module_llvm: GccContext {
|
||||
context,
|
||||
should_combine_object_files,
|
||||
// TODO(antoyo): use the correct relocation model here.
|
||||
relocation_model: RelocModel::Pic,
|
||||
temp_dir: None,
|
||||
},
|
||||
name: thin_module.name().to_string(),
|
||||
kind: ModuleKind::Regular,
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@ use rustc_session::config::OutputType;
|
|||
use rustc_span::fatal_error::FatalError;
|
||||
use rustc_target::spec::SplitDebuginfo;
|
||||
|
||||
use crate::base::add_pic_option;
|
||||
use crate::errors::CopyBitcode;
|
||||
use crate::{GccCodegenBackend, GccContext};
|
||||
|
||||
|
@ -159,7 +160,7 @@ pub(crate) unsafe fn codegen(
|
|||
|
||||
// NOTE: without -fuse-linker-plugin, we get the following error:
|
||||
// lto1: internal compiler error: decompressed stream: Destination buffer is too small
|
||||
// TODO: since we do not do LTO when the linker is invoked anymore, perhaps
|
||||
// TODO(antoyo): since we do not do LTO when the linker is invoked anymore, perhaps
|
||||
// the following flag is not necessary anymore.
|
||||
context.add_driver_option("-fuse-linker-plugin");
|
||||
}
|
||||
|
@ -185,7 +186,7 @@ pub(crate) unsafe fn codegen(
|
|||
// flags, it combines the .o files together in another .o.
|
||||
context.compile_to_file(OutputKind::Executable, <o_path);
|
||||
|
||||
let context = Context::default(); // TODO: might need to set some other flags from new_context.
|
||||
let context = Context::default();
|
||||
if cgcx.target_arch == "x86" || cgcx.target_arch == "x86_64" {
|
||||
// NOTE: it seems we need to use add_driver_option instead of
|
||||
// add_command_line_option here because we use the LTO frontend via gcc.
|
||||
|
@ -195,12 +196,9 @@ pub(crate) unsafe fn codegen(
|
|||
// NOTE: these two options are needed to invoke LTO to produce an object file.
|
||||
// We need to initiate a second compilation because the arguments "-x lto"
|
||||
// needs to be at the very beginning.
|
||||
// TODO TODO: check that LTO still does the optimizations across different
|
||||
// object files with this change.
|
||||
// TODO: this should probably be in a condition `if fat_lto`.
|
||||
context.add_driver_option("-x");
|
||||
context.add_driver_option("lto");
|
||||
context.add_driver_option("-fPIC"); // TODO TODO: only add this flag when necessary.
|
||||
add_pic_option(&context, module.module_llvm.relocation_model);
|
||||
context.add_driver_option(lto_path);
|
||||
|
||||
context.compile_to_file(OutputKind::ObjectFile, path);
|
||||
|
|
39
src/base.rs
39
src/base.rs
|
@ -3,7 +3,7 @@ use std::env;
|
|||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
use gccjit::{CType, FunctionType, GlobalKind};
|
||||
use gccjit::{CType, Context, FunctionType, GlobalKind};
|
||||
use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
|
||||
use rustc_codegen_ssa::mono_item::MonoItemExt;
|
||||
use rustc_codegen_ssa::traits::DebugInfoCodegenMethods;
|
||||
|
@ -15,9 +15,9 @@ use rustc_middle::mir::mono::Visibility;
|
|||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::DebugInfo;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_target::spec::SymbolVisibility;
|
||||
use rustc_target::spec::{PanicStrategy, RelocModel};
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::context::CodegenCx;
|
||||
|
@ -151,18 +151,7 @@ pub fn compile_codegen_unit(
|
|||
});
|
||||
}
|
||||
|
||||
match tcx.sess.relocation_model() {
|
||||
rustc_target::spec::RelocModel::Static => {
|
||||
context.add_command_line_option("-fno-pie");
|
||||
}
|
||||
rustc_target::spec::RelocModel::Pic => {
|
||||
context.add_command_line_option("-fPIC");
|
||||
}
|
||||
rustc_target::spec::RelocModel::Pie => {
|
||||
context.add_command_line_option("-fPIE");
|
||||
}
|
||||
model => eprintln!("Unsupported relocation model: {:?}", model),
|
||||
}
|
||||
add_pic_option(&context, tcx.sess.relocation_model());
|
||||
|
||||
let target_cpu = gcc_util::target_cpu(tcx.sess);
|
||||
if target_cpu != "generic" {
|
||||
|
@ -256,6 +245,7 @@ pub fn compile_codegen_unit(
|
|||
name: cgu_name.to_string(),
|
||||
module_llvm: GccContext {
|
||||
context: Arc::new(SyncContext::new(context)),
|
||||
relocation_model: tcx.sess.relocation_model(),
|
||||
should_combine_object_files: false,
|
||||
temp_dir: None,
|
||||
},
|
||||
|
@ -265,3 +255,24 @@ pub fn compile_codegen_unit(
|
|||
|
||||
(module, cost)
|
||||
}
|
||||
|
||||
pub fn add_pic_option<'gcc>(context: &Context<'gcc>, relocation_model: RelocModel) {
|
||||
match relocation_model {
|
||||
rustc_target::spec::RelocModel::Static => {
|
||||
context.add_command_line_option("-fno-pie");
|
||||
context.add_driver_option("-fno-pie");
|
||||
}
|
||||
rustc_target::spec::RelocModel::Pic => {
|
||||
context.add_command_line_option("-fPIC");
|
||||
// NOTE: we use both add_command_line_option and add_driver_option because the usage in
|
||||
// this module (compile_codegen_unit) requires add_command_line_option while the usage
|
||||
// in the back::write module (codegen) requires add_driver_option.
|
||||
context.add_driver_option("-fPIC");
|
||||
}
|
||||
rustc_target::spec::RelocModel::Pie => {
|
||||
context.add_command_line_option("-fPIE");
|
||||
context.add_driver_option("-fPIE");
|
||||
}
|
||||
model => eprintln!("Unsupported relocation model: {:?}", model),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ use rustc_session::Session;
|
|||
use rustc_session::config::{Lto, OptLevel, OutputFilenames};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::fatal_error::FatalError;
|
||||
use rustc_target::spec::RelocModel;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::back::lto::ModuleBuffer;
|
||||
|
@ -298,6 +299,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
|
|||
) -> Self::Module {
|
||||
let mut mods = GccContext {
|
||||
context: Arc::new(SyncContext::new(new_context(tcx))),
|
||||
relocation_model: tcx.sess.relocation_model(),
|
||||
should_combine_object_files: false,
|
||||
temp_dir: None,
|
||||
};
|
||||
|
@ -329,6 +331,9 @@ impl ExtraBackendMethods for GccCodegenBackend {
|
|||
|
||||
pub struct GccContext {
|
||||
context: Arc<SyncContext>,
|
||||
/// This field is needed in order to be able to set the flag -fPIC when necessary when doing
|
||||
/// LTO.
|
||||
relocation_model: RelocModel,
|
||||
should_combine_object_files: bool,
|
||||
// Temporary directory used by LTO. We keep it here so that it's not removed before linking.
|
||||
temp_dir: Option<TempDir>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue