1 #![feature(rustc_private, never_type, decl_macro)]
2 #![allow(intra_doc_link_resolution_failure)]
5 extern crate rustc_allocator;
6 extern crate rustc_codegen_ssa;
7 extern crate rustc_codegen_utils;
8 extern crate rustc_data_structures;
9 extern crate rustc_fs_util;
10 extern crate rustc_incremental;
11 extern crate rustc_mir;
12 extern crate rustc_target;
18 use rustc::dep_graph::DepGraph;
19 use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
20 use rustc::session::config::OutputFilenames;
21 use rustc::ty::query::Providers;
22 use rustc::util::common::ErrorReported;
23 use rustc_codegen_utils::codegen_backend::CodegenBackend;
25 use cranelift::codegen::settings;
27 use crate::constant::ConstantCx;
28 use crate::prelude::*;
50 pub use std::any::Any;
51 pub use std::collections::{HashMap, HashSet};
52 pub use std::convert::TryInto;
54 pub use syntax::ast::{FloatTy, IntTy, UintTy};
55 pub use syntax::source_map::{Pos, Span, DUMMY_SP};
58 pub use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
59 pub use rustc::mir::{self, interpret::AllocId, mono::MonoItem, *};
60 pub use rustc::session::{
61 config::{CrateType, Lto},
64 pub use rustc::ty::layout::{self, Abi, LayoutOf, Scalar, Size, TyLayout, VariantIdx};
66 self, FnSig, Instance, InstanceDef, ParamEnv, PolyFnSig, Ty, TyCtxt,
67 TypeAndMut, TypeFoldable,
69 pub use rustc_data_structures::{
70 fx::{FxHashMap, FxHashSet},
74 pub use rustc_mir::monomorphize::collector;
76 pub use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
77 pub use rustc_codegen_ssa::traits::*;
78 pub use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleKind};
80 pub use cranelift::codegen::ir::{
81 condcodes::IntCC, function::Function, ExternalName, FuncRef, Inst, SourceLoc, StackSlot,
83 pub use cranelift::codegen::isa::CallConv;
84 pub use cranelift::codegen::Context;
85 pub use cranelift::prelude::*;
86 pub use cranelift_module::{
87 self, Backend, DataContext, DataId, FuncId, FuncOrDataId, Linkage, Module,
90 pub use crate::abi::*;
91 pub use crate::base::{trans_operand, trans_place};
92 pub use crate::common::*;
93 pub use crate::debuginfo::{DebugContext, FunctionDebugContext};
94 pub use crate::trap::*;
95 pub use crate::unimpl::{unimpl, with_unimpl_span};
96 pub use crate::{Caches, CodegenCx};
98 pub struct PrintOnPanic<F: Fn() -> String>(pub F);
99 impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
101 if ::std::thread::panicking() {
102 println!("{}", (self.0)());
108 pub struct Caches<'tcx> {
109 pub context: Context,
110 pub vtables: HashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), DataId>,
113 impl<'tcx> Default for Caches<'tcx> {
114 fn default() -> Self {
116 context: Context::new(),
117 vtables: HashMap::new(),
122 pub struct CodegenCx<'a, 'clif, 'tcx, B: Backend + 'static> {
123 tcx: TyCtxt<'a, 'tcx, 'tcx>,
124 module: &'clif mut Module<B>,
126 caches: Caches<'tcx>,
127 debug_context: Option<&'clif mut DebugContext<'tcx>>,
130 impl<'a, 'clif, 'tcx, B: Backend + 'static> CodegenCx<'a, 'clif, 'tcx, B> {
132 tcx: TyCtxt<'a, 'tcx, 'tcx>,
133 module: &'clif mut Module<B>,
134 debug_context: Option<&'clif mut DebugContext<'tcx>>,
139 ccx: ConstantCx::default(),
140 caches: Caches::default(),
146 self.ccx.finalize(self.tcx, self.module);
150 struct CraneliftCodegenBackend;
152 impl CodegenBackend for CraneliftCodegenBackend {
153 fn init(&self, sess: &Session) {
154 for cty in sess.opts.crate_types.iter() {
156 CrateType::Rlib | CrateType::Dylib | CrateType::Executable => {}
159 "Rustc codegen cranelift doesn't support output type {}",
166 Lto::Fat | Lto::Thin | Lto::ThinLocal => {
167 sess.warn("Rustc codegen cranelift doesn't support lto");
171 if sess.opts.cg.rpath {
172 sess.err("rpath is not yet supported");
174 if sess.opts.debugging_opts.pgo_gen.enabled() {
175 sess.err("pgo is not supported");
179 fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
180 Box::new(crate::metadata::CraneliftMetadataLoader)
183 fn provide(&self, providers: &mut Providers) {
184 rustc_codegen_utils::symbol_names::provide(providers);
185 rustc_codegen_ssa::back::symbol_export::provide(providers);
187 providers.target_features_whitelist = |tcx, _cnum| tcx.arena.alloc(FxHashMap::default());
189 fn provide_extern(&self, providers: &mut Providers) {
190 rustc_codegen_ssa::back::symbol_export::provide_extern(providers);
193 fn codegen_crate<'a, 'tcx>(
195 tcx: TyCtxt<'a, 'tcx, 'tcx>,
196 metadata: EncodedMetadata,
197 need_metadata_module: bool,
198 _rx: mpsc::Receiver<Box<dyn Any + Send>>,
200 driver::codegen_crate(tcx, metadata, need_metadata_module)
203 fn join_codegen_and_link(
207 _dep_graph: &DepGraph,
208 outputs: &OutputFilenames,
209 ) -> Result<(), ErrorReported> {
210 use rustc_codegen_ssa::back::link::link_binary;
212 let codegen_results = *res
213 .downcast::<CodegenResults>()
214 .expect("Expected CraneliftCodegenBackend's CodegenResult, found Box<Any>");
216 let target_cpu = ::target_lexicon::HOST.to_string();
217 link_binary::<crate::archive::ArArchiveBuilder<'_>>(
221 &codegen_results.crate_name.as_str(),
229 fn target_triple(sess: &Session) -> target_lexicon::Triple {
230 let mut target = &*sess.target.target.llvm_target;
232 // FIXME add support for x86_64-apple-macosx10.7.0 to target-lexicon
233 if target.starts_with("x86_64-apple-macosx") {
234 target = "x86_64-apple-darwin";
237 target.parse().unwrap()
240 fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> {
241 let mut flags_builder = settings::builder();
242 flags_builder.enable("is_pic").unwrap();
243 flags_builder.set("probestack_enabled", "false").unwrap(); // ___cranelift_probestack is not provided
244 flags_builder.set("enable_verifier", if cfg!(debug_assertions) {
250 // FIXME enable again when https://github.com/CraneStation/cranelift/issues/664 is fixed
252 use rustc::session::config::OptLevel;
253 match sess.opts.optimize {
255 flags_builder.set("opt_level", "fastest").unwrap();
257 OptLevel::Less | OptLevel::Default => {}
258 OptLevel::Aggressive => {
259 flags_builder.set("opt_level", "best").unwrap();
261 OptLevel::Size | OptLevel::SizeMin => {
262 sess.warn("Optimizing for size is not supported. Just ignoring the request");
266 let target_triple = target_triple(sess);
267 let flags = settings::Flags::new(flags_builder);
268 cranelift::codegen::isa::lookup(target_triple)
273 /// This is the entrypoint for a hot plugged rustc_codegen_cranelift
275 pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
276 Box::new(CraneliftCodegenBackend)