1 #![feature(rustc_private, decl_macro, type_alias_impl_trait, associated_type_bounds, never_type)]
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_session;
16 extern crate rustc_target;
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::*;
54 mod target_features_whitelist;
62 pub use std::any::Any;
63 pub use std::collections::{HashMap, HashSet};
64 pub use std::convert::{TryFrom, TryInto};
66 pub use syntax::ast::{FloatTy, IntTy, UintTy};
67 pub use syntax::source_map::{Pos, Span};
70 pub use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
71 pub use rustc::mir::{self, interpret::AllocId, mono::MonoItem, *};
72 pub use rustc::session::{
73 config::{CrateType, Lto},
76 pub use rustc::ty::layout::{self, Abi, LayoutOf, Scalar, Size, TyLayout, VariantIdx};
78 self, FnSig, Instance, InstanceDef, ParamEnv, PolyFnSig, Ty, TyCtxt, TypeAndMut,
82 pub use rustc_data_structures::{
83 fx::{FxHashMap, FxHashSet},
87 pub use rustc_index::vec::Idx;
89 pub use rustc_mir::monomorphize::collector;
91 pub use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
92 pub use rustc_codegen_ssa::traits::*;
93 pub use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleKind};
95 pub use cranelift_codegen::Context;
96 pub use cranelift_codegen::ir::{AbiParam, Ebb, ExternalName, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc, StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value};
97 pub use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
98 pub use cranelift_codegen::ir::function::Function;
99 pub use cranelift_codegen::ir::immediates::{Ieee32, Ieee64};
100 pub use cranelift_codegen::ir::types;
101 pub use cranelift_codegen::isa::{self, CallConv};
102 pub use cranelift_codegen::settings::{self, Configurable};
103 pub use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
104 pub use cranelift_module::{
105 self, Backend, DataContext, DataId, FuncId, FuncOrDataId, Linkage, Module,
108 pub use crate::abi::*;
109 pub use crate::base::{trans_operand, trans_place};
110 pub use crate::cast::*;
111 pub use crate::common::*;
112 pub use crate::debuginfo::{DebugContext, FunctionDebugContext};
113 pub use crate::pointer::Pointer;
114 pub use crate::trap::*;
115 pub use crate::unimpl::unimpl;
116 pub use crate::value_and_place::{CPlace, CPlaceInner, CValue};
117 pub use crate::CodegenCx;
119 pub struct PrintOnPanic<F: Fn() -> String>(pub F);
120 impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
122 if ::std::thread::panicking() {
123 println!("{}", (self.0)());
129 pub struct CodegenCx<'clif, 'tcx, B: Backend + 'static> {
131 module: &'clif mut Module<B>,
132 constants_cx: ConstantCx,
133 cached_context: Context,
134 vtables: HashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), DataId>,
135 debug_context: Option<&'clif mut DebugContext<'tcx>>,
138 impl<'clif, 'tcx, B: Backend + 'static> CodegenCx<'clif, 'tcx, B> {
141 module: &'clif mut Module<B>,
142 debug_context: Option<&'clif mut DebugContext<'tcx>>,
147 constants_cx: ConstantCx::default(),
148 cached_context: Context::new(),
149 vtables: HashMap::new(),
155 self.constants_cx.finalize(self.tcx, self.module);
159 struct CraneliftCodegenBackend;
161 impl CodegenBackend for CraneliftCodegenBackend {
162 fn init(&self, _sess: &Session) {}
164 fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
165 Box::new(crate::metadata::CraneliftMetadataLoader)
168 fn provide(&self, providers: &mut Providers) {
169 providers.target_features_whitelist = |tcx, cnum| {
170 assert_eq!(cnum, LOCAL_CRATE);
171 if tcx.sess.opts.actually_rustdoc {
172 // rustdoc needs to be able to document functions that use all the features, so
173 // whitelist them all
175 target_features_whitelist::all_known_features()
176 .map(|(a, b)| (a.to_string(), b))
181 target_features_whitelist::target_feature_whitelist(tcx.sess)
183 .map(|&(a, b)| (a.to_string(), b))
189 fn provide_extern(&self, _providers: &mut Providers) {}
191 fn codegen_crate<'tcx>(
194 metadata: EncodedMetadata,
195 need_metadata_module: bool,
197 rustc_codegen_utils::check_for_rustc_errors_attr(tcx);
199 let res = driver::codegen_crate(tcx, metadata, need_metadata_module);
201 rustc_incremental::assert_module_sources::assert_module_sources(tcx);
202 rustc_codegen_utils::symbol_names_test::report_symbol_names(tcx);
207 fn join_codegen_and_link(
211 _dep_graph: &DepGraph,
212 outputs: &OutputFilenames,
213 ) -> Result<(), ErrorReported> {
214 use rustc_codegen_ssa::back::link::link_binary;
216 let codegen_results = *res
217 .downcast::<CodegenResults>()
218 .expect("Expected CraneliftCodegenBackend's CodegenResult, found Box<Any>");
220 let _timer = sess.prof.generic_activity("link_crate");
222 rustc::util::common::time(sess, "linking", || {
223 let target_cpu = crate::target_triple(sess).to_string();
224 link_binary::<crate::archive::ArArchiveBuilder<'_>>(
228 &codegen_results.crate_name.as_str(),
237 fn target_triple(sess: &Session) -> target_lexicon::Triple {
238 sess.target.target.llvm_target.parse().unwrap()
241 fn build_isa(sess: &Session, enable_pic: bool) -> Box<dyn isa::TargetIsa + 'static> {
242 let mut flags_builder = settings::builder();
244 flags_builder.enable("is_pic").unwrap();
246 flags_builder.set("is_pic", "false").unwrap();
248 flags_builder.set("probestack_enabled", "false").unwrap(); // __cranelift_probestack is not provided
252 if cfg!(debug_assertions) {
260 // FIXME(CraneStation/cranelift#732) fix LICM in presence of jump tables
262 use rustc::session::config::OptLevel;
263 match sess.opts.optimize {
265 flags_builder.set("opt_level", "fastest").unwrap();
267 OptLevel::Less | OptLevel::Default => {}
268 OptLevel::Aggressive => {
269 flags_builder.set("opt_level", "best").unwrap();
271 OptLevel::Size | OptLevel::SizeMin => {
272 sess.warn("Optimizing for size is not supported. Just ignoring the request");
276 let target_triple = crate::target_triple(sess);
277 let flags = settings::Flags::new(flags_builder);
278 cranelift_codegen::isa::lookup(target_triple)
283 /// This is the entrypoint for a hot plugged rustc_codegen_cranelift
285 pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
286 Box::new(CraneliftCodegenBackend)