Format code using 'cargo fmt'

This commit is contained in:
Atul Bhosale 2019-08-31 22:58:09 +05:30
parent 5b17cf2083
commit f481a4b685
No known key found for this signature in database
GPG Key ID: 9CE70EE4DDBEB4A7
26 changed files with 831 additions and 518 deletions

View File

@ -2,8 +2,8 @@
use rustc::mir;
use crate::prelude::*;
use crate::abi::pass_mode::*;
use crate::prelude::*;
pub fn add_args_header_comment(fx: &mut FunctionCx<impl Backend>) {
fx.add_global_comment(format!(

View File

@ -1,16 +1,20 @@
#[cfg(debug_assertions)]
mod comments;
mod returning;
mod pass_mode;
mod returning;
use rustc_target::spec::abi::Abi;
use crate::prelude::*;
use self::pass_mode::*;
use crate::prelude::*;
pub use self::returning::codegen_return;
fn clif_sig_from_fn_sig<'tcx>(tcx: TyCtxt<'tcx>, sig: FnSig<'tcx>, is_vtable_fn: bool) -> Signature {
fn clif_sig_from_fn_sig<'tcx>(
tcx: TyCtxt<'tcx>,
sig: FnSig<'tcx>,
is_vtable_fn: bool,
) -> Signature {
let abi = match sig.abi {
Abi::System => {
if tcx.sess.target.target.options.is_like_windows {
@ -47,12 +51,18 @@ fn clif_sig_from_fn_sig<'tcx>(tcx: TyCtxt<'tcx>, sig: FnSig<'tcx>, is_vtable_fn:
if i == 0 && is_vtable_fn {
// Virtual calls turn their self param into a thin pointer.
// See https://github.com/rust-lang/rust/blob/37b6a5e5e82497caf5353d9d856e4eb5d14cbe06/src/librustc/ty/layout.rs#L2519-L2572 for more info
layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.mk_mut_ptr(tcx.mk_unit()))).unwrap();
layout = tcx
.layout_of(ParamEnv::reveal_all().and(tcx.mk_mut_ptr(tcx.mk_unit())))
.unwrap();
}
get_pass_mode(tcx, layout).get_param_ty(tcx).into_iter()
}).flatten();
})
.flatten();
let (params, returns) = match get_pass_mode(tcx, tcx.layout_of(ParamEnv::reveal_all().and(output)).unwrap()) {
let (params, returns) = match get_pass_mode(
tcx,
tcx.layout_of(ParamEnv::reveal_all().and(output)).unwrap(),
) {
PassMode::NoPass => (inputs.map(AbiParam::new).collect(), vec![]),
PassMode::ByVal(ret_ty) => (
inputs.map(AbiParam::new).collect(),
@ -87,7 +97,8 @@ pub fn get_function_name_and_sig<'tcx>(
support_vararg: bool,
) -> (String, Signature) {
assert!(!inst.substs.needs_infer() && !inst.substs.has_param_types());
let fn_sig = tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &inst.fn_sig(tcx));
let fn_sig =
tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &inst.fn_sig(tcx));
if fn_sig.c_variadic && !support_vararg {
unimpl!("Variadic function definitions are not yet supported");
}
@ -141,7 +152,8 @@ fn lib_call(
.module
.declare_func_in_func(func_id, &mut self.bcx.func);
let call_inst = self.bcx.ins().call(func_ref, args);
#[cfg(debug_assertions)] {
#[cfg(debug_assertions)]
{
self.add_comment(call_inst, format!("easy_call {}", name));
}
let results = self.bcx.inst_results(call_inst);
@ -185,7 +197,10 @@ pub fn easy_call(
}
fn self_sig(&self) -> FnSig<'tcx> {
self.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &self.instance.fn_sig(self.tcx))
self.tcx.normalize_erasing_late_bound_regions(
ParamEnv::reveal_all(),
&self.instance.fn_sig(self.tcx),
)
}
fn return_layout(&self) -> TyLayout<'tcx> {
@ -213,10 +228,7 @@ fn local_place<'tcx>(
fx.local_map[&local]
}
pub fn codegen_fn_prelude(
fx: &mut FunctionCx<'_, '_, impl Backend>,
start_ebb: Ebb,
) {
pub fn codegen_fn_prelude(fx: &mut FunctionCx<'_, '_, impl Backend>, start_ebb: Ebb) {
let ssa_analyzed = crate::analyze::analyze(fx);
#[cfg(debug_assertions)]
@ -250,20 +262,13 @@ enum ArgKind<'tcx> {
let mut params = Vec::new();
for (i, arg_ty) in tupled_arg_tys.types().enumerate() {
let param = cvalue_for_param(
fx,
start_ebb,
local,
Some(i),
arg_ty,
);
let param = cvalue_for_param(fx, start_ebb, local, Some(i), arg_ty);
params.push(param);
}
(local, ArgKind::Spread(params), arg_ty)
} else {
let param =
cvalue_for_param(fx, start_ebb, local, None, arg_ty);
let param = cvalue_for_param(fx, start_ebb, local, None, arg_ty);
(local, ArgKind::Normal(param), arg_ty)
}
})
@ -354,7 +359,9 @@ pub fn codegen_terminator_call<'tcx>(
destination: &Option<(Place<'tcx>, BasicBlock)>,
) {
let fn_ty = fx.monomorphize(&func.ty(fx.mir, fx.tcx));
let sig = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &fn_ty.fn_sig(fx.tcx));
let sig = fx
.tcx
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &fn_ty.fn_sig(fx.tcx));
let destination = destination
.as_ref()
@ -365,7 +372,13 @@ pub fn codegen_terminator_call<'tcx>(
ty::Instance::resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap();
if fx.tcx.symbol_name(instance).as_str().starts_with("llvm.") {
crate::llvm_intrinsics::codegen_llvm_intrinsic_call(fx, &fx.tcx.symbol_name(instance).as_str(), substs, args, destination);
crate::llvm_intrinsics::codegen_llvm_intrinsic_call(
fx,
&fx.tcx.symbol_name(instance).as_str(),
substs,
args,
destination,
);
return;
}
@ -430,7 +443,9 @@ fn codegen_call_inner<'tcx>(
args: Vec<CValue<'tcx>>,
ret_place: Option<CPlace<'tcx>>,
) {
let fn_sig = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &fn_ty.fn_sig(fx.tcx));
let fn_sig = fx
.tcx
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &fn_ty.fn_sig(fx.tcx));
let instance = match fn_ty.sty {
ty::FnDef(def_id, substs) => {
@ -453,7 +468,10 @@ fn codegen_call_inner<'tcx>(
let nop_inst = fx.bcx.ins().nop();
fx.add_comment(
nop_inst,
format!("virtual call; self arg pass mode: {:?}", get_pass_mode(fx.tcx, args[0].layout())),
format!(
"virtual call; self arg pass mode: {:?}",
get_pass_mode(fx.tcx, args[0].layout())
),
);
}
let (ptr, method) = crate::vtable::get_ptr_and_method_ref(fx, args[0], idx);
@ -461,7 +479,13 @@ fn codegen_call_inner<'tcx>(
}
// Normal call
Some(_) => (None, args.get(0).map(|arg| adjust_arg_for_abi(fx, *arg)).unwrap_or(Empty), false),
Some(_) => (
None,
args.get(0)
.map(|arg| adjust_arg_for_abi(fx, *arg))
.unwrap_or(Empty),
false,
),
// Indirect call
None => {
@ -474,36 +498,40 @@ fn codegen_call_inner<'tcx>(
.load_scalar(fx);
(
Some(func),
args.get(0).map(|arg| adjust_arg_for_abi(fx, *arg)).unwrap_or(Empty),
args.get(0)
.map(|arg| adjust_arg_for_abi(fx, *arg))
.unwrap_or(Empty),
false,
)
}
};
let (call_inst, call_args) = self::returning::codegen_with_call_return_arg(fx, fn_sig, ret_place, |fx, return_ptr| {
let call_args: Vec<Value> = return_ptr
.into_iter()
.chain(first_arg.into_iter())
.chain(
args.into_iter()
.skip(1)
.map(|arg| adjust_arg_for_abi(fx, arg).into_iter())
.flatten(),
)
.collect::<Vec<_>>();
let (call_inst, call_args) =
self::returning::codegen_with_call_return_arg(fx, fn_sig, ret_place, |fx, return_ptr| {
let call_args: Vec<Value> = return_ptr
.into_iter()
.chain(first_arg.into_iter())
.chain(
args.into_iter()
.skip(1)
.map(|arg| adjust_arg_for_abi(fx, arg).into_iter())
.flatten(),
)
.collect::<Vec<_>>();
let call_inst = if let Some(func_ref) = func_ref {
let sig = fx
.bcx
.import_signature(clif_sig_from_fn_sig(fx.tcx, fn_sig, is_virtual_call));
fx.bcx.ins().call_indirect(sig, func_ref, &call_args)
} else {
let func_ref = fx.get_function_ref(instance.expect("non-indirect call on non-FnDef type"));
fx.bcx.ins().call(func_ref, &call_args)
};
let call_inst = if let Some(func_ref) = func_ref {
let sig =
fx.bcx
.import_signature(clif_sig_from_fn_sig(fx.tcx, fn_sig, is_virtual_call));
fx.bcx.ins().call_indirect(sig, func_ref, &call_args)
} else {
let func_ref =
fx.get_function_ref(instance.expect("non-indirect call on non-FnDef type"));
fx.bcx.ins().call(func_ref, &call_args)
};
(call_inst, call_args)
});
(call_inst, call_args)
});
// FIXME find a cleaner way to support varargs
if fn_sig.c_variadic {
@ -526,10 +554,7 @@ fn codegen_call_inner<'tcx>(
}
}
pub fn codegen_drop<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
drop_place: CPlace<'tcx>,
) {
pub fn codegen_drop<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl Backend>, drop_place: CPlace<'tcx>) {
let ty = drop_place.layout().ty;
let drop_fn = Instance::resolve_drop_in_place(fx.tcx, ty);
@ -542,7 +567,10 @@ pub fn codegen_drop<'tcx>(
let (ptr, vtable) = drop_place.to_addr_maybe_unsized(fx);
let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable.unwrap());
let fn_sig = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &drop_fn_ty.fn_sig(fx.tcx));
let fn_sig = fx.tcx.normalize_erasing_late_bound_regions(
ParamEnv::reveal_all(),
&drop_fn_ty.fn_sig(fx.tcx),
);
assert_eq!(fn_sig.output(), fx.tcx.mk_unit());
@ -564,13 +592,7 @@ pub fn codegen_drop<'tcx>(
);
drop_place.write_place_ref(fx, arg_place);
let arg_value = arg_place.to_cvalue(fx);
codegen_call_inner(
fx,
None,
drop_fn_ty,
vec![arg_value],
None,
);
codegen_call_inner(fx, None, drop_fn_ty, vec![arg_value], None);
}
}
}

View File

@ -50,14 +50,14 @@ impl<T: std::fmt::Debug> EmptySinglePair<T> {
pub fn assert_single(self) -> T {
match self {
Single(v) => v,
_ => panic!("Called assert_single on {:?}", self)
_ => panic!("Called assert_single on {:?}", self),
}
}
pub fn assert_pair(self) -> (T, T) {
match self {
Pair(a, b) => (a, b),
_ => panic!("Called assert_pair on {:?}", self)
_ => panic!("Called assert_pair on {:?}", self),
}
}
}
@ -75,10 +75,7 @@ pub fn get_param_ty(self, tcx: TyCtxt<'_>) -> EmptySinglePair<Type> {
}
}
pub fn get_pass_mode<'tcx>(
tcx: TyCtxt<'tcx>,
layout: TyLayout<'tcx>,
) -> PassMode {
pub fn get_pass_mode<'tcx>(tcx: TyCtxt<'tcx>, layout: TyLayout<'tcx>) -> PassMode {
assert!(!layout.is_unsized());
if layout.is_zst() {

View File

@ -1,5 +1,5 @@
use crate::prelude::*;
use crate::abi::pass_mode::*;
use crate::prelude::*;
pub fn codegen_return_param(
fx: &mut FunctionCx<impl Backend>,
@ -27,10 +27,8 @@ pub fn codegen_return_param(
}
PassMode::ByRef => {
let ret_param = fx.bcx.append_ebb_param(start_ebb, fx.pointer_type);
fx.local_map.insert(
RETURN_PLACE,
CPlace::for_addr(ret_param, ret_layout),
);
fx.local_map
.insert(RETURN_PLACE, CPlace::for_addr(ret_param, ret_layout));
Single(ret_param)
}

View File

@ -3,8 +3,8 @@
use crate::prelude::*;
use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder};
use rustc_codegen_ssa::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION};
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, find_library};
struct ArchiveConfig<'a> {
sess: &'a Session,
@ -16,7 +16,10 @@ struct ArchiveConfig<'a> {
#[derive(Debug)]
enum ArchiveEntry {
FromArchive { archive_index: usize, entry_index: usize },
FromArchive {
archive_index: usize,
entry_index: usize,
},
File(PathBuf),
}
@ -50,7 +53,10 @@ fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self {
let entry = entry.unwrap();
entries.push((
String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
ArchiveEntry::FromArchive { archive_index: 0, entry_index: i },
ArchiveEntry::FromArchive {
archive_index: 0,
entry_index: i,
},
));
i += 1;
}
@ -73,7 +79,8 @@ fn src_files(&mut self) -> Vec<String> {
}
fn remove_file(&mut self, name: &str) {
let index = self.entries
let index = self
.entries
.iter()
.position(|(entry_name, _)| entry_name == name)
.expect("Tried to remove file not existing in src archive");
@ -89,12 +96,23 @@ fn add_file(&mut self, file: &Path) {
fn add_native_library(&mut self, name: &str) {
let location = find_library(name, &self.config.lib_search_paths, self.config.sess);
self.add_archive(location.clone(), |_| false).unwrap_or_else(|e| {
panic!("failed to add native library {}: {}", location.to_string_lossy(), e);
});
self.add_archive(location.clone(), |_| false)
.unwrap_or_else(|e| {
panic!(
"failed to add native library {}: {}",
location.to_string_lossy(),
e
);
});
}
fn add_rlib(&mut self, rlib: &Path, name: &str, lto: bool, skip_objects: bool) -> std::io::Result<()> {
fn add_rlib(
&mut self,
rlib: &Path,
name: &str,
lto: bool,
skip_objects: bool,
) -> std::io::Result<()> {
let obj_start = name.to_owned();
self.add_archive(rlib.to_owned(), move |fname: &str| {
@ -147,7 +165,10 @@ enum BuilderKind<'a> {
} else if self.config.use_gnu_style_archive {
BuilderKind::Gnu(ar::GnuBuilder::new(
File::create(&self.config.dst).unwrap(),
self.entries.iter().map(|(name, _)| name.as_bytes().to_vec()).collect(),
self.entries
.iter()
.map(|(name, _)| name.as_bytes().to_vec())
.collect(),
))
} else {
BuilderKind::Bsd(ar::Builder::new(File::create(&self.config.dst).unwrap()))
@ -156,8 +177,12 @@ enum BuilderKind<'a> {
// Add all files
for (entry_name, entry) in self.entries.into_iter() {
match entry {
ArchiveEntry::FromArchive { archive_index, entry_index } => {
let (ref src_archive_path, ref mut src_archive) = self.src_archives[archive_index];
ArchiveEntry::FromArchive {
archive_index,
entry_index,
} => {
let (ref src_archive_path, ref mut src_archive) =
self.src_archives[archive_index];
let entry = src_archive.jump_to_entry(entry_index).unwrap();
let orig_header = entry.header();
@ -170,22 +195,33 @@ enum BuilderKind<'a> {
header.set_mode(orig_header.mode());
match builder {
BuilderKind::Bsd(ref mut builder) => builder.append(&header, entry).unwrap(),
BuilderKind::Gnu(ref mut builder) => builder.append(&header, entry).unwrap(),
BuilderKind::Bsd(ref mut builder) => {
builder.append(&header, entry).unwrap()
}
BuilderKind::Gnu(ref mut builder) => {
builder.append(&header, entry).unwrap()
}
BuilderKind::NativeAr(archive_file) => {
Command::new("ar").arg("x").arg(src_archive_path).arg(&entry_name).status().unwrap();
Command::new("ar")
.arg("x")
.arg(src_archive_path)
.arg(&entry_name)
.status()
.unwrap();
add_file_using_ar(archive_file, Path::new(&entry_name));
std::fs::remove_file(entry_name).unwrap();
}
}
}
ArchiveEntry::File(file) => {
match builder {
BuilderKind::Bsd(ref mut builder) => builder.append_file(entry_name.as_bytes(), &mut File::open(file).unwrap()).unwrap(),
BuilderKind::Gnu(ref mut builder) => builder.append_file(entry_name.as_bytes(), &mut File::open(file).unwrap()).unwrap(),
BuilderKind::NativeAr(archive_file) => add_file_using_ar(archive_file, &file),
}
}
ArchiveEntry::File(file) => match builder {
BuilderKind::Bsd(ref mut builder) => builder
.append_file(entry_name.as_bytes(), &mut File::open(file).unwrap())
.unwrap(),
BuilderKind::Gnu(ref mut builder) => builder
.append_file(entry_name.as_bytes(), &mut File::open(file).unwrap())
.unwrap(),
BuilderKind::NativeAr(archive_file) => add_file_using_ar(archive_file, &file),
},
}
}
@ -207,7 +243,8 @@ enum BuilderKind<'a> {
impl<'a> ArArchiveBuilder<'a> {
fn add_archive<F>(&mut self, archive_path: PathBuf, mut skip: F) -> std::io::Result<()>
where F: FnMut(&str) -> bool + 'static
where
F: FnMut(&str) -> bool + 'static,
{
let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?);
let archive_index = self.src_archives.len();
@ -219,7 +256,10 @@ fn add_archive<F>(&mut self, archive_path: PathBuf, mut skip: F) -> std::io::Res
if !skip(&file_name) {
self.entries.push((
file_name,
ArchiveEntry::FromArchive { archive_index, entry_index: i },
ArchiveEntry::FromArchive {
archive_index,
entry_index: i,
},
));
}
i += 1;

View File

@ -72,15 +72,22 @@ pub fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
// Define function
let context = &mut cx.caches.context;
context.func = func;
cx.module
.define_function(func_id, context)
.unwrap();
cx.module.define_function(func_id, context).unwrap();
let value_ranges = context.build_value_labels_ranges(cx.module.isa()).expect("value location ranges");
let value_ranges = context
.build_value_labels_ranges(cx.module.isa())
.expect("value location ranges");
// Write optimized function to file for debugging
#[cfg(debug_assertions)]
crate::pretty_clif::write_clif_file(cx.tcx, "opt", instance, &context.func, &clif_comments, Some(&value_ranges));
crate::pretty_clif::write_clif_file(
cx.tcx,
"opt",
instance,
&context.func,
&clif_comments,
Some(&value_ranges),
);
// Define debuginfo for function
let isa = cx.module.isa();
@ -164,7 +171,14 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Backend>) {
} else {
fx.bcx.ins().brz(cond, target, &[]);
};
trap_panic(fx, format!("[panic] Assert {:?} at {:?} failed.", msg, bb_data.terminator().source_info.span));
trap_panic(
fx,
format!(
"[panic] Assert {:?} at {:?} failed.",
msg,
bb_data.terminator().source_info.span
),
);
}
TerminatorKind::SwitchInt {
@ -272,7 +286,8 @@ fn trans_stmt<'tcx>(
let rhs = trans_operand(fx, rhs);
let res = if !fx.tcx.sess.overflow_checks() {
let val = crate::num::trans_int_binop(fx, *bin_op, lhs, rhs).load_scalar(fx);
let val =
crate::num::trans_int_binop(fx, *bin_op, lhs, rhs).load_scalar(fx);
let is_overflow = fx.bcx.ins().iconst(types::I8, 0);
CValue::by_val_pair(val, is_overflow, lval.layout())
} else {
@ -293,9 +308,7 @@ fn trans_stmt<'tcx>(
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
fx.bcx.ins().bint(types::I8, res)
}
ty::Uint(_) | ty::Int(_) => {
fx.bcx.ins().bnot(val)
}
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().bnot(val),
_ => unimplemented!("un op Not for {:?}", layout.ty),
}
}
@ -304,7 +317,12 @@ fn trans_stmt<'tcx>(
let clif_ty = fx.clif_type(layout.ty).unwrap();
if clif_ty == types::I128 {
// FIXME implement it
crate::trap::trap_unreachable_ret_value(fx, layout, "i128 neg is not yet supported").load_scalar(fx)
crate::trap::trap_unreachable_ret_value(
fx,
layout,
"i128 neg is not yet supported",
)
.load_scalar(fx)
} else {
let zero = fx.bcx.ins().iconst(clif_ty, 0);
fx.bcx.ins().isub(zero, val)
@ -343,10 +361,19 @@ fn trans_stmt<'tcx>(
let operand = trans_operand(fx, operand);
let from_ty = operand.layout().ty;
fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, ty: Ty<'tcx>) -> bool {
ty
.builtin_deref(true)
.map(|ty::TypeAndMut {ty: pointee_ty, mutbl: _ }| fx.layout_of(pointee_ty).is_unsized())
fn is_fat_ptr<'tcx>(
fx: &FunctionCx<'_, 'tcx, impl Backend>,
ty: Ty<'tcx>,
) -> bool {
ty.builtin_deref(true)
.map(
|ty::TypeAndMut {
ty: pointee_ty,
mutbl: _,
}| {
fx.layout_of(pointee_ty).is_unsized()
},
)
.unwrap_or(false)
}
@ -363,17 +390,27 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, ty: Ty<'tcx>) -> bo
// enum -> discriminant value
assert!(adt_def.is_enum());
match to_ty.sty {
ty::Uint(_) | ty::Int(_) => {},
ty::Uint(_) | ty::Int(_) => {}
_ => unreachable!("cast adt {} -> {}", from_ty, to_ty),
}
let discr = crate::discriminant::codegen_get_discriminant(fx, operand, fx.layout_of(to_ty));
let discr = crate::discriminant::codegen_get_discriminant(
fx,
operand,
fx.layout_of(to_ty),
);
lval.write_cvalue(fx, discr);
} else {
let to_clif_ty = fx.clif_type(to_ty).unwrap();
let from = operand.load_scalar(fx);
let res = clif_int_or_float_cast(fx, from, type_sign(from_ty), to_clif_ty, type_sign(to_ty));
let res = clif_int_or_float_cast(
fx,
from,
type_sign(from_ty),
to_clif_ty,
type_sign(to_ty),
);
lval.write_cvalue(fx, CValue::by_val(res, dest_layout));
}
}
@ -391,9 +428,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, ty: Ty<'tcx>) -> bo
let func_addr = fx.bcx.ins().func_addr(fx.pointer_type, func_ref);
lval.write_cvalue(fx, CValue::by_val(func_addr, lval.layout()));
}
_ => {
bug!("{} cannot be cast to a fn ptr", operand.layout().ty)
}
_ => bug!("{} cannot be cast to a fn ptr", operand.layout().ty),
}
}
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), operand, _ty) => {
@ -403,7 +438,8 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, ty: Ty<'tcx>) -> bo
Rvalue::Discriminant(place) => {
let place = trans_place(fx, place);
let value = place.to_cvalue(fx);
let discr = crate::discriminant::codegen_get_discriminant(fx, value, dest_layout);
let discr =
crate::discriminant::codegen_get_discriminant(fx, value, dest_layout);
lval.write_cvalue(fx, discr);
}
Rvalue::Repeat(operand, times) => {
@ -478,15 +514,19 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, ty: Ty<'tcx>) -> bo
StatementKind::InlineAsm(asm) => {
use syntax::ast::Name;
let InlineAsm { asm, outputs: _, inputs: _ } = &**asm;
let InlineAsm {
asm,
outputs: _,
inputs: _,
} = &**asm;
let rustc::hir::InlineAsm {
asm: asm_code, // Name
outputs, // Vec<Name>
inputs, // Vec<Name>
clobbers, // Vec<Name>
volatile, // bool
alignstack, // bool
dialect: _, // syntax::ast::AsmDialect
outputs, // Vec<Name>
inputs, // Vec<Name>
clobbers, // Vec<Name>
volatile, // bool
alignstack, // bool
dialect: _, // syntax::ast::AsmDialect
asm_str_style: _,
} = asm;
match &*asm_code.as_str() {
@ -494,7 +534,10 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, ty: Ty<'tcx>) -> bo
assert_eq!(inputs, &[Name::intern("{eax}"), Name::intern("{ecx}")]);
assert_eq!(outputs.len(), 4);
for (i, c) in (&["={eax}", "={ebx}", "={ecx}", "={edx}"]).iter().enumerate() {
for (i, c) in (&["={eax}", "={ebx}", "={ecx}", "={edx}"])
.iter()
.enumerate()
{
assert_eq!(&outputs[i].constraint.as_str(), c);
assert!(!outputs[i].is_rw);
assert!(!outputs[i].is_indirect);
@ -505,7 +548,10 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, ty: Ty<'tcx>) -> bo
assert!(!volatile);
assert!(!alignstack);
crate::trap::trap_unimplemented(fx, "__cpuid_count arch intrinsic is not supported");
crate::trap::trap_unimplemented(
fx,
"__cpuid_count arch intrinsic is not supported",
);
}
"xgetbv" => {
assert_eq!(inputs, &[Name::intern("{ecx}")]);
@ -565,7 +611,7 @@ pub fn trans_place<'tcx>(
let instance = Instance::new(static_.def_id, fx.monomorphize(&substs));
crate::constant::trans_promoted(fx, instance, promoted, static_.ty)
}
}
},
};
trans_place_projection(fx, base, &place.projection)
@ -615,7 +661,9 @@ pub fn trans_place_projection<'tcx>(
let len = crate::constant::force_eval_const(fx, len)
.eval_usize(fx.tcx, ParamEnv::reveal_all());
CPlace::for_addr(
fx.bcx.ins().iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
fx.bcx
.ins()
.iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
fx.layout_of(fx.tcx.mk_array(elem_ty, len - from as u64 - to as u64)),
)
}
@ -624,7 +672,9 @@ pub fn trans_place_projection<'tcx>(
let (ptr, len) = base.to_addr_maybe_unsized(fx);
let len = len.unwrap();
CPlace::for_addr_with_extra(
fx.bcx.ins().iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
fx.bcx
.ins()
.iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
fx.bcx.ins().iadd_imm(len, -(from as i64 + to as i64)),
base.layout(),
)

View File

@ -40,9 +40,7 @@ pub fn clif_intcast(
fx.bcx.ins().ireduce(to, lsb)
}
}
(_, _) => {
fx.bcx.ins().ireduce(to, val)
}
(_, _) => fx.bcx.ins().ireduce(to, val),
}
}
@ -71,13 +69,10 @@ pub fn clif_int_or_float_cast(
// __floatuntisf: u128 -> f32
// __floatuntidf: u128 -> f64
let name = format!("__float{sign}ti{flt}f",
sign=if from_signed {
""
} else {
"un"
},
flt=match to_ty {
let name = format!(
"__float{sign}ti{flt}f",
sign = if from_signed { "" } else { "un" },
flt = match to_ty {
types::F32 => "s",
types::F64 => "d",
_ => unreachable!("{:?}", to_ty),
@ -96,11 +91,13 @@ pub fn clif_int_or_float_cast(
_ => unreachable!(),
};
return fx.easy_call(
&name,
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
to_rust_ty,
).load_scalar(fx);
return fx
.easy_call(
&name,
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
to_rust_ty,
)
.load_scalar(fx);
}
// int-like -> float
@ -117,13 +114,10 @@ pub fn clif_int_or_float_cast(
// __fixunssfti: f32 -> u128
// __fixunsdfti: f64 -> u128
let name = format!("__fix{sign}{flt}fti",
sign=if to_signed {
""
} else {
"uns"
},
flt=match from_ty {
let name = format!(
"__fix{sign}{flt}fti",
sign = if to_signed { "" } else { "uns" },
flt = match from_ty {
types::F32 => "s",
types::F64 => "d",
_ => unreachable!("{:?}", to_ty),
@ -142,11 +136,13 @@ pub fn clif_int_or_float_cast(
fx.tcx.types.u128
};
return fx.easy_call(
&name,
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
to_rust_ty,
).load_scalar(fx);
return fx
.easy_call(
&name,
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
to_rust_ty,
)
.load_scalar(fx);
}
// float -> int-like
@ -162,24 +158,12 @@ pub fn clif_int_or_float_cast(
let max_val = fx.bcx.ins().iconst(types::I32, max);
let val = if to_signed {
let has_underflow = fx.bcx.ins().icmp_imm(
IntCC::SignedLessThan,
val,
min,
);
let has_overflow = fx.bcx.ins().icmp_imm(
IntCC::SignedGreaterThan,
val,
max,
);
let has_underflow = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, val, min);
let has_overflow = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThan, val, max);
let bottom_capped = fx.bcx.ins().select(has_underflow, min_val, val);
fx.bcx.ins().select(has_overflow, max_val, bottom_capped)
} else {
let has_overflow = fx.bcx.ins().icmp_imm(
IntCC::UnsignedGreaterThan,
val,
max,
);
let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, val, max);
fx.bcx.ins().select(has_overflow, max_val, val)
};
fx.bcx.ins().ireduce(to_ty, val)
@ -193,12 +177,8 @@ pub fn clif_int_or_float_cast(
} else if from_ty.is_float() && to_ty.is_float() {
// float -> float
match (from_ty, to_ty) {
(types::F32, types::F64) => {
fx.bcx.ins().fpromote(types::F64, from)
}
(types::F64, types::F32) => {
fx.bcx.ins().fdemote(types::F32, from)
}
(types::F32, types::F64) => fx.bcx.ins().fpromote(types::F64, from),
(types::F64, types::F32) => fx.bcx.ins().fdemote(types::F32, from),
_ => from,
}
} else {

View File

@ -30,7 +30,7 @@ pub fn maybe_codegen<'tcx>(
fx.easy_call("__rust_i128_addo", &[lhs, rhs], out_ty)
} else {
fx.easy_call("__rust_u128_addo", &[lhs, rhs], out_ty)
})
});
}
BinOp::Sub => {
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
@ -38,7 +38,7 @@ pub fn maybe_codegen<'tcx>(
fx.easy_call("__rust_i128_subo", &[lhs, rhs], out_ty)
} else {
fx.easy_call("__rust_u128_subo", &[lhs, rhs], out_ty)
})
});
}
BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"),
BinOp::Mul => {
@ -50,7 +50,11 @@ pub fn maybe_codegen<'tcx>(
fx.easy_call("__rust_u128_mulo", &[lhs, rhs], out_ty)
}
} else {
let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
let val_ty = if is_signed {
fx.tcx.types.i128
} else {
fx.tcx.types.u128
};
fx.easy_call("__multi3", &[lhs, rhs], val_ty)
};
return Some(res);
@ -111,17 +115,21 @@ pub fn maybe_codegen<'tcx>(
Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.i128)))
}
(BinOp::Shl, _) => {
let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
let val_ty = if is_signed {
fx.tcx.types.i128
} else {
fx.tcx.types.u128
};
let val = fx.bcx.ins().iconcat(all_zeros, lhs_lsb);
Some(CValue::by_val(val, fx.layout_of(val_ty)))
}
_ => None
_ => None,
};
if let Some(val) = val {
if let Some(is_overflow) = is_overflow {
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
let val = val.load_scalar(fx);
return Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty)))
return Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty)));
} else {
return Some(val);
}

View File

@ -1,7 +1,7 @@
use rustc::ty::layout::{FloatTy, Integer, Primitive};
use rustc_target::spec::{HasTargetSpec, Target};
use cranelift::codegen::ir::{Opcode, InstructionData, ValueDef};
use cranelift::codegen::ir::{InstructionData, Opcode, ValueDef};
use crate::prelude::*;
@ -35,10 +35,7 @@ pub fn scalar_to_clif_type(tcx: TyCtxt, scalar: Scalar) -> Type {
}
}
pub fn clif_type_from_ty<'tcx>(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
) -> Option<types::Type> {
pub fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Type> {
Some(match ty.sty {
ty::Bool => types::I8,
ty::Uint(size) => match size {
@ -184,7 +181,8 @@ fn resolve_normal_value_imm(func: &Function, val: Value) -> Option<i64> {
if let InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm,
} = func.dfg[inst] {
} = func.dfg[inst]
{
Some(imm.into())
} else {
None
@ -199,7 +197,8 @@ fn resolve_128bit_value_imm(func: &Function, val: Value) -> Option<u128> {
if let InstructionData::Binary {
opcode: Opcode::Iconcat,
args: [lsb, msb],
} = func.dfg[inst] {
} = func.dfg[inst]
{
(lsb, msb)
} else {
return None;
@ -225,10 +224,9 @@ pub fn resolve_value_imm(func: &Function, val: Value) -> Option<u128> {
pub fn type_min_max_value(ty: Type, signed: bool) -> (i64, i64) {
assert!(ty.is_int());
let min = match (ty, signed) {
(types::I8 , false)
| (types::I16, false)
| (types::I32, false)
| (types::I64, false) => 0i64,
(types::I8, false) | (types::I16, false) | (types::I32, false) | (types::I64, false) => {
0i64
}
(types::I8, true) => i8::min_value() as i64,
(types::I16, true) => i16::min_value() as i64,
(types::I32, true) => i32::min_value() as i64,
@ -287,11 +285,14 @@ impl<'tcx, B: Backend> LayoutOf for FunctionCx<'_, 'tcx, B> {
fn layout_of(&self, ty: Ty<'tcx>) -> TyLayout<'tcx> {
let ty = self.monomorphize(&ty);
self.tcx.layout_of(ParamEnv::reveal_all().and(&ty))
.unwrap_or_else(|e| if let layout::LayoutError::SizeOverflow(_) = e {
self.tcx.sess.fatal(&e.to_string())
} else {
bug!("failed to get layout for `{}`: {}", ty, e)
self.tcx
.layout_of(ParamEnv::reveal_all().and(&ty))
.unwrap_or_else(|e| {
if let layout::LayoutError::SizeOverflow(_) = e {
self.tcx.sess.fatal(&e.to_string())
} else {
bug!("failed to get layout for `{}`: {}", ty, e)
}
})
}
}

View File

@ -1,12 +1,11 @@
use std::borrow::Cow;
use rustc::mir::interpret::{
read_target_uint, AllocId, GlobalAlloc, Allocation, ConstValue, InterpResult, GlobalId, Scalar,
read_target_uint, AllocId, Allocation, ConstValue, GlobalAlloc, GlobalId, InterpResult, Scalar,
};
use rustc::ty::{Const, layout::Align};
use rustc::ty::{layout::Align, Const};
use rustc_mir::interpret::{
InterpCx, ImmTy, Machine, Memory, MemoryKind, OpTy, PlaceTy, Pointer,
StackPopCleanup,
ImmTy, InterpCx, Machine, Memory, MemoryKind, OpTy, PlaceTy, Pointer, StackPopCleanup,
};
use cranelift_module::*;
@ -26,11 +25,7 @@ enum TodoItem {
}
impl ConstantCx {
pub fn finalize(
mut self,
tcx: TyCtxt<'_>,
module: &mut Module<impl Backend>,
) {
pub fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut Module<impl Backend>) {
//println!("todo {:?}", self.todo);
define_all_allocs(tcx, module, &mut self);
//println!("done {:?}", self.done);
@ -58,25 +53,20 @@ pub fn trans_promoted<'tcx>(
promoted: Promoted,
dest_ty: Ty<'tcx>,
) -> CPlace<'tcx> {
match fx
.tcx
.const_eval(ParamEnv::reveal_all().and(GlobalId {
instance,
promoted: Some(promoted),
}))
{
match fx.tcx.const_eval(ParamEnv::reveal_all().and(GlobalId {
instance,
promoted: Some(promoted),
})) {
Ok(const_) => {
let cplace = trans_const_place(fx, const_);
debug_assert_eq!(cplace.layout(), fx.layout_of(dest_ty));
cplace
}
Err(_) => {
crate::trap::trap_unreachable_ret_place(
fx,
fx.layout_of(dest_ty),
"[panic] Tried to get value of promoted value with errored during const eval.",
)
}
Err(_) => crate::trap::trap_unreachable_ret_place(
fx,
fx.layout_of(dest_ty),
"[panic] Tried to get value of promoted value with errored during const eval.",
),
}
}
@ -120,13 +110,23 @@ pub fn trans_const_value<'tcx>(
}
ty::Int(_) => {
let bits = const_.val.try_to_bits(layout.size).unwrap();
CValue::const_val(fx, ty, rustc::mir::interpret::sign_extend(bits, layout.size))
CValue::const_val(
fx,
ty,
rustc::mir::interpret::sign_extend(bits, layout.size),
)
}
ty::Float(fty) => {
let bits = const_.val.try_to_bits(layout.size).unwrap();
let val = match fty {
FloatTy::F32 => fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(bits).unwrap())),
FloatTy::F64 => fx.bcx.ins().f64const(Ieee64::with_bits(u64::try_from(bits).unwrap())),
FloatTy::F32 => fx
.bcx
.ins()
.f32const(Ieee32::with_bits(u32::try_from(bits).unwrap())),
FloatTy::F64 => fx
.bcx
.ins()
.f64const(Ieee64::with_bits(u64::try_from(bits).unwrap())),
};
CValue::by_val(val, layout)
}
@ -170,7 +170,9 @@ fn trans_const_place<'tcx>(
)?;
let ptr = ecx.allocate(op.layout, MemoryKind::Stack);
ecx.copy_op(op, ptr.into())?;
let alloc = ecx.memory().get(ptr.to_ref().to_scalar()?.to_ptr()?.alloc_id)?;
let alloc = ecx
.memory()
.get(ptr.to_ref().to_scalar()?.to_ptr()?.alloc_id)?;
Ok(fx.tcx.intern_const_alloc(alloc.clone()))
};
let alloc = result().expect("unable to convert ConstValue to Allocation");
@ -182,9 +184,18 @@ fn trans_const_place<'tcx>(
cplace_for_dataid(fx, const_.ty, data_id)
}
fn data_id_for_alloc_id<B: Backend>(module: &mut Module<B>, alloc_id: AllocId, align: Align) -> DataId {
fn data_id_for_alloc_id<B: Backend>(
module: &mut Module<B>,
alloc_id: AllocId,
align: Align,
) -> DataId {
module
.declare_data(&format!("__alloc_{}", alloc_id.0), Linkage::Local, false, Some(align.bytes() as u8))
.declare_data(
&format!("__alloc_{}", alloc_id.0),
Linkage::Local,
false,
Some(align.bytes() as u8),
)
.unwrap()
}
@ -202,16 +213,29 @@ fn data_id_for_static(
} else {
!ty.is_freeze(tcx, ParamEnv::reveal_all(), DUMMY_SP)
};
let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes();
let align = tcx
.layout_of(ParamEnv::reveal_all().and(ty))
.unwrap()
.align
.pref
.bytes();
let data_id = module
.declare_data(&*symbol_name, linkage, is_mutable, Some(align.try_into().unwrap()))
.declare_data(
&*symbol_name,
linkage,
is_mutable,
Some(align.try_into().unwrap()),
)
.unwrap();
if linkage == Linkage::Preemptible {
if let ty::RawPtr(_) = ty.sty {
} else {
tcx.sess.span_fatal(tcx.def_span(def_id), "must have type `*const T` or `*mut T` due to `#[linkage]` attribute")
tcx.sess.span_fatal(
tcx.def_span(def_id),
"must have type `*const T` or `*mut T` due to `#[linkage]` attribute",
)
}
let mut data_ctx = DataContext::new();
@ -243,11 +267,7 @@ fn cplace_for_dataid<'tcx>(
CPlace::for_addr(global_ptr, layout)
}
fn define_all_allocs(
tcx: TyCtxt<'_>,
module: &mut Module<impl Backend>,
cx: &mut ConstantCx,
) {
fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut Module<impl Backend>, cx: &mut ConstantCx) {
let memory = Memory::<TransPlaceInterpreter>::new(tcx.at(DUMMY_SP), ());
while let Some(todo_item) = pop_set(&mut cx.todo) {
@ -277,11 +297,16 @@ fn define_all_allocs(
_ => bug!("static const eval returned {:#?}", const_),
};
let data_id = data_id_for_static(tcx, module, def_id, if tcx.is_reachable_non_generic(def_id) {
Linkage::Export
} else {
Linkage::Local
});
let data_id = data_id_for_static(
tcx,
module,
def_id,
if tcx.is_reachable_non_generic(def_id) {
Linkage::Export
} else {
Linkage::Local
},
);
(data_id, alloc)
}
};
@ -395,10 +420,7 @@ fn call_intrinsic(
panic!();
}
fn find_foreign_static(
_: TyCtxt<'tcx>,
_: DefId,
) -> InterpResult<'tcx, Cow<'tcx, Allocation>> {
fn find_foreign_static(_: TyCtxt<'tcx>, _: DefId) -> InterpResult<'tcx, Cow<'tcx, Allocation>> {
panic!();
}
@ -411,10 +433,7 @@ fn binary_ptr_op(
panic!();
}
fn ptr_to_int(
_: &Memory<'mir, 'tcx, Self>,
_: Pointer<()>,
) -> InterpResult<'tcx, u64> {
fn ptr_to_int(_: &Memory<'mir, 'tcx, Self>, _: Pointer<()>) -> InterpResult<'tcx, u64> {
panic!();
}
@ -473,10 +492,12 @@ pub fn mir_operand_get_const_val<'tcx>(
StaticKind::Static => unimplemented!(),
StaticKind::Promoted(promoted, substs) => {
let instance = Instance::new(static_.def_id, fx.monomorphize(substs));
fx.tcx.const_eval(ParamEnv::reveal_all().and(GlobalId {
instance,
promoted: Some(*promoted),
})).unwrap()
fx.tcx
.const_eval(ParamEnv::reveal_all().and(GlobalId {
instance,
promoted: Some(*promoted),
}))
.unwrap()
}
})
}

View File

@ -30,11 +30,7 @@ fn line_program_add_file(
FileName::Real(path) => {
let dir_name = path.parent().unwrap().to_str().unwrap().as_bytes();
let dir_id = if !dir_name.is_empty() {
let dir_name = LineString::new(
dir_name,
line_program.encoding(),
line_strings,
);
let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings);
line_program.add_directory(dir_name)
} else {
line_program.default_directory()
@ -196,7 +192,11 @@ pub fn emit(&mut self, artifact: &mut Artifact) {
let _: Result<()> = sections.for_each_mut(|id, section| {
if !section.writer.slice().is_empty() {
artifact
.declare_with(id.name(), Decl::section(SectionKind::Debug), section.writer.take())
.declare_with(
id.name(),
Decl::section(SectionKind::Debug),
section.writer.take(),
)
.unwrap();
}
Ok(())

View File

@ -33,11 +33,12 @@ pub fn codegen_set_discriminant<'tcx>(
layout::Variants::Multiple {
discr: _,
discr_index,
discr_kind: layout::DiscriminantKind::Niche {
dataful_variant,
ref niche_variants,
niche_start,
},
discr_kind:
layout::DiscriminantKind::Niche {
dataful_variant,
ref niche_variants,
niche_start,
},
variants: _,
} => {
if variant_index != dataful_variant {
@ -59,7 +60,11 @@ pub fn codegen_get_discriminant<'tcx>(
let layout = value.layout();
if layout.abi == layout::Abi::Uninhabited {
return trap_unreachable_ret_value(fx, dest_layout, "[panic] Tried to get discriminant for uninhabited type.");
return trap_unreachable_ret_value(
fx,
dest_layout,
"[panic] Tried to get discriminant for uninhabited type.",
);
}
let (discr_scalar, discr_index, discr_kind) = match &layout.variants {
@ -70,9 +75,12 @@ pub fn codegen_get_discriminant<'tcx>(
.map_or(u128::from(index.as_u32()), |discr| discr.val);
return CValue::const_val(fx, dest_layout.ty, discr_val);
}
layout::Variants::Multiple { discr, discr_index, discr_kind, variants: _ } => {
(discr, *discr_index, discr_kind)
}
layout::Variants::Multiple {
discr,
discr_index,
discr_kind,
variants: _,
} => (discr, *discr_index, discr_kind),
};
let cast_to = fx.clif_type(dest_layout.ty).unwrap();
@ -86,7 +94,7 @@ pub fn codegen_get_discriminant<'tcx>(
layout::DiscriminantKind::Tag => {
let signed = match discr_scalar.value {
layout::Int(_, signed) => signed,
_ => false
_ => false,
};
let val = clif_intcast(fx, encoded_discr, cast_to, signed);
return CValue::by_val(val, dest_layout);
@ -112,11 +120,18 @@ pub fn codegen_get_discriminant<'tcx>(
encoded_discr
} else {
// FIXME handle niche_start > i64::max_value()
fx.bcx.ins().iadd_imm(encoded_discr, -i64::try_from(niche_start).unwrap())
fx.bcx
.ins()
.iadd_imm(encoded_discr, -i64::try_from(niche_start).unwrap())
};
let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
let is_niche = {
codegen_icmp_imm(fx, IntCC::UnsignedLessThanOrEqual, relative_discr, i128::from(relative_max))
codegen_icmp_imm(
fx,
IntCC::UnsignedLessThanOrEqual,
relative_discr,
i128::from(relative_max),
)
};
// NOTE(eddyb) this addition needs to be performed on the final
@ -135,18 +150,16 @@ pub fn codegen_get_discriminant<'tcx>(
} else {
clif_intcast(fx, relative_discr, cast_to, false)
};
fx.bcx.ins().iadd_imm(
relative_discr,
i64::from(niche_variants.start().as_u32()),
)
fx.bcx
.ins()
.iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32()))
};
let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32()));
let discr = fx.bcx.ins().select(
is_niche,
niche_discr,
dataful_variant,
);
let dataful_variant = fx
.bcx
.ins()
.iconst(cast_to, i64::from(dataful_variant.as_u32()));
let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant);
CValue::by_val(discr, dest_layout)
}
}

View File

@ -109,7 +109,9 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
Linkage::Static => {
let name = tcx.crate_name(cnum);
let mut err = tcx.sess.struct_err(&format!("Can't load static lib {}", name.as_str()));
let mut err = tcx
.sess
.struct_err(&format!("Can't load static lib {}", name.as_str()));
err.note("rustc_codegen_cranelift can only load dylibs in JIT mode.");
err.emit();
}
@ -222,8 +224,10 @@ fn run_aot(
.as_str()
.to_string();
let mut metadata_artifact =
faerie::Artifact::new(crate::build_isa(tcx.sess, true).triple().clone(), metadata_cgu_name.clone());
let mut metadata_artifact = faerie::Artifact::new(
crate::build_isa(tcx.sess, true).triple().clone(),
metadata_cgu_name.clone(),
);
crate::metadata::write_metadata(tcx, &mut metadata_artifact);
let tmp_file = tcx

View File

@ -138,7 +138,10 @@ pub fn lane_type_and_count<'tcx>(
assert!(layout.ty.is_simd());
let lane_count = match layout.fields {
layout::FieldPlacement::Array { stride: _, count } => u32::try_from(count).unwrap(),
_ => panic!("Non vector type {:?} passed to or returned from simd_* intrinsic {}", layout.ty, intrinsic),
_ => panic!(
"Non vector type {:?} passed to or returned from simd_* intrinsic {}",
layout.ty, intrinsic
),
};
let lane_layout = layout.field(fx, 0);
(lane_layout, lane_count)
@ -150,7 +153,13 @@ pub fn simd_for_each_lane<'tcx, B: Backend>(
x: CValue<'tcx>,
y: CValue<'tcx>,
ret: CPlace<'tcx>,
f: impl Fn(&mut FunctionCx<'_, 'tcx, B>, TyLayout<'tcx>, TyLayout<'tcx>, Value, Value) -> CValue<'tcx>,
f: impl Fn(
&mut FunctionCx<'_, 'tcx, B>,
TyLayout<'tcx>,
TyLayout<'tcx>,
Value,
Value,
) -> CValue<'tcx>,
) {
assert_eq!(x.layout(), y.layout());
let layout = x.layout();
@ -184,7 +193,10 @@ pub fn bool_to_zero_or_max_uint<'tcx>(
};
let zero = fx.bcx.ins().iconst(int_ty, 0);
let max = fx.bcx.ins().iconst(int_ty, (u64::max_value() >> (64 - int_ty.bits())) as i64);
let max = fx
.bcx
.ins()
.iconst(int_ty, (u64::max_value() >> (64 - int_ty.bits())) as i64);
let mut res = crate::common::codegen_select(&mut fx.bcx, val, max, zero);
if ty.is_float() {
@ -196,83 +208,131 @@ pub fn bool_to_zero_or_max_uint<'tcx>(
macro_rules! simd_cmp {
($fx:expr, $intrinsic:expr, $cc:ident($x:ident, $y:ident) -> $ret:ident) => {
simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, res_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) | ty::Int(_) => codegen_icmp(fx, IntCC::$cc, x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
});
simd_for_each_lane(
$fx,
$intrinsic,
$x,
$y,
$ret,
|fx, lane_layout, res_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) | ty::Int(_) => codegen_icmp(fx, IntCC::$cc, x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
},
);
};
($fx:expr, $intrinsic:expr, $cc_u:ident|$cc_s:ident($x:ident, $y:ident) -> $ret:ident) => {
simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, res_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) => codegen_icmp(fx, IntCC::$cc_u, x_lane, y_lane),
ty::Int(_) => codegen_icmp(fx, IntCC::$cc_s, x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
});
simd_for_each_lane(
$fx,
$intrinsic,
$x,
$y,
$ret,
|fx, lane_layout, res_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) => codegen_icmp(fx, IntCC::$cc_u, x_lane, y_lane),
ty::Int(_) => codegen_icmp(fx, IntCC::$cc_s, x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
},
);
};
}
macro_rules! simd_int_binop {
($fx:expr, $intrinsic:expr, $op:ident($x:ident, $y:ident) -> $ret:ident) => {
simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().$op(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
});
simd_for_each_lane(
$fx,
$intrinsic,
$x,
$y,
$ret,
|fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().$op(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
},
);
};
($fx:expr, $intrinsic:expr, $op_u:ident|$op_s:ident($x:ident, $y:ident) -> $ret:ident) => {
simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) => fx.bcx.ins().$op_u(x_lane, y_lane),
ty::Int(_) => fx.bcx.ins().$op_s(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
});
simd_for_each_lane(
$fx,
$intrinsic,
$x,
$y,
$ret,
|fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) => fx.bcx.ins().$op_u(x_lane, y_lane),
ty::Int(_) => fx.bcx.ins().$op_s(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
},
);
};
}
macro_rules! simd_int_flt_binop {
($fx:expr, $intrinsic:expr, $op:ident|$op_f:ident($x:ident, $y:ident) -> $ret:ident) => {
simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().$op(x_lane, y_lane),
ty::Float(_) => fx.bcx.ins().$op_f(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
});
simd_for_each_lane(
$fx,
$intrinsic,
$x,
$y,
$ret,
|fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().$op(x_lane, y_lane),
ty::Float(_) => fx.bcx.ins().$op_f(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
},
);
};
($fx:expr, $intrinsic:expr, $op_u:ident|$op_s:ident|$op_f:ident($x:ident, $y:ident) -> $ret:ident) => {
simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) => fx.bcx.ins().$op_u(x_lane, y_lane),
ty::Int(_) => fx.bcx.ins().$op_s(x_lane, y_lane),
ty::Float(_) => fx.bcx.ins().$op_f(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
});
simd_for_each_lane(
$fx,
$intrinsic,
$x,
$y,
$ret,
|fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) => fx.bcx.ins().$op_u(x_lane, y_lane),
ty::Int(_) => fx.bcx.ins().$op_s(x_lane, y_lane),
ty::Float(_) => fx.bcx.ins().$op_f(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
},
);
};
}
macro_rules! simd_flt_binop {
($fx:expr, $intrinsic:expr, $op:ident($x:ident, $y:ident) -> $ret:ident) => {
simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Float(_) => fx.bcx.ins().$op(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
});
}
simd_for_each_lane(
$fx,
$intrinsic,
$x,
$y,
$ret,
|fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Float(_) => fx.bcx.ins().$op(x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
CValue::by_val(res_lane, ret_lane_layout)
},
);
};
}
pub fn codegen_intrinsic_call<'tcx>(
@ -297,7 +357,10 @@ pub fn codegen_intrinsic_call<'tcx>(
trap_unreachable(fx, "[corruption] Called intrinsic::unreachable.");
}
"transmute" => {
trap_unreachable(fx, "[corruption] Called intrinsic::transmute with uninhabited argument.");
trap_unreachable(
fx,
"[corruption] Called intrinsic::transmute with uninhabited argument.",
);
}
_ => unimplemented!("unsupported instrinsic {}", intrinsic),
}

View File

@ -71,8 +71,8 @@ mod prelude {
};
pub use rustc::ty::layout::{self, Abi, LayoutOf, Scalar, Size, TyLayout, VariantIdx};
pub use rustc::ty::{
self, FnSig, Instance, InstanceDef, ParamEnv, PolyFnSig, Ty, TyCtxt,
TypeAndMut, TypeFoldable,
self, FnSig, Instance, InstanceDef, ParamEnv, PolyFnSig, Ty, TyCtxt, TypeAndMut,
TypeFoldable,
};
pub use rustc_data_structures::{
fx::{FxHashMap, FxHashSet},
@ -102,7 +102,7 @@ mod prelude {
pub use crate::debuginfo::{DebugContext, FunctionDebugContext};
pub use crate::trap::*;
pub use crate::unimpl::{unimpl, with_unimpl_span};
pub use crate::value_and_place::{CValue, CPlace, CPlaceInner};
pub use crate::value_and_place::{CPlace, CPlaceInner, CValue};
pub use crate::{Caches, CodegenCx};
pub struct PrintOnPanic<F: Fn() -> String>(pub F);
@ -175,14 +175,18 @@ fn provide(&self, providers: &mut Providers) {
if tcx.sess.opts.actually_rustdoc {
// rustdoc needs to be able to document functions that use all the features, so
// whitelist them all
tcx.arena.alloc(target_features_whitelist::all_known_features()
.map(|(a, b)| (a.to_string(), b))
.collect())
tcx.arena.alloc(
target_features_whitelist::all_known_features()
.map(|(a, b)| (a.to_string(), b))
.collect(),
)
} else {
tcx.arena.alloc(target_features_whitelist::target_feature_whitelist(tcx.sess)
.iter()
.map(|&(a, b)| (a.to_string(), b))
.collect())
tcx.arena.alloc(
target_features_whitelist::target_feature_whitelist(tcx.sess)
.iter()
.map(|&(a, b)| (a.to_string(), b))
.collect(),
)
}
};
}
@ -252,11 +256,16 @@ fn build_isa(sess: &Session, enable_pic: bool) -> Box<dyn isa::TargetIsa + 'stat
flags_builder.set("is_pic", "false").unwrap();
}
flags_builder.set("probestack_enabled", "false").unwrap(); // __cranelift_probestack is not provided
flags_builder.set("enable_verifier", if cfg!(debug_assertions) {
"true"
} else {
"false"
}).unwrap();
flags_builder
.set(
"enable_verifier",
if cfg!(debug_assertions) {
"true"
} else {
"false"
},
)
.unwrap();
// FIXME(CraneStation/cranelift#732) fix LICM in presence of jump tables
//flags_builder.set("opt_level", "best").unwrap();

View File

@ -1,4 +1,4 @@
use rustc::mir::mono::{MonoItem, Linkage as RLinkage, Visibility};
use rustc::mir::mono::{Linkage as RLinkage, MonoItem, Visibility};
use crate::prelude::*;

View File

@ -1,5 +1,5 @@
use crate::prelude::*;
use crate::intrinsics::*;
use crate::prelude::*;
use rustc::ty::subst::SubstsRef;

View File

@ -2,10 +2,7 @@
/// Create the `main` function which will initialize the rust runtime and call
/// users main function.
pub fn maybe_create_entry_wrapper(
tcx: TyCtxt<'_>,
module: &mut Module<impl Backend + 'static>,
) {
pub fn maybe_create_entry_wrapper(tcx: TyCtxt<'_>, module: &mut Module<impl Backend + 'static>) {
use rustc::middle::lang_items::StartFnLangItem;
use rustc::session::config::EntryFnType;

View File

@ -1,9 +1,9 @@
use std::fs::File;
use std::path::Path;
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc::session::config;
use rustc::ty::TyCtxt;
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc_codegen_ssa::METADATA_FILENAME;
use rustc_data_structures::owning_ref::{self, OwningRef};
use rustc_data_structures::rustc_erase_owner;
@ -41,40 +41,44 @@ fn get_dylib_metadata(
use object::Object;
let file = std::fs::read(path).map_err(|e| format!("read:{:?}", e))?;
let file = object::File::parse(&file).map_err(|e| format!("parse: {:?}", e))?;
let buf = file.section_data_by_name(".rustc").ok_or("no .rustc section")?.into_owned();
let buf = file
.section_data_by_name(".rustc")
.ok_or("no .rustc section")?
.into_owned();
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
Ok(rustc_erase_owner!(buf.map_owner_box()))
}
}
// Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112
pub fn write_metadata(
tcx: TyCtxt<'_>,
artifact: &mut faerie::Artifact
) -> EncodedMetadata {
use std::io::Write;
use flate2::Compression;
pub fn write_metadata(tcx: TyCtxt<'_>, artifact: &mut faerie::Artifact) -> EncodedMetadata {
use flate2::write::DeflateEncoder;
use flate2::Compression;
use std::io::Write;
#[derive(PartialEq, Eq, PartialOrd, Ord)]
enum MetadataKind {
None,
Uncompressed,
Compressed
Compressed,
}
let kind = tcx.sess.crate_types.borrow().iter().map(|ty| {
match *ty {
config::CrateType::Executable |
config::CrateType::Staticlib |
config::CrateType::Cdylib => MetadataKind::None,
let kind = tcx
.sess
.crate_types
.borrow()
.iter()
.map(|ty| match *ty {
config::CrateType::Executable
| config::CrateType::Staticlib
| config::CrateType::Cdylib => MetadataKind::None,
config::CrateType::Rlib => MetadataKind::Uncompressed,
config::CrateType::Dylib |
config::CrateType::ProcMacro => MetadataKind::Compressed,
}
}).max().unwrap_or(MetadataKind::None);
config::CrateType::Dylib | config::CrateType::ProcMacro => MetadataKind::Compressed,
})
.max()
.unwrap_or(MetadataKind::None);
if kind == MetadataKind::None {
return EncodedMetadata::new();
@ -88,19 +92,27 @@ enum MetadataKind {
assert!(kind == MetadataKind::Compressed);
let mut compressed = tcx.metadata_encoding_version();
DeflateEncoder::new(&mut compressed, Compression::fast())
.write_all(&metadata.raw_data).unwrap();
.write_all(&metadata.raw_data)
.unwrap();
artifact.declare(".rustc", faerie::Decl::section(faerie::SectionKind::Data)).unwrap();
artifact.define_with_symbols(".rustc", compressed, {
let mut map = std::collections::BTreeMap::new();
// FIXME implement faerie elf backend section custom symbols
// For MachO this is necessary to prevent the linker from throwing away the .rustc section,
// but for ELF it isn't.
if tcx.sess.target.target.options.is_like_osx {
map.insert(rustc::middle::exported_symbols::metadata_symbol_name(tcx), 0);
}
map
}).unwrap();
artifact
.declare(".rustc", faerie::Decl::section(faerie::SectionKind::Data))
.unwrap();
artifact
.define_with_symbols(".rustc", compressed, {
let mut map = std::collections::BTreeMap::new();
// FIXME implement faerie elf backend section custom symbols
// For MachO this is necessary to prevent the linker from throwing away the .rustc section,
// but for ELF it isn't.
if tcx.sess.target.target.options.is_like_osx {
map.insert(
rustc::middle::exported_symbols::metadata_symbol_name(tcx),
0,
);
}
map
})
.unwrap();
metadata
}

View File

@ -5,11 +5,35 @@ pub fn bin_op_to_intcc(bin_op: BinOp, signed: bool) -> Option<IntCC> {
use IntCC::*;
Some(match bin_op {
Eq => Equal,
Lt => if signed { SignedLessThan } else { UnsignedLessThan},
Le => if signed { SignedLessThanOrEqual } else { UnsignedLessThanOrEqual},
Lt => {
if signed {
SignedLessThan
} else {
UnsignedLessThan
}
}
Le => {
if signed {
SignedLessThanOrEqual
} else {
UnsignedLessThanOrEqual
}
}
Ne => NotEqual,
Ge => if signed { SignedGreaterThanOrEqual } else { UnsignedGreaterThanOrEqual },
Gt => if signed { SignedGreaterThan } else { UnsignedGreaterThan },
Ge => {
if signed {
SignedGreaterThanOrEqual
} else {
UnsignedGreaterThanOrEqual
}
}
Gt => {
if signed {
SignedGreaterThan
} else {
UnsignedGreaterThan
}
}
_ => return None,
})
}
@ -41,9 +65,9 @@ pub fn codegen_binop<'tcx>(
let lhs = in_lhs.load_scalar(fx);
let rhs = in_rhs.load_scalar(fx);
let (lhs, rhs) = if
(bin_op == BinOp::Eq || bin_op == BinOp::Ne)
&& (in_lhs.layout().ty.sty == fx.tcx.types.i8.sty || in_lhs.layout().ty.sty == fx.tcx.types.i16.sty)
let (lhs, rhs) = if (bin_op == BinOp::Eq || bin_op == BinOp::Ne)
&& (in_lhs.layout().ty.sty == fx.tcx.types.i8.sty
|| in_lhs.layout().ty.sty == fx.tcx.types.i16.sty)
{
// FIXME(CraneStation/cranelift#896) icmp_imm.i8/i16 with eq/ne for signed ints is implemented wrong.
(
@ -64,14 +88,15 @@ pub fn codegen_binop<'tcx>(
match in_lhs.layout().ty.sty {
ty::Bool => crate::num::trans_bool_binop(fx, bin_op, in_lhs, in_rhs),
ty::Uint(_) | ty::Int(_)=> {
crate::num::trans_int_binop(fx, bin_op, in_lhs, in_rhs)
}
ty::Uint(_) | ty::Int(_) => crate::num::trans_int_binop(fx, bin_op, in_lhs, in_rhs),
ty::Float(_) => crate::num::trans_float_binop(fx, bin_op, in_lhs, in_rhs),
ty::RawPtr(..) | ty::FnPtr(..) => {
crate::num::trans_ptr_binop(fx, bin_op, in_lhs, in_rhs)
}
_ => unimplemented!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty),
ty::RawPtr(..) | ty::FnPtr(..) => crate::num::trans_ptr_binop(fx, bin_op, in_lhs, in_rhs),
_ => unimplemented!(
"{:?}({:?}, {:?})",
bin_op,
in_lhs.layout().ty,
in_rhs.layout().ty
),
}
}
@ -124,8 +149,20 @@ pub fn trans_int_binop<'tcx>(
BinOp::Add => b.iadd(lhs, rhs),
BinOp::Sub => b.isub(lhs, rhs),
BinOp::Mul => b.imul(lhs, rhs),
BinOp::Div => if signed { b.sdiv(lhs, rhs) } else { b.udiv(lhs, rhs) },
BinOp::Rem => if signed { b.srem(lhs, rhs) } else { b.urem(lhs, rhs) },
BinOp::Div => {
if signed {
b.sdiv(lhs, rhs)
} else {
b.udiv(lhs, rhs)
}
}
BinOp::Rem => {
if signed {
b.srem(lhs, rhs)
} else {
b.urem(lhs, rhs)
}
}
BinOp::BitXor => b.bxor(lhs, rhs),
BinOp::BitAnd => b.band(lhs, rhs),
BinOp::BitOr => b.bor(lhs, rhs),
@ -144,7 +181,12 @@ pub fn trans_int_binop<'tcx>(
}
}
// Compare binops handles by `codegen_binop`.
_ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty),
_ => unreachable!(
"{:?}({:?}, {:?})",
bin_op,
in_lhs.layout().ty,
in_rhs.layout().ty
),
};
CValue::by_val(val, in_lhs.layout())
@ -239,7 +281,11 @@ pub fn trans_checked_int_binop<'tcx>(
};
let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow);
let out_place = CPlace::new_stack_slot(fx, fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()));
let out_place = CPlace::new_stack_slot(
fx,
fx.tcx
.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()),
);
let out_layout = out_place.layout();
out_place.write_cvalue(fx, CValue::by_val_pair(res, has_overflow, out_layout));
@ -341,14 +387,24 @@ pub fn trans_ptr_binop<'tcx>(
BinOp::Lt | BinOp::Le | BinOp::Ge | BinOp::Gt => {
let ptr_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_ptr, rhs_ptr);
let ptr_cmp = fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr);
let extra_cmp = fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_extra, rhs_extra);
let ptr_cmp =
fx.bcx
.ins()
.icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr);
let extra_cmp = fx.bcx.ins().icmp(
bin_op_to_intcc(bin_op, false).unwrap(),
lhs_extra,
rhs_extra,
);
fx.bcx.ins().select(ptr_eq, extra_cmp, ptr_cmp)
}
_ => panic!("bin_op {:?} on ptr", bin_op),
};
CValue::by_val(fx.bcx.ins().bint(types::I8, res), fx.layout_of(fx.tcx.types.bool))
CValue::by_val(
fx.bcx.ins().bint(types::I8, res),
fx.layout_of(fx.tcx.types.bool),
)
}
}

View File

@ -4,11 +4,7 @@
use cranelift::codegen::{
entity::SecondaryMap,
ir::{
self,
entities::AnyEntity,
function::DisplayFunctionAnnotations,
},
ir::{self, entities::AnyEntity, function::DisplayFunctionAnnotations},
write::{FuncWriter, PlainWriter},
ValueLabelsRanges,
};
@ -82,7 +78,13 @@ pub fn new<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self {
global_comments: vec![
format!("symbol {}", tcx.symbol_name(instance).as_str()),
format!("instance {:?}", instance),
format!("sig {:?}", tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &instance.fn_sig(tcx))),
format!(
"sig {:?}",
tcx.normalize_erasing_late_bound_regions(
ParamEnv::reveal_all(),
&instance.fn_sig(tcx)
)
),
String::new(),
],
entity_comments: HashMap::new(),
@ -218,7 +220,9 @@ pub fn write_clif_file<'tcx>(
&mut clif,
&func,
&DisplayFunctionAnnotations {
isa: Some(&*crate::build_isa(tcx.sess, true /* PIC doesn't matter here */)),
isa: Some(&*crate::build_isa(
tcx.sess, true, /* PIC doesn't matter here */
)),
value_ranges,
},
)

View File

@ -115,8 +115,10 @@
///
/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
/// iterator!
pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<Symbol>)> {
ARM_WHITELIST.iter().cloned()
pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol>)> {
ARM_WHITELIST
.iter()
.cloned()
.chain(AARCH64_WHITELIST.iter().cloned())
.chain(X86_WHITELIST.iter().cloned())
.chain(HEXAGON_WHITELIST.iter().cloned())
@ -125,9 +127,7 @@ pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<Symbol>)
.chain(WASM_WHITELIST.iter().cloned())
}
pub fn target_feature_whitelist(sess: &Session)
-> &'static [(&'static str, Option<Symbol>)]
{
pub fn target_feature_whitelist(sess: &Session) -> &'static [(&'static str, Option<Symbol>)] {
match &*sess.target.target.arch {
"arm" => ARM_WHITELIST,
"aarch64" => AARCH64_WHITELIST,

View File

@ -1,13 +1,21 @@
use crate::prelude::*;
fn codegen_print(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: &str) {
let puts = fx.module.declare_function("puts", Linkage::Import, &Signature {
call_conv: CallConv::SystemV,
params: vec![AbiParam::new(pointer_ty(fx.tcx))],
returns: vec![],
}).unwrap();
let puts = fx
.module
.declare_function(
"puts",
Linkage::Import,
&Signature {
call_conv: CallConv::SystemV,
params: vec![AbiParam::new(pointer_ty(fx.tcx))],
returns: vec![],
},
)
.unwrap();
let puts = fx.module.declare_func_in_func(puts, &mut fx.bcx.func);
#[cfg(debug_assertions)] {
#[cfg(debug_assertions)]
{
fx.add_entity_comment(puts, "puts");
}
@ -15,13 +23,22 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, ms
let real_msg = format!("trap at {:?} ({}): {}\0", fx.instance, symbol_name, msg);
let mut data_ctx = DataContext::new();
data_ctx.define(real_msg.as_bytes().to_vec().into_boxed_slice());
let msg_id = fx.module.declare_data(&(symbol_name.as_str().to_string() + msg), Linkage::Local, false, None).unwrap();
let msg_id = fx
.module
.declare_data(
&(symbol_name.as_str().to_string() + msg),
Linkage::Local,
false,
None,
)
.unwrap();
// Ignore DuplicateDefinition error, as the data will be the same
let _ = fx.module.define_data(msg_id, &data_ctx);
let local_msg_id = fx.module.declare_data_in_func(msg_id, fx.bcx.func);
#[cfg(debug_assertions)] {
#[cfg(debug_assertions)]
{
fx.add_entity_comment(local_msg_id, msg);
}
let msg_ptr = fx.bcx.ins().global_value(pointer_ty(fx.tcx), local_msg_id);
@ -31,7 +48,10 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, ms
/// Use this when `rustc_codegen_llvm` would insert a call to the panic handler.
///
/// Trap code: user0
pub fn trap_panic(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: impl AsRef<str>) {
pub fn trap_panic(
fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>,
msg: impl AsRef<str>,
) {
codegen_print(fx, msg.as_ref());
fx.bcx.ins().trap(TrapCode::User(0));
}
@ -40,7 +60,10 @@ pub fn trap_panic(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, m
/// so you can **not** add instructions to it afterwards.
///
/// Trap code: user65535
pub fn trap_unreachable(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: impl AsRef<str>) {
pub fn trap_unreachable(
fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>,
msg: impl AsRef<str>,
) {
codegen_print(fx, msg.as_ref());
fx.bcx.ins().trap(TrapCode::User(!0));
}
@ -50,7 +73,10 @@ pub fn trap_unreachable(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backe
/// to it afterwards.
///
/// Trap code: user65535
pub fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: impl AsRef<str>) {
pub fn trap_unimplemented(
fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>,
msg: impl AsRef<str>,
) {
codegen_print(fx, msg.as_ref());
let true_ = fx.bcx.ins().iconst(types::I32, 1);
fx.bcx.ins().trapnz(true_, TrapCode::User(!0));
@ -59,7 +85,11 @@ pub fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Bac
/// Like `trap_unreachable` but returns a fake value of the specified type.
///
/// Trap code: user65535
pub fn trap_unreachable_ret_value<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>, msg: impl AsRef<str>) -> CValue<'tcx> {
pub fn trap_unreachable_ret_value<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>,
dest_layout: TyLayout<'tcx>,
msg: impl AsRef<str>,
) -> CValue<'tcx> {
trap_unimplemented(fx, msg);
let zero = fx.bcx.ins().iconst(fx.pointer_type, 0);
CValue::by_ref(zero, dest_layout)
@ -68,7 +98,11 @@ pub fn trap_unreachable_ret_value<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl crane
/// Like `trap_unreachable` but returns a fake place for the specified type.
///
/// Trap code: user65535
pub fn trap_unreachable_ret_place<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>, dest_layout: TyLayout<'tcx>, msg: impl AsRef<str>) -> CPlace<'tcx> {
pub fn trap_unreachable_ret_place<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl cranelift_module::Backend>,
dest_layout: TyLayout<'tcx>,
msg: impl AsRef<str>,
) -> CPlace<'tcx> {
trap_unimplemented(fx, msg);
let zero = fx.bcx.ins().iconst(fx.pointer_type, 0);
CPlace::for_addr(zero, dest_layout)

View File

@ -15,15 +15,13 @@ pub fn unsized_info<'tcx>(
old_info: Option<Value>,
) -> Value {
let (source, target) =
fx.tcx.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
fx.tcx
.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
match (&source.sty, &target.sty) {
(&ty::Array(_, len), &ty::Slice(_)) => fx
.bcx
.ins()
.iconst(
fx.pointer_type,
len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64,
),
(&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst(
fx.pointer_type,
len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64,
),
(&ty::Dynamic(..), &ty::Dynamic(..)) => {
// For now, upcasts are limited to changes in marker
// traits, and hence never actually require an actual

View File

@ -19,7 +19,10 @@ fn codegen_field<'tcx>(
}
fn scalar_pair_calculate_b_offset(tcx: TyCtxt<'_>, a_scalar: &Scalar, b_scalar: &Scalar) -> i32 {
let b_offset = a_scalar.value.size(&tcx).align_to(b_scalar.value.align(&tcx).abi);
let b_offset = a_scalar
.value
.size(&tcx)
.align_to(b_scalar.value.align(&tcx).abi);
b_offset.bytes().try_into().unwrap()
}
@ -88,7 +91,10 @@ pub fn load_scalar<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> Val
}
/// Load a value pair with layout.abi of scalar pair
pub fn load_scalar_pair<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> (Value, Value) {
pub fn load_scalar_pair<'a>(
self,
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
) -> (Value, Value) {
let layout = self.1;
match self.0 {
CValueInner::ByRef(addr) => {
@ -100,12 +106,7 @@ pub fn load_scalar_pair<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -
let clif_ty1 = scalar_to_clif_type(fx.tcx, a_scalar.clone());
let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar.clone());
let val1 = fx.bcx.ins().load(clif_ty1, MemFlags::new(), addr, 0);
let val2 = fx.bcx.ins().load(
clif_ty2,
MemFlags::new(),
addr,
b_offset,
);
let val2 = fx.bcx.ins().load(clif_ty2, MemFlags::new(), addr, b_offset);
(val1, val2)
}
CValueInner::ByVal(_) => bug!("Please use load_scalar for ByVal"),
@ -144,20 +145,29 @@ pub fn const_val<'a>(
let val = match ty.sty {
ty::TyKind::Uint(UintTy::U128) | ty::TyKind::Int(IntTy::I128) => {
let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64);
let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64);
let msb = fx
.bcx
.ins()
.iconst(types::I64, (const_val >> 64) as u64 as i64);
fx.bcx.ins().iconcat(lsb, msb)
}
ty::TyKind::Bool => {
assert!(const_val == 0 || const_val == 1, "Invalid bool 0x{:032X}", const_val);
assert!(
const_val == 0 || const_val == 1,
"Invalid bool 0x{:032X}",
const_val
);
fx.bcx.ins().iconst(types::I8, const_val as i64)
}
ty::TyKind::Uint(_) | ty::TyKind::Ref(..) | ty::TyKind::RawPtr(.. )=> {
fx.bcx.ins().iconst(clif_ty, u64::try_from(const_val).expect("uint") as i64)
}
ty::TyKind::Int(_) => {
fx.bcx.ins().iconst(clif_ty, const_val as i128 as i64)
}
_ => panic!("CValue::const_val for non bool/integer/pointer type {:?} is not allowed", ty),
ty::TyKind::Uint(_) | ty::TyKind::Ref(..) | ty::TyKind::RawPtr(..) => fx
.bcx
.ins()
.iconst(clif_ty, u64::try_from(const_val).expect("uint") as i64),
ty::TyKind::Int(_) => fx.bcx.ins().iconst(clif_ty, const_val as i128 as i64),
_ => panic!(
"CValue::const_val for non bool/integer/pointer type {:?} is not allowed",
ty
),
};
CValue::by_val(val, layout)
@ -193,9 +203,9 @@ pub fn inner(&self) -> &CPlaceInner {
}
pub fn no_place(layout: TyLayout<'tcx>) -> CPlace<'tcx> {
CPlace{
CPlace {
inner: CPlaceInner::NoPlace,
layout
layout,
}
}
@ -299,7 +309,11 @@ pub fn write_cvalue(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, from: CVa
let from_ty = from.layout().ty;
let to_ty = self.layout().ty;
fn assert_assignable<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) {
fn assert_assignable<'tcx>(
fx: &FunctionCx<'_, 'tcx, impl Backend>,
from_ty: Ty<'tcx>,
to_ty: Ty<'tcx>,
) {
match (&from_ty.sty, &to_ty.sty) {
(ty::Ref(_, t, MutImmutable), ty::Ref(_, u, MutImmutable))
| (ty::Ref(_, t, MutMutable), ty::Ref(_, u, MutImmutable))
@ -308,9 +322,10 @@ fn assert_assignable<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, from_ty: Ty<
// &mut T -> &T is allowed
// &'a T -> &'b T is allowed
}
(ty::Ref(_, _, MutImmutable), ty::Ref(_, _, MutMutable)) => {
panic!("Cant assign value of type {} to place of type {}", from_ty, to_ty)
}
(ty::Ref(_, _, MutImmutable), ty::Ref(_, _, MutMutable)) => panic!(
"Cant assign value of type {} to place of type {}",
from_ty, to_ty
),
(ty::FnPtr(_), ty::FnPtr(_)) => {
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
ParamEnv::reveal_all(),
@ -328,14 +343,12 @@ fn assert_assignable<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, from_ty: Ty<
// fn(&T) -> for<'l> fn(&'l T) is allowed
}
(ty::Dynamic(from_traits, _), ty::Dynamic(to_traits, _)) => {
let from_traits = fx.tcx.normalize_erasing_late_bound_regions(
ParamEnv::reveal_all(),
from_traits,
);
let to_traits = fx.tcx.normalize_erasing_late_bound_regions(
ParamEnv::reveal_all(),
to_traits,
);
let from_traits = fx
.tcx
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from_traits);
let to_traits = fx
.tcx
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to_traits);
assert_eq!(
from_traits, to_traits,
"Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}",
@ -382,24 +395,17 @@ fn assert_assignable<'tcx>(fx: &FunctionCx<'_, 'tcx, impl Backend>, from_ty: Ty<
CValueInner::ByVal(val) => {
fx.bcx.ins().store(MemFlags::new(), val, addr, 0);
}
CValueInner::ByValPair(value, extra) => {
match dst_layout.abi {
Abi::ScalarPair(ref a_scalar, ref b_scalar) => {
let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
fx.bcx.ins().store(MemFlags::new(), value, addr, 0);
fx.bcx.ins().store(
MemFlags::new(),
extra,
addr,
b_offset,
);
}
_ => bug!(
"Non ScalarPair abi {:?} for ByValPair CValue",
dst_layout.abi
),
CValueInner::ByValPair(value, extra) => match dst_layout.abi {
Abi::ScalarPair(ref a_scalar, ref b_scalar) => {
let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
fx.bcx.ins().store(MemFlags::new(), value, addr, 0);
fx.bcx.ins().store(MemFlags::new(), extra, addr, b_offset);
}
}
_ => bug!(
"Non ScalarPair abi {:?} for ByValPair CValue",
dst_layout.abi
),
},
CValueInner::ByRef(from_addr) => {
let src_layout = from.1;
let size = dst_layout.size.bytes();
@ -468,7 +474,11 @@ pub fn write_place_ref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, dest:
dest.write_cvalue(fx, ptr);
} else {
let (value, extra) = self.to_addr_maybe_unsized(fx);
let ptr = CValue::by_val_pair(value, extra.expect("unsized type without metadata"), dest.layout());
let ptr = CValue::by_val_pair(
value,
extra.expect("unsized type without metadata"),
dest.layout(),
);
dest.write_cvalue(fx, ptr);
}
}

View File

@ -6,10 +6,7 @@
const SIZE_INDEX: usize = 1;
const ALIGN_INDEX: usize = 2;
pub fn drop_fn_of_obj(
fx: &mut FunctionCx<'_, '_, impl Backend>,
vtable: Value,
) -> Value {
pub fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, impl Backend>, vtable: Value) -> Value {
let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
fx.bcx.ins().load(
pointer_ty(fx.tcx),
@ -19,10 +16,7 @@ pub fn drop_fn_of_obj(
)
}
pub fn size_of_obj(
fx: &mut FunctionCx<'_, '_, impl Backend>,
vtable: Value,
) -> Value {
pub fn size_of_obj(fx: &mut FunctionCx<'_, '_, impl Backend>, vtable: Value) -> Value {
let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
fx.bcx.ins().load(
pointer_ty(fx.tcx),
@ -32,10 +26,7 @@ pub fn size_of_obj(
)
}
pub fn min_align_of_obj(
fx: &mut FunctionCx<'_, '_, impl Backend>,
vtable: Value,
) -> Value {
pub fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, impl Backend>, vtable: Value) -> Value {
let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
fx.bcx.ins().load(
pointer_ty(fx.tcx),
@ -86,11 +77,8 @@ fn build_vtable<'tcx>(
let tcx = fx.tcx;
let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
let drop_in_place_fn = import_function(
tcx,
fx.module,
Instance::resolve_drop_in_place(tcx, ty),
);
let drop_in_place_fn =
import_function(tcx, fx.module, Instance::resolve_drop_in_place(tcx, ty));
let mut components: Vec<_> = vec![Some(drop_in_place_fn), None, None];
@ -136,7 +124,15 @@ fn build_vtable<'tcx>(
&format!("vtable.{:?}.for.{:?}", trait_ref, ty),
Linkage::Local,
false,
Some(fx.tcx.data_layout.pointer_align.pref.bytes().try_into().unwrap())
Some(
fx.tcx
.data_layout
.pointer_align
.pref
.bytes()
.try_into()
.unwrap(),
),
)
.unwrap();