1 #![feature(rustc_private, never_type, decl_macro, type_alias_impl_trait, associated_type_bounds)]
2 #![allow(intra_doc_link_resolution_failure)]
7 extern crate rustc_codegen_ssa;
8 extern crate rustc_codegen_utils;
9 extern crate rustc_data_structures;
10 extern crate rustc_driver;
11 extern crate rustc_fs_util;
12 extern crate rustc_incremental;
13 extern crate rustc_index;
14 extern crate rustc_mir;
15 extern crate rustc_target;
17 extern crate syntax_expand;
21 use rustc::dep_graph::DepGraph;
22 use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
23 use rustc::session::config::OutputFilenames;
24 use rustc::ty::query::Providers;
25 use rustc::util::common::ErrorReported;
26 use rustc_codegen_utils::codegen_backend::CodegenBackend;
28 use cranelift::codegen::settings;
30 use crate::constant::ConstantCx;
31 use crate::prelude::*;
53 mod target_features_whitelist;
61 pub use std::any::Any;
62 pub use std::collections::{HashMap, HashSet};
63 pub use std::convert::{TryFrom, TryInto};
65 pub use syntax::ast::{FloatTy, IntTy, UintTy};
66 pub use syntax::source_map::{Pos, Span, DUMMY_SP};
69 pub use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
70 pub use rustc::mir::{self, interpret::AllocId, mono::MonoItem, *};
71 pub use rustc::session::{
72 config::{CrateType, Lto},
75 pub use rustc::ty::layout::{self, Abi, LayoutOf, Scalar, Size, TyLayout, VariantIdx};
77 self, FnSig, Instance, InstanceDef, ParamEnv, PolyFnSig, Ty, TyCtxt, TypeAndMut,
81 pub use rustc_data_structures::{
82 fx::{FxHashMap, FxHashSet},
86 pub use rustc_index::vec::Idx;
88 pub use rustc_mir::monomorphize::collector;
90 pub use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
91 pub use rustc_codegen_ssa::traits::*;
92 pub use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleKind};
94 pub use cranelift::codegen::ir::{
95 condcodes::IntCC, function::Function, ExternalName, FuncRef, Inst, SourceLoc, StackSlot,
97 pub use cranelift::codegen::isa::CallConv;
98 pub use cranelift::codegen::Context;
99 pub use cranelift::prelude::*;
100 pub use cranelift_module::{
101 self, Backend, DataContext, DataId, FuncId, FuncOrDataId, Linkage, Module,
104 pub use crate::abi::*;
105 pub use crate::base::{trans_operand, trans_place};
106 pub use crate::cast::*;
107 pub use crate::common::*;
108 pub use crate::debuginfo::{DebugContext, FunctionDebugContext};
109 pub use crate::trap::*;
110 pub use crate::unimpl::unimpl;
111 pub use crate::value_and_place::{CPlace, CPlaceInner, CValue};
112 pub use crate::{Caches, CodegenCx};
114 pub struct PrintOnPanic<F: Fn() -> String>(pub F);
115 impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
117 if ::std::thread::panicking() {
118 println!("{}", (self.0)());
124 pub struct Caches<'tcx> {
125 pub context: Context,
126 pub vtables: HashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), DataId>,
129 impl Default for Caches<'_> {
130 fn default() -> Self {
132 context: Context::new(),
133 vtables: HashMap::new(),
138 pub struct CodegenCx<'clif, 'tcx, B: Backend + 'static> {
140 module: &'clif mut Module<B>,
141 constants_cx: ConstantCx,
142 caches: Caches<'tcx>,
143 debug_context: Option<&'clif mut DebugContext<'tcx>>,
146 impl<'clif, 'tcx, B: Backend + 'static> CodegenCx<'clif, 'tcx, B> {
149 module: &'clif mut Module<B>,
150 debug_context: Option<&'clif mut DebugContext<'tcx>>,
155 constants_cx: ConstantCx::default(),
156 caches: Caches::default(),
162 self.constants_cx.finalize(self.tcx, self.module);
166 struct CraneliftCodegenBackend;
168 impl CodegenBackend for CraneliftCodegenBackend {
169 fn init(&self, _sess: &Session) {}
171 fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
172 Box::new(crate::metadata::CraneliftMetadataLoader)
175 fn provide(&self, providers: &mut Providers) {
176 providers.target_features_whitelist = |tcx, cnum| {
177 assert_eq!(cnum, LOCAL_CRATE);
178 if tcx.sess.opts.actually_rustdoc {
179 // rustdoc needs to be able to document functions that use all the features, so
180 // whitelist them all
182 target_features_whitelist::all_known_features()
183 .map(|(a, b)| (a.to_string(), b))
188 target_features_whitelist::target_feature_whitelist(tcx.sess)
190 .map(|&(a, b)| (a.to_string(), b))
196 fn provide_extern(&self, _providers: &mut Providers) {}
198 fn codegen_crate<'tcx>(
201 metadata: EncodedMetadata,
202 need_metadata_module: bool,
204 rustc_codegen_utils::check_for_rustc_errors_attr(tcx);
206 let res = driver::codegen_crate(tcx, metadata, need_metadata_module);
208 rustc_incremental::assert_module_sources::assert_module_sources(tcx);
209 rustc_codegen_utils::symbol_names_test::report_symbol_names(tcx);
214 fn join_codegen_and_link(
218 _dep_graph: &DepGraph,
219 outputs: &OutputFilenames,
220 ) -> Result<(), ErrorReported> {
221 use rustc_codegen_ssa::back::link::link_binary;
223 let codegen_results = *res
224 .downcast::<CodegenResults>()
225 .expect("Expected CraneliftCodegenBackend's CodegenResult, found Box<Any>");
227 let _timer = sess.prof.generic_activity("link_crate");
229 rustc::util::common::time(sess, "linking", || {
230 let target_cpu = crate::target_triple(sess).to_string();
231 link_binary::<crate::archive::ArArchiveBuilder<'_>>(
235 &codegen_results.crate_name.as_str(),
244 fn target_triple(sess: &Session) -> target_lexicon::Triple {
245 sess.target.target.llvm_target.parse().unwrap()
248 fn default_call_conv(sess: &Session) -> CallConv {
249 CallConv::triple_default(&target_triple(sess))
252 fn build_isa(sess: &Session, enable_pic: bool) -> Box<dyn isa::TargetIsa + 'static> {
253 let mut flags_builder = settings::builder();
255 flags_builder.enable("is_pic").unwrap();
257 flags_builder.set("is_pic", "false").unwrap();
259 flags_builder.set("probestack_enabled", "false").unwrap(); // __cranelift_probestack is not provided
263 if cfg!(debug_assertions) {
271 // FIXME(CraneStation/cranelift#732) fix LICM in presence of jump tables
273 use rustc::session::config::OptLevel;
274 match sess.opts.optimize {
276 flags_builder.set("opt_level", "fastest").unwrap();
278 OptLevel::Less | OptLevel::Default => {}
279 OptLevel::Aggressive => {
280 flags_builder.set("opt_level", "best").unwrap();
282 OptLevel::Size | OptLevel::SizeMin => {
283 sess.warn("Optimizing for size is not supported. Just ignoring the request");
287 let target_triple = crate::target_triple(sess);
288 let flags = settings::Flags::new(flags_builder);
289 cranelift::codegen::isa::lookup(target_triple)
294 /// This is the entrypoint for a hot plugged rustc_codegen_cranelift
296 pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
297 Box::new(CraneliftCodegenBackend)