use std::path::PathBuf;
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_codegen_ssa::back::linker::LinkerInfo;
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use crate::{prelude::*, BackendConfig};
-fn new_module(tcx: TyCtxt<'_>, name: String) -> ObjectModule {
- let module = crate::backend::make_module(tcx.sess, name);
- assert_eq!(pointer_ty(tcx), module.target_config().pointer_type());
- module
-}
-
struct ModuleCodegenResult(CompiledModule, Option<(WorkProductId, WorkProduct)>);
impl<HCX> HashStable<HCX> for ModuleCodegenResult {
fn emit_module(
tcx: TyCtxt<'_>,
+ backend_config: &BackendConfig,
name: String,
kind: ModuleKind,
module: ObjectModule,
debug: Option<DebugContext<'_>>,
- unwind_context: UnwindContext<'_>,
+ unwind_context: UnwindContext,
) -> ModuleCodegenResult {
let mut product = module.finish();
unwind_context.emit(&mut product);
- let tmp_file = tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(&name));
+ let tmp_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(&name));
let obj = product.object.write().unwrap();
if let Err(err) = std::fs::write(&tmp_file, obj) {
tcx.sess.fatal(&format!("error writing object file: {}", err));
}
- let work_product = if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() {
+ let work_product = if backend_config.disable_incr_cache {
None
} else {
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
let mut object = None;
let work_product = cgu.work_product(tcx);
if let Some(saved_file) = &work_product.saved_file {
- let obj_out = tcx
- .output_filenames(LOCAL_CRATE)
- .temp_path(OutputType::Object, Some(&cgu.name().as_str()));
+ let obj_out =
+ tcx.output_filenames(()).temp_path(OutputType::Object, Some(&cgu.name().as_str()));
object = Some(obj_out.clone());
let source_file = rustc_incremental::in_incr_comp_dir(&incr_comp_session_dir, &saved_file);
if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
let cgu = tcx.codegen_unit(cgu_name);
let mono_items = cgu.items_in_deterministic_order(tcx);
- let mut module = new_module(tcx, cgu_name.as_str().to_string());
+ let isa = crate::build_isa(tcx.sess, &backend_config);
+ let mut module = crate::backend::make_module(tcx.sess, isa, cgu_name.as_str().to_string());
let mut cx = crate::CodegenCx::new(
tcx,
- backend_config,
- &mut module,
+ backend_config.clone(),
+ module.isa(),
tcx.sess.opts.debuginfo != DebugInfo::None,
);
- super::predefine_mono_items(&mut cx, &mono_items);
+ super::predefine_mono_items(tcx, &mut module, &mono_items);
for (mono_item, _) in mono_items {
match mono_item {
MonoItem::Fn(inst) => {
- cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst));
- }
- MonoItem::Static(def_id) => {
- crate::constant::codegen_static(&mut cx.constants_cx, def_id)
+ cx.tcx
+ .sess
+ .time("codegen fn", || crate::base::codegen_fn(&mut cx, &mut module, inst));
}
+ MonoItem::Static(def_id) => crate::constant::codegen_static(tcx, &mut module, def_id),
MonoItem::GlobalAsm(item_id) => {
let item = cx.tcx.hir().item(item_id);
- if let rustc_hir::ItemKind::GlobalAsm(rustc_hir::GlobalAsm { asm }) = item.kind {
- cx.global_asm.push_str(&*asm.as_str());
- cx.global_asm.push_str("\n\n");
+ if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind {
+ if !asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
+ cx.global_asm.push_str("\n.intel_syntax noprefix\n");
+ } else {
+ cx.global_asm.push_str("\n.att_syntax\n");
+ }
+ for piece in asm.template {
+ match *piece {
+ InlineAsmTemplatePiece::String(ref s) => cx.global_asm.push_str(s),
+ InlineAsmTemplatePiece::Placeholder { .. } => todo!(),
+ }
+ }
+ cx.global_asm.push_str("\n.att_syntax\n\n");
} else {
bug!("Expected GlobalAsm found {:?}", item);
}
}
}
}
- let (global_asm, debug, mut unwind_context) =
- tcx.sess.time("finalize CodegenCx", || cx.finalize());
- crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, &mut unwind_context);
-
- let codegen_result = emit_module(
+ crate::main_shim::maybe_create_entry_wrapper(
tcx,
- cgu.name().as_str().to_string(),
- ModuleKind::Regular,
- module,
- debug,
- unwind_context,
+ &mut module,
+ &mut cx.unwind_context,
+ false,
+ cgu.is_primary(),
);
- codegen_global_asm(tcx, &cgu.name().as_str(), &global_asm);
+ let debug_context = cx.debug_context;
+ let unwind_context = cx.unwind_context;
+ let codegen_result = tcx.sess.time("write object file", || {
+ emit_module(
+ tcx,
+ &backend_config,
+ cgu.name().as_str().to_string(),
+ ModuleKind::Regular,
+ module,
+ debug_context,
+ unwind_context,
+ )
+ });
+
+ codegen_global_asm(tcx, &cgu.name().as_str(), &cx.global_asm);
codegen_result
}
-pub(super) fn run_aot(
+pub(crate) fn run_aot(
tcx: TyCtxt<'_>,
backend_config: BackendConfig,
metadata: EncodedMetadata,
need_metadata_module: bool,
) -> Box<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)> {
- use rustc_span::symbol::sym;
-
- let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
- let subsystem = tcx.sess.first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
- let windows_subsystem = subsystem.map(|subsystem| {
- if subsystem != sym::windows && subsystem != sym::console {
- tcx.sess.fatal(&format!(
- "invalid windows subsystem `{}`, only \
- `windows` and `console` are allowed",
- subsystem
- ));
- }
- subsystem.to_string()
- });
-
let mut work_products = FxHashMap::default();
let cgus = if tcx.sess.opts.output_types.should_codegen() {
- tcx.collect_and_partition_mono_items(LOCAL_CRATE).1
+ tcx.collect_and_partition_mono_items(()).1
} else {
// If only `--emit metadata` is used, we shouldn't perform any codegen.
// Also `tcx.collect_and_partition_mono_items` may panic in that case.
}
}
- let modules = super::time(tcx, "codegen mono items", || {
+ let modules = super::time(tcx, backend_config.display_cg_time, "codegen mono items", || {
cgus.iter()
.map(|cgu| {
let cgu_reuse = determine_cgu_reuse(tcx, cgu);
tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
match cgu_reuse {
- _ if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() => {}
+ _ if backend_config.disable_incr_cache => {}
CguReuse::No => {}
CguReuse::PreLto => {
return reuse_workproduct_for_cgu(tcx, &*cgu, &mut work_products);
let (ModuleCodegenResult(module, work_product), _) = tcx.dep_graph.with_task(
dep_node,
tcx,
- (backend_config, cgu.name()),
+ (backend_config.clone(), cgu.name()),
module_codegen,
rustc_middle::dep_graph::hash_result,
);
tcx.sess.abort_if_errors();
- let mut allocator_module = new_module(tcx, "allocator_shim".to_string());
+ let isa = crate::build_isa(tcx.sess, &backend_config);
+ let mut allocator_module =
+ crate::backend::make_module(tcx.sess, isa, "allocator_shim".to_string());
+ assert_eq!(pointer_ty(tcx), allocator_module.target_config().pointer_type());
let mut allocator_unwind_context = UnwindContext::new(tcx, allocator_module.isa(), true);
let created_alloc_shim =
crate::allocator::codegen(tcx, &mut allocator_module, &mut allocator_unwind_context);
let allocator_module = if created_alloc_shim {
let ModuleCodegenResult(module, work_product) = emit_module(
tcx,
+ &backend_config,
"allocator_shim".to_string(),
ModuleKind::Allocator,
allocator_module,
.as_str()
.to_string();
- let tmp_file = tcx
- .output_filenames(LOCAL_CRATE)
- .temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
+ let tmp_file =
+ tcx.output_filenames(()).temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
let obj = crate::backend::with_object(tcx.sess, &metadata_cgu_name, |object| {
crate::metadata::write_metadata(tcx, object);
Box::new((
CodegenResults {
- crate_name: tcx.crate_name(LOCAL_CRATE),
modules,
allocator_module,
metadata_module,
metadata,
- windows_subsystem,
- linker_info: LinkerInfo::new(tcx),
+ linker_info: LinkerInfo::new(tcx, crate::target_triple(tcx.sess).to_string()),
crate_info: CrateInfo::new(tcx),
},
work_products,
.collect::<Vec<_>>()
.join("\n");
- let output_object_file =
- tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(cgu_name));
+ let output_object_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu_name));
// Assemble `global_asm`
let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");