Remove the intrinsic for align_offset

Keep only the language item. This removes some indirection and makes
codegen worse for debug builds, but simplifies code significantly, which
is a good tradeoff to make, in my opinion.

Besides, the codegen can be improved even further with some constant
evaluation improvements that we expect to happen in the future.
This commit is contained in:
Simonas Kazlauskas 2018-05-04 00:49:22 +03:00
parent 680031b016
commit 6d5bf8b23f
5 changed files with 26 additions and 84 deletions

View file

@ -25,7 +25,6 @@ use type_of::LayoutLlvmExt;
use rustc::ty::{self, Ty};
use rustc::ty::layout::{HasDataLayout, LayoutOf};
use rustc::hir;
use rustc::middle::lang_items::AlignOffsetLangItem;
use syntax::ast;
use syntax::symbol::Symbol;
use builder::Builder;
@ -390,31 +389,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
args[0].deref(bx.cx).codegen_get_discr(bx, ret_ty)
}
"align_offset" => {
let (ptr, align) = (args[0].immediate(), args[1].immediate());
let stride_of_t = bx.cx.layout_of(substs.type_at(0)).size_and_align().0.bytes();
let stride = C_usize(bx.cx, stride_of_t);
let zero = C_null(bx.cx.isize_ty);
let max = C_int(cx.isize_ty, -1); // -1isize (wherein I cheat horribly to make !0usize)
if stride_of_t <= 1 {
// offset = ptr as usize % align => offset = ptr as usize & (align - 1)
let modmask = bx.sub(align, C_usize(bx.cx, 1));
let offset = bx.and(bx.ptrtoint(ptr, bx.cx.isize_ty), modmask);
let is_zero = bx.icmp(llvm::IntPredicate::IntEQ, offset, zero);
// if offset == 0 { 0 } else { if stride_of_t == 1 { align - offset } else { !0 } }
bx.select(is_zero, zero, if stride_of_t == 1 {
bx.sub(align, offset)
} else {
max
})
} else {
let did = ::common::langcall(bx.tcx(), Some(span), "", AlignOffsetLangItem);
let instance = ty::Instance::mono(bx.tcx(), did);
let llfn = ::callee::get_fn(bx.cx, instance);
bx.call(llfn, &[ptr, align, stride], None)
}
}
name if name.starts_with("simd_") => {
match generic_simd_intrinsic(bx, name,
callee_ty,