codegen_llvm: improve common patterns

This commit is contained in:
ljedrz 2018-10-08 16:58:26 +02:00
parent cd41765851
commit 0af79143ae
8 changed files with 86 additions and 115 deletions

View File

@ -695,14 +695,13 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
// If the value is a boolean, the range is 0..2 and that ultimately
// become 0..0 when the type becomes i1, which would be rejected
// by the LLVM verifier.
match scalar.value {
layout::Int(..) if !scalar.is_bool() => {
if let layout::Int(..) = scalar.value {
if !scalar.is_bool() {
let range = scalar.valid_range_exclusive(bx.cx);
if range.start != range.end {
bx.range_metadata(callsite, range);
}
}
_ => {}
}
}
for arg in &self.args {

View File

@ -94,9 +94,8 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
// Currently stack probes seem somewhat incompatible with the address
// sanitizer. With asan we're already protected from stack overflow anyway
// so we don't really need stack probes regardless.
match cx.sess().opts.debugging_opts.sanitizer {
Some(Sanitizer::Address) => return,
_ => {}
if let Some(Sanitizer::Address) = cx.sess().opts.debugging_opts.sanitizer {
return
}
// probestack doesn't play nice either with pgo-gen.

View File

@ -495,10 +495,8 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'
let sig = common::ty_fn_sig(cx, fn_ty);
let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
let lldecl = match cx.instances.borrow().get(&instance) {
Some(&val) => val,
None => bug!("Instance `{:?}` not already declared", instance)
};
let lldecl = cx.instances.borrow().get(&instance).cloned().unwrap_or_else(||
bug!("Instance `{:?}` not already declared", instance));
cx.stats.borrow_mut().n_closures += 1;
@ -836,12 +834,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
.iter()
.any(|(_, list)| {
use rustc::middle::dependency_format::Linkage;
list.iter().any(|linkage| {
match linkage {
Linkage::Dynamic => true,
_ => false,
}
})
list.iter().any(|&linkage| linkage == Linkage::Dynamic)
});
let allocator_module = if any_dynamic_crate {
None

View File

@ -336,16 +336,13 @@ pub fn langcall(tcx: TyCtxt,
msg: &str,
li: LangItem)
-> DefId {
match tcx.lang_items().require(li) {
Ok(id) => id,
Err(s) => {
let msg = format!("{} {}", msg, s);
match span {
Some(span) => tcx.sess.span_fatal(span, &msg[..]),
None => tcx.sess.fatal(&msg[..]),
}
tcx.lang_items().require(li).unwrap_or_else(|s| {
let msg = format!("{} {}", msg, s);
match span {
Some(span) => tcx.sess.span_fatal(span, &msg[..]),
None => tcx.sess.fatal(&msg[..]),
}
}
})
}
// To avoid UB from LLVM, these two functions mask RHS with an

View File

@ -249,14 +249,13 @@ fn check_and_apply_linkage(
// extern "C" fn() from being non-null, so we can't just declare a
// static and call it a day. Some linkages (like weak) will make it such
// that the static actually has a null value.
let llty2 = match ty.sty {
ty::RawPtr(ref mt) => cx.layout_of(mt.ty).llvm_type(cx),
_ => {
if span.is_some() {
cx.sess().span_fatal(span.unwrap(), "must have type `*const T` or `*mut T`")
} else {
bug!("must have type `*const T` or `*mut T`")
}
let llty2 = if let ty::RawPtr(ref mt) = ty.sty {
cx.layout_of(mt.ty).llvm_type(cx)
} else {
if let Some(span) = span {
cx.sess().span_fatal(span, "must have type `*const T` or `*mut T`")
} else {
bug!("must have type `*const T` or `*mut T`")
}
};
unsafe {
@ -273,9 +272,9 @@ fn check_and_apply_linkage(
let mut real_name = "_rust_extern_with_linkage_".to_string();
real_name.push_str(&sym);
let g2 = declare::define_global(cx, &real_name, llty).unwrap_or_else(||{
if span.is_some() {
if let Some(span) = span {
cx.sess().span_fatal(
span.unwrap(),
span,
&format!("symbol `{}` is already defined", &sym)
)
} else {

View File

@ -318,10 +318,8 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
return v;
}
match declare_intrinsic(self, key) {
Some(v) => return v,
None => bug!("unknown intrinsic '{}'", key)
}
declare_intrinsic(self, key).unwrap_or_else(|| bug!("unknown intrinsic '{}'", key))
}
/// Generate a new symbol name with the given prefix. This symbol name must
@ -465,9 +463,10 @@ impl LayoutOf for &'a CodegenCx<'ll, 'tcx> {
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty))
.unwrap_or_else(|e| match e {
LayoutError::SizeOverflow(_) => self.sess().fatal(&e.to_string()),
_ => bug!("failed to get layout for `{}`: {}", ty, e)
.unwrap_or_else(|e| if let LayoutError::SizeOverflow(_) = e {
self.sess().fatal(&e.to_string())
} else {
bug!("failed to get layout for `{}`: {}", ty, e)
})
}
}

View File

@ -539,10 +539,9 @@ pub fn codegen_intrinsic_call(
}
_ => {
let intr = match Intrinsic::find(&name) {
Some(intr) => intr,
None => bug!("unknown intrinsic '{}'", name),
};
let intr = Intrinsic::find(&name).unwrap_or_else(||
bug!("unknown intrinsic '{}'", name));
fn one<T>(x: Vec<T>) -> T {
assert_eq!(x.len(), 1);
x.into_iter().next().unwrap()
@ -1071,11 +1070,8 @@ fn generic_simd_intrinsic(
}
if name.starts_with("simd_shuffle") {
let n: usize = match name["simd_shuffle".len()..].parse() {
Ok(n) => n,
Err(_) => span_bug!(span,
"bad `simd_shuffle` instruction only caught in codegen?")
};
let n: usize = name["simd_shuffle".len()..].parse().unwrap_or_else(|_|
span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?"));
require_simd!(ret_ty, "return");
@ -1216,63 +1212,53 @@ fn generic_simd_intrinsic(
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
None);
unsafe { llvm::LLVMRustSetHasUnsafeAlgebra(c) };
return Ok(c);
Ok(c)
}
if name == "simd_fsqrt" {
return simd_simple_float_intrinsic("sqrt", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_fsin" {
return simd_simple_float_intrinsic("sin", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_fcos" {
return simd_simple_float_intrinsic("cos", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_fabs" {
return simd_simple_float_intrinsic("fabs", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_floor" {
return simd_simple_float_intrinsic("floor", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_ceil" {
return simd_simple_float_intrinsic("ceil", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_fexp" {
return simd_simple_float_intrinsic("exp", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_fexp2" {
return simd_simple_float_intrinsic("exp2", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_flog10" {
return simd_simple_float_intrinsic("log10", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_flog2" {
return simd_simple_float_intrinsic("log2", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_flog" {
return simd_simple_float_intrinsic("log", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_fpowi" {
return simd_simple_float_intrinsic("powi", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_fpow" {
return simd_simple_float_intrinsic("pow", in_elem, in_ty, in_len, bx, span, args);
}
if name == "simd_fma" {
return simd_simple_float_intrinsic("fma", in_elem, in_ty, in_len, bx, span, args);
match name {
"simd_fsqrt" => {
return simd_simple_float_intrinsic("sqrt", in_elem, in_ty, in_len, bx, span, args);
}
"simd_fsin" => {
return simd_simple_float_intrinsic("sin", in_elem, in_ty, in_len, bx, span, args);
}
"simd_fcos" => {
return simd_simple_float_intrinsic("cos", in_elem, in_ty, in_len, bx, span, args);
}
"simd_fabs" => {
return simd_simple_float_intrinsic("fabs", in_elem, in_ty, in_len, bx, span, args);
}
"simd_floor" => {
return simd_simple_float_intrinsic("floor", in_elem, in_ty, in_len, bx, span, args);
}
"simd_ceil" => {
return simd_simple_float_intrinsic("ceil", in_elem, in_ty, in_len, bx, span, args);
}
"simd_fexp" => {
return simd_simple_float_intrinsic("exp", in_elem, in_ty, in_len, bx, span, args);
}
"simd_fexp2" => {
return simd_simple_float_intrinsic("exp2", in_elem, in_ty, in_len, bx, span, args);
}
"simd_flog10" => {
return simd_simple_float_intrinsic("log10", in_elem, in_ty, in_len, bx, span, args);
}
"simd_flog2" => {
return simd_simple_float_intrinsic("log2", in_elem, in_ty, in_len, bx, span, args);
}
"simd_flog" => {
return simd_simple_float_intrinsic("log", in_elem, in_ty, in_len, bx, span, args);
}
"simd_fpowi" => {
return simd_simple_float_intrinsic("powi", in_elem, in_ty, in_len, bx, span, args);
}
"simd_fpow" => {
return simd_simple_float_intrinsic("pow", in_elem, in_ty, in_len, bx, span, args);
}
"simd_fma" => {
return simd_simple_float_intrinsic("fma", in_elem, in_ty, in_len, bx, span, args);
}
_ => { /* fallthrough */ }
}
// FIXME: use:
@ -1364,7 +1350,7 @@ fn generic_simd_intrinsic(
}
};
assert!(pointer_count > 0);
assert!(pointer_count - 1 == ptr_count(arg_tys[0].simd_type(tcx)));
assert_eq!(pointer_count - 1, ptr_count(arg_tys[0].simd_type(tcx)));
assert_eq!(underlying_ty, non_ptr(arg_tys[0].simd_type(tcx)));
// The element type of the third argument must be a signed integer type of any width:
@ -1461,7 +1447,7 @@ fn generic_simd_intrinsic(
}
};
assert!(pointer_count > 0);
assert!(pointer_count - 1 == ptr_count(arg_tys[0].simd_type(tcx)));
assert_eq!(pointer_count - 1, ptr_count(arg_tys[0].simd_type(tcx)));
assert_eq!(underlying_ty, non_ptr(arg_tys[0].simd_type(tcx)));
// The element type of the third argument must be a signed integer type of any width:

View File

@ -65,13 +65,12 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
let mut name = String::with_capacity(32);
let printer = DefPathBasedNames::new(cx.tcx, true, true);
printer.push_type_name(layout.ty, &mut name);
match (&layout.ty.sty, &layout.variants) {
(&ty::Adt(def, _), &layout::Variants::Single { index }) => {
if def.is_enum() && !def.variants.is_empty() {
write!(&mut name, "::{}", def.variants[index].name).unwrap();
}
if let (&ty::Adt(def, _), &layout::Variants::Single { index })
= (&layout.ty.sty, &layout.variants)
{
if def.is_enum() && !def.variants.is_empty() {
write!(&mut name, "::{}", def.variants[index].name).unwrap();
}
_ => {}
}
Some(name)
}
@ -155,7 +154,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
debug!("struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}",
padding, offset, layout.size);
result.push(Type::padding_filler(cx, padding, padding_align));
assert!(result.len() == 1 + field_count * 2);
assert_eq!(result.len(), 1 + field_count * 2);
} else {
debug!("struct_llfields: offset: {:?} stride: {:?}",
offset, layout.size);