rust/src/base.rs

133 lines
4.8 KiB
Rust
Raw Normal View History

2020-05-10 10:54:30 -04:00
use std::env;
use std::time::Instant;
use gccjit::{
Context,
FunctionType,
GlobalKind,
};
use rustc_middle::dep_graph;
use rustc_middle::ty::TyCtxt;
use rustc_middle::mir::mono::Linkage;
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind};
use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
use rustc_codegen_ssa::mono_item::MonoItemExt;
use rustc_codegen_ssa::traits::DebugInfoMethods;
use rustc_session::config::DebugInfo;
use rustc_span::Symbol;
use crate::GccContext;
2020-05-10 10:54:30 -04:00
use crate::builder::Builder;
use crate::context::CodegenCx;
pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind {
match linkage {
Linkage::External => GlobalKind::Imported,
Linkage::AvailableExternally => GlobalKind::Imported,
Linkage::LinkOnceAny => unimplemented!(),
Linkage::LinkOnceODR => unimplemented!(),
Linkage::WeakAny => unimplemented!(),
Linkage::WeakODR => unimplemented!(),
Linkage::Appending => unimplemented!(),
Linkage::Internal => GlobalKind::Internal,
Linkage::Private => GlobalKind::Internal,
2021-08-15 08:28:46 -04:00
Linkage::ExternalWeak => GlobalKind::Imported, // TODO(antoyo): should be weak linkage.
2020-05-10 10:54:30 -04:00
Linkage::Common => unimplemented!(),
}
}
pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType {
match linkage {
Linkage::External => FunctionType::Exported,
Linkage::AvailableExternally => FunctionType::Extern,
Linkage::LinkOnceAny => unimplemented!(),
Linkage::LinkOnceODR => unimplemented!(),
2021-08-15 08:28:46 -04:00
Linkage::WeakAny => FunctionType::Exported, // FIXME(antoyo): should be similar to linkonce.
2020-05-10 10:54:30 -04:00
Linkage::WeakODR => unimplemented!(),
Linkage::Appending => unimplemented!(),
Linkage::Internal => FunctionType::Internal,
Linkage::Private => FunctionType::Internal,
Linkage::ExternalWeak => unimplemented!(),
Linkage::Common => unimplemented!(),
}
}
pub fn compile_codegen_unit<'tcx>(tcx: TyCtxt<'tcx>, cgu_name: Symbol) -> (ModuleCodegen<GccContext>, u64) {
let prof_timer = tcx.prof.generic_activity("codegen_module");
let start_time = Instant::now();
let dep_node = tcx.codegen_unit(cgu_name).codegen_dep_node(tcx);
2021-10-16 22:31:48 +02:00
let (module, _) = tcx.dep_graph.with_task(
dep_node,
tcx,
cgu_name,
module_codegen,
Some(dep_graph::hash_result),
);
2020-05-10 10:54:30 -04:00
let time_to_codegen = start_time.elapsed();
drop(prof_timer);
// We assume that the cost to run GCC on a CGU is proportional to
// the time we needed for codegenning it.
let cost = time_to_codegen.as_secs() * 1_000_000_000 + time_to_codegen.subsec_nanos() as u64;
fn module_codegen(tcx: TyCtxt<'_>, cgu_name: Symbol) -> ModuleCodegen<GccContext> {
let cgu = tcx.codegen_unit(cgu_name);
// Instantiate monomorphizations without filling out definitions yet...
//let llvm_module = ModuleLlvm::new(tcx, &cgu_name.as_str());
let context = Context::default();
2021-08-15 08:28:46 -04:00
// TODO(antoyo): only set on x86 platforms.
2020-05-10 10:54:30 -04:00
context.add_command_line_option("-masm=intel");
for arg in &tcx.sess.opts.cg.llvm_args {
context.add_command_line_option(arg);
}
context.add_command_line_option("-fno-semantic-interposition");
2021-08-15 08:28:46 -04:00
if env::var("CG_GCCJIT_DUMP_CODE").as_deref() == Ok("1") {
context.set_dump_code_on_compile(true);
}
2020-05-10 10:54:30 -04:00
if env::var("CG_GCCJIT_DUMP_GIMPLE").as_deref() == Ok("1") {
context.set_dump_initial_gimple(true);
}
context.set_debug_info(true);
2021-08-15 08:28:46 -04:00
if env::var("CG_GCCJIT_DUMP_EVERYTHING").as_deref() == Ok("1") {
context.set_dump_everything(true);
}
if env::var("CG_GCCJIT_KEEP_INTERMEDIATES").as_deref() == Ok("1") {
context.set_keep_intermediates(true);
}
2020-05-10 10:54:30 -04:00
{
let cx = CodegenCx::new(&context, cgu, tcx);
let mono_items = cgu.items_in_deterministic_order(tcx);
for &(mono_item, (linkage, visibility)) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
}
// ... and now that we have everything pre-defined, fill out those definitions.
for &(mono_item, _) in &mono_items {
mono_item.define::<Builder<'_, '_, '_>>(&cx);
}
// If this codegen unit contains the main function, also create the
// wrapper here
maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx);
// Finalize debuginfo
if cx.sess().opts.debuginfo != DebugInfo::None {
cx.debuginfo_finalize();
}
}
ModuleCodegen {
name: cgu_name.to_string(),
module_llvm: GccContext {
context
},
kind: ModuleKind::Regular,
}
}
(module, cost)
}