]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_gcc/src/base.rs
Auto merge of #105712 - amg98:feat/vita-support, r=wesleywiser
[rust.git] / compiler / rustc_codegen_gcc / src / base.rs
1 use std::env;
2 use std::time::Instant;
3
4 use gccjit::{
5     Context,
6     FunctionType,
7     GlobalKind,
8 };
9 use rustc_middle::dep_graph;
10 use rustc_middle::ty::TyCtxt;
11 use rustc_middle::mir::mono::Linkage;
12 use rustc_codegen_ssa::{ModuleCodegen, ModuleKind};
13 use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
14 use rustc_codegen_ssa::mono_item::MonoItemExt;
15 use rustc_codegen_ssa::traits::DebugInfoMethods;
16 use rustc_session::config::DebugInfo;
17 use rustc_span::Symbol;
18
19 use crate::GccContext;
20 use crate::builder::Builder;
21 use crate::context::CodegenCx;
22
23 pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind {
24     match linkage {
25         Linkage::External => GlobalKind::Imported,
26         Linkage::AvailableExternally => GlobalKind::Imported,
27         Linkage::LinkOnceAny => unimplemented!(),
28         Linkage::LinkOnceODR => unimplemented!(),
29         Linkage::WeakAny => unimplemented!(),
30         Linkage::WeakODR => unimplemented!(),
31         Linkage::Appending => unimplemented!(),
32         Linkage::Internal => GlobalKind::Internal,
33         Linkage::Private => GlobalKind::Internal,
34         Linkage::ExternalWeak => GlobalKind::Imported, // TODO(antoyo): should be weak linkage.
35         Linkage::Common => unimplemented!(),
36     }
37 }
38
39 pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType {
40     match linkage {
41         Linkage::External => FunctionType::Exported,
42         Linkage::AvailableExternally => FunctionType::Extern,
43         Linkage::LinkOnceAny => unimplemented!(),
44         Linkage::LinkOnceODR => unimplemented!(),
45         Linkage::WeakAny => FunctionType::Exported, // FIXME(antoyo): should be similar to linkonce.
46         Linkage::WeakODR => unimplemented!(),
47         Linkage::Appending => unimplemented!(),
48         Linkage::Internal => FunctionType::Internal,
49         Linkage::Private => FunctionType::Internal,
50         Linkage::ExternalWeak => unimplemented!(),
51         Linkage::Common => unimplemented!(),
52     }
53 }
54
55 pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, supports_128bit_integers: bool) -> (ModuleCodegen<GccContext>, u64) {
56     let prof_timer = tcx.prof.generic_activity("codegen_module");
57     let start_time = Instant::now();
58
59     let dep_node = tcx.codegen_unit(cgu_name).codegen_dep_node(tcx);
60     let (module, _) = tcx.dep_graph.with_task(
61         dep_node,
62         tcx,
63         (cgu_name, supports_128bit_integers),
64         module_codegen,
65         Some(dep_graph::hash_result),
66     );
67     let time_to_codegen = start_time.elapsed();
68     drop(prof_timer);
69
70     // We assume that the cost to run GCC on a CGU is proportional to
71     // the time we needed for codegenning it.
72     let cost = time_to_codegen.as_secs() * 1_000_000_000 + time_to_codegen.subsec_nanos() as u64;
73
74     fn module_codegen(tcx: TyCtxt<'_>, (cgu_name, supports_128bit_integers): (Symbol, bool)) -> ModuleCodegen<GccContext> {
75         let cgu = tcx.codegen_unit(cgu_name);
76         // Instantiate monomorphizations without filling out definitions yet...
77         //let llvm_module = ModuleLlvm::new(tcx, &cgu_name.as_str());
78         let context = Context::default();
79         // TODO(antoyo): only set on x86 platforms.
80         context.add_command_line_option("-masm=intel");
81         // TODO(antoyo): only add the following cli argument if the feature is supported.
82         context.add_command_line_option("-msse2");
83         context.add_command_line_option("-mavx2");
84         context.add_command_line_option("-msha");
85         context.add_command_line_option("-mpclmul");
86         // FIXME(antoyo): the following causes an illegal instruction on vmovdqu64 in std_example on my CPU.
87         // Only add if the CPU supports it.
88         //context.add_command_line_option("-mavx512f");
89         for arg in &tcx.sess.opts.cg.llvm_args {
90             context.add_command_line_option(arg);
91         }
92         // NOTE: This is needed to compile the file src/intrinsic/archs.rs during a bootstrap of rustc.
93         context.add_command_line_option("-fno-var-tracking-assignments");
94         // NOTE: an optimization (https://github.com/rust-lang/rustc_codegen_gcc/issues/53).
95         context.add_command_line_option("-fno-semantic-interposition");
96         // NOTE: Rust relies on LLVM not doing TBAA (https://github.com/rust-lang/unsafe-code-guidelines/issues/292).
97         context.add_command_line_option("-fno-strict-aliasing");
98
99         if tcx.sess.opts.unstable_opts.function_sections.unwrap_or(tcx.sess.target.function_sections) {
100             context.add_command_line_option("-ffunction-sections");
101             context.add_command_line_option("-fdata-sections");
102         }
103
104         if env::var("CG_GCCJIT_DUMP_CODE").as_deref() == Ok("1") {
105             context.set_dump_code_on_compile(true);
106         }
107         if env::var("CG_GCCJIT_DUMP_GIMPLE").as_deref() == Ok("1") {
108             context.set_dump_initial_gimple(true);
109         }
110         context.set_debug_info(true);
111         if env::var("CG_GCCJIT_DUMP_EVERYTHING").as_deref() == Ok("1") {
112             context.set_dump_everything(true);
113         }
114         if env::var("CG_GCCJIT_KEEP_INTERMEDIATES").as_deref() == Ok("1") {
115             context.set_keep_intermediates(true);
116         }
117
118         // TODO(bjorn3): Remove once unwinding is properly implemented
119         context.set_allow_unreachable_blocks(true);
120
121         {
122             let cx = CodegenCx::new(&context, cgu, tcx, supports_128bit_integers);
123
124             let mono_items = cgu.items_in_deterministic_order(tcx);
125             for &(mono_item, (linkage, visibility)) in &mono_items {
126                 mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
127             }
128
129             // ... and now that we have everything pre-defined, fill out those definitions.
130             for &(mono_item, _) in &mono_items {
131                 mono_item.define::<Builder<'_, '_, '_>>(&cx);
132             }
133
134             // If this codegen unit contains the main function, also create the
135             // wrapper here
136             maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx);
137
138             // Finalize debuginfo
139             if cx.sess().opts.debuginfo != DebugInfo::None {
140                 cx.debuginfo_finalize();
141             }
142         }
143
144         ModuleCodegen {
145             name: cgu_name.to_string(),
146             module_llvm: GccContext {
147                 context
148             },
149             kind: ModuleKind::Regular,
150         }
151     }
152
153     (module, cost)
154 }