Remove a lot of methods from BuilderMethods
This commit is contained in:
parent
794ecd965a
commit
bcab49720e
@ -133,19 +133,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count_insn(&self, category: &str) {
|
|
||||||
if self.sess().codegen_stats() {
|
|
||||||
self.stats.borrow_mut().n_llvm_insns += 1;
|
|
||||||
}
|
|
||||||
if self.sess().count_llvm_insns() {
|
|
||||||
*self.stats
|
|
||||||
.borrow_mut()
|
|
||||||
.llvm_insns
|
|
||||||
.entry(category.to_string())
|
|
||||||
.or_insert(0) += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_value_name(&mut self, value: &'ll Value, name: &str) {
|
fn set_value_name(&mut self, value: &'ll Value, name: &str) {
|
||||||
let cname = SmallCStr::new(name);
|
let cname = SmallCStr::new(name);
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -159,12 +146,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ret_void(&mut self) {
|
fn ret_void(&mut self) {
|
||||||
self.count_insn("retvoid");
|
self.count_insn("retvoid");
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -897,17 +878,12 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Miscellaneous instructions */
|
/* Miscellaneous instructions */
|
||||||
fn empty_phi(&mut self, ty: &'ll Type) -> &'ll Value {
|
|
||||||
self.count_insn("emptyphi");
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMBuildPhi(self.llbuilder, ty, noname())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
|
fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
|
||||||
assert_eq!(vals.len(), bbs.len());
|
|
||||||
let phi = self.empty_phi(ty);
|
|
||||||
self.count_insn("addincoming");
|
self.count_insn("addincoming");
|
||||||
|
assert_eq!(vals.len(), bbs.len());
|
||||||
|
let phi = unsafe {
|
||||||
|
llvm::LLVMBuildPhi(self.llbuilder, ty, noname())
|
||||||
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMAddIncoming(phi, vals.as_ptr(),
|
llvm::LLVMAddIncoming(phi, vals.as_ptr(),
|
||||||
bbs.as_ptr(),
|
bbs.as_ptr(),
|
||||||
@ -1012,15 +988,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None);
|
self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("minnum");
|
|
||||||
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
|
|
||||||
}
|
|
||||||
fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("maxnum");
|
|
||||||
unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn select(
|
fn select(
|
||||||
&mut self, cond: &'ll Value,
|
&mut self, cond: &'ll Value,
|
||||||
then_val: &'ll Value,
|
then_val: &'ll Value,
|
||||||
@ -1032,14 +999,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
|
|
||||||
self.count_insn("vaarg");
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_element(&mut self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value {
|
fn extract_element(&mut self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value {
|
||||||
self.count_insn("extractelement");
|
self.count_insn("extractelement");
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -1047,24 +1006,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_element(
|
|
||||||
&mut self, vec: &'ll Value,
|
|
||||||
elt: &'ll Value,
|
|
||||||
idx: &'ll Value,
|
|
||||||
) -> &'ll Value {
|
|
||||||
self.count_insn("insertelement");
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, noname())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shuffle_vector(&mut self, v1: &'ll Value, v2: &'ll Value, mask: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("shufflevector");
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, noname())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn vector_splat(&mut self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
|
fn vector_splat(&mut self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
let elt_ty = self.cx.val_ty(elt);
|
let elt_ty = self.cx.val_ty(elt);
|
||||||
@ -1075,81 +1016,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.fadd_fast");
|
|
||||||
unsafe {
|
|
||||||
// FIXME: add a non-fast math version once
|
|
||||||
// https://bugs.llvm.org/show_bug.cgi?id=36732
|
|
||||||
// is fixed.
|
|
||||||
let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
|
|
||||||
llvm::LLVMRustSetHasUnsafeAlgebra(instr);
|
|
||||||
instr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.fmul_fast");
|
|
||||||
unsafe {
|
|
||||||
// FIXME: add a non-fast math version once
|
|
||||||
// https://bugs.llvm.org/show_bug.cgi?id=36732
|
|
||||||
// is fixed.
|
|
||||||
let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
|
|
||||||
llvm::LLVMRustSetHasUnsafeAlgebra(instr);
|
|
||||||
instr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.add");
|
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
|
|
||||||
}
|
|
||||||
fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.mul");
|
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
|
|
||||||
}
|
|
||||||
fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.and");
|
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
|
|
||||||
}
|
|
||||||
fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.or");
|
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
|
|
||||||
}
|
|
||||||
fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.xor");
|
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
|
|
||||||
}
|
|
||||||
fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.fmin");
|
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) }
|
|
||||||
}
|
|
||||||
fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.fmax");
|
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) }
|
|
||||||
}
|
|
||||||
fn vector_reduce_fmin_fast(&mut self, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.fmin_fast");
|
|
||||||
unsafe {
|
|
||||||
let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true);
|
|
||||||
llvm::LLVMRustSetHasUnsafeAlgebra(instr);
|
|
||||||
instr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn vector_reduce_fmax_fast(&mut self, src: &'ll Value) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.fmax_fast");
|
|
||||||
unsafe {
|
|
||||||
let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true);
|
|
||||||
llvm::LLVMRustSetHasUnsafeAlgebra(instr);
|
|
||||||
instr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.min");
|
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
|
|
||||||
}
|
|
||||||
fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
|
|
||||||
self.count_insn("vector.reduce.max");
|
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_value(&mut self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
|
fn extract_value(&mut self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
|
||||||
self.count_insn("extractvalue");
|
self.count_insn("extractvalue");
|
||||||
assert_eq!(idx as c_uint as u64, idx);
|
assert_eq!(idx as c_uint as u64, idx);
|
||||||
@ -1177,12 +1043,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMAddClause(landing_pad, clause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_cleanup(&mut self, landing_pad: &'ll Value) {
|
fn set_cleanup(&mut self, landing_pad: &'ll Value) {
|
||||||
self.count_insn("setcleanup");
|
self.count_insn("setcleanup");
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -1236,14 +1096,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
Funclet::new(ret.expect("LLVM does not have support for catchpad"))
|
Funclet::new(ret.expect("LLVM does not have support for catchpad"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value {
|
|
||||||
self.count_insn("catchret");
|
|
||||||
let ret = unsafe {
|
|
||||||
llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind)
|
|
||||||
};
|
|
||||||
ret.expect("LLVM does not have support for catchret")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn catch_switch(
|
fn catch_switch(
|
||||||
&mut self,
|
&mut self,
|
||||||
parent: Option<&'ll Value>,
|
parent: Option<&'ll Value>,
|
||||||
@ -1347,67 +1199,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_store<'b>(&mut self,
|
|
||||||
val: &'ll Value,
|
|
||||||
ptr: &'ll Value) -> &'ll Value {
|
|
||||||
let dest_ptr_ty = self.cx.val_ty(ptr);
|
|
||||||
let stored_ty = self.cx.val_ty(val);
|
|
||||||
let stored_ptr_ty = self.cx.type_ptr_to(stored_ty);
|
|
||||||
|
|
||||||
assert_eq!(self.cx.type_kind(dest_ptr_ty), TypeKind::Pointer);
|
|
||||||
|
|
||||||
if dest_ptr_ty == stored_ptr_ty {
|
|
||||||
ptr
|
|
||||||
} else {
|
|
||||||
debug!("Type mismatch in store. \
|
|
||||||
Expected {:?}, got {:?}; inserting bitcast",
|
|
||||||
dest_ptr_ty, stored_ptr_ty);
|
|
||||||
self.bitcast(ptr, stored_ptr_ty)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_call<'b>(&mut self,
|
|
||||||
typ: &str,
|
|
||||||
llfn: &'ll Value,
|
|
||||||
args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> {
|
|
||||||
let mut fn_ty = self.cx.val_ty(llfn);
|
|
||||||
// Strip off pointers
|
|
||||||
while self.cx.type_kind(fn_ty) == TypeKind::Pointer {
|
|
||||||
fn_ty = self.cx.element_type(fn_ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(self.cx.type_kind(fn_ty) == TypeKind::Function,
|
|
||||||
"builder::{} not passed a function, but {:?}", typ, fn_ty);
|
|
||||||
|
|
||||||
let param_tys = self.cx.func_params_types(fn_ty);
|
|
||||||
|
|
||||||
let all_args_match = param_tys.iter()
|
|
||||||
.zip(args.iter().map(|&v| self.val_ty(v)))
|
|
||||||
.all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
|
|
||||||
|
|
||||||
if all_args_match {
|
|
||||||
return Cow::Borrowed(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
let casted_args: Vec<_> = param_tys.into_iter()
|
|
||||||
.zip(args.iter())
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, (expected_ty, &actual_val))| {
|
|
||||||
let actual_ty = self.val_ty(actual_val);
|
|
||||||
if expected_ty != actual_ty {
|
|
||||||
debug!("Type mismatch in function call of {:?}. \
|
|
||||||
Expected {:?} for param {}, got {:?}; injecting bitcast",
|
|
||||||
llfn, expected_ty, i, actual_ty);
|
|
||||||
self.bitcast(actual_val, expected_ty)
|
|
||||||
} else {
|
|
||||||
actual_val
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Cow::Owned(casted_args)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lifetime_start(&mut self, ptr: &'ll Value, size: Size) {
|
fn lifetime_start(&mut self, ptr: &'ll Value, size: Size) {
|
||||||
self.call_lifetime_intrinsic("llvm.lifetime.start", ptr, size);
|
self.call_lifetime_intrinsic("llvm.lifetime.start", ptr, size);
|
||||||
}
|
}
|
||||||
@ -1509,6 +1300,215 @@ impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Builder<'a, 'll, 'tcx> {
|
impl Builder<'a, 'll, 'tcx> {
|
||||||
|
fn count_insn(&self, category: &str) {
|
||||||
|
if self.sess().codegen_stats() {
|
||||||
|
self.stats.borrow_mut().n_llvm_insns += 1;
|
||||||
|
}
|
||||||
|
if self.sess().count_llvm_insns() {
|
||||||
|
*self.stats
|
||||||
|
.borrow_mut()
|
||||||
|
.llvm_insns
|
||||||
|
.entry(category.to_string())
|
||||||
|
.or_insert(0) += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("minnum");
|
||||||
|
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("maxnum");
|
||||||
|
unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_element(
|
||||||
|
&mut self, vec: &'ll Value,
|
||||||
|
elt: &'ll Value,
|
||||||
|
idx: &'ll Value,
|
||||||
|
) -> &'ll Value {
|
||||||
|
self.count_insn("insertelement");
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, noname())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shuffle_vector(
|
||||||
|
&mut self,
|
||||||
|
v1: &'ll Value,
|
||||||
|
v2: &'ll Value,
|
||||||
|
mask: &'ll Value,
|
||||||
|
) -> &'ll Value {
|
||||||
|
self.count_insn("shufflevector");
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, noname())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.fadd_fast");
|
||||||
|
unsafe {
|
||||||
|
// FIXME: add a non-fast math version once
|
||||||
|
// https://bugs.llvm.org/show_bug.cgi?id=36732
|
||||||
|
// is fixed.
|
||||||
|
let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
|
||||||
|
llvm::LLVMRustSetHasUnsafeAlgebra(instr);
|
||||||
|
instr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.fmul_fast");
|
||||||
|
unsafe {
|
||||||
|
// FIXME: add a non-fast math version once
|
||||||
|
// https://bugs.llvm.org/show_bug.cgi?id=36732
|
||||||
|
// is fixed.
|
||||||
|
let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
|
||||||
|
llvm::LLVMRustSetHasUnsafeAlgebra(instr);
|
||||||
|
instr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.add");
|
||||||
|
unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.mul");
|
||||||
|
unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.and");
|
||||||
|
unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.or");
|
||||||
|
unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.xor");
|
||||||
|
unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.fmin");
|
||||||
|
unsafe { llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) }
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.fmax");
|
||||||
|
unsafe { llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) }
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_fmin_fast(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.fmin_fast");
|
||||||
|
unsafe {
|
||||||
|
let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true);
|
||||||
|
llvm::LLVMRustSetHasUnsafeAlgebra(instr);
|
||||||
|
instr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_fmax_fast(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.fmax_fast");
|
||||||
|
unsafe {
|
||||||
|
let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true);
|
||||||
|
llvm::LLVMRustSetHasUnsafeAlgebra(instr);
|
||||||
|
instr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.min");
|
||||||
|
unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
|
||||||
|
}
|
||||||
|
pub fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
|
||||||
|
self.count_insn("vector.reduce.max");
|
||||||
|
unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMAddClause(landing_pad, clause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value {
|
||||||
|
self.count_insn("catchret");
|
||||||
|
let ret = unsafe {
|
||||||
|
llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind)
|
||||||
|
};
|
||||||
|
ret.expect("LLVM does not have support for catchret")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_store<'b>(&mut self,
|
||||||
|
val: &'ll Value,
|
||||||
|
ptr: &'ll Value) -> &'ll Value {
|
||||||
|
let dest_ptr_ty = self.cx.val_ty(ptr);
|
||||||
|
let stored_ty = self.cx.val_ty(val);
|
||||||
|
let stored_ptr_ty = self.cx.type_ptr_to(stored_ty);
|
||||||
|
|
||||||
|
assert_eq!(self.cx.type_kind(dest_ptr_ty), TypeKind::Pointer);
|
||||||
|
|
||||||
|
if dest_ptr_ty == stored_ptr_ty {
|
||||||
|
ptr
|
||||||
|
} else {
|
||||||
|
debug!("Type mismatch in store. \
|
||||||
|
Expected {:?}, got {:?}; inserting bitcast",
|
||||||
|
dest_ptr_ty, stored_ptr_ty);
|
||||||
|
self.bitcast(ptr, stored_ptr_ty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_call<'b>(&mut self,
|
||||||
|
typ: &str,
|
||||||
|
llfn: &'ll Value,
|
||||||
|
args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> {
|
||||||
|
let mut fn_ty = self.cx.val_ty(llfn);
|
||||||
|
// Strip off pointers
|
||||||
|
while self.cx.type_kind(fn_ty) == TypeKind::Pointer {
|
||||||
|
fn_ty = self.cx.element_type(fn_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(self.cx.type_kind(fn_ty) == TypeKind::Function,
|
||||||
|
"builder::{} not passed a function, but {:?}", typ, fn_ty);
|
||||||
|
|
||||||
|
let param_tys = self.cx.func_params_types(fn_ty);
|
||||||
|
|
||||||
|
let all_args_match = param_tys.iter()
|
||||||
|
.zip(args.iter().map(|&v| self.val_ty(v)))
|
||||||
|
.all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
|
||||||
|
|
||||||
|
if all_args_match {
|
||||||
|
return Cow::Borrowed(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
let casted_args: Vec<_> = param_tys.into_iter()
|
||||||
|
.zip(args.iter())
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, (expected_ty, &actual_val))| {
|
||||||
|
let actual_ty = self.val_ty(actual_val);
|
||||||
|
if expected_ty != actual_ty {
|
||||||
|
debug!("Type mismatch in function call of {:?}. \
|
||||||
|
Expected {:?} for param {}, got {:?}; injecting bitcast",
|
||||||
|
llfn, expected_ty, i, actual_ty);
|
||||||
|
self.bitcast(actual_val, expected_ty)
|
||||||
|
} else {
|
||||||
|
actual_val
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Cow::Owned(casted_args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
|
||||||
|
self.count_insn("vaarg");
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
|
fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
|
||||||
if self.cx.sess().opts.optimize == config::OptLevel::No {
|
if self.cx.sess().opts.optimize == config::OptLevel::No {
|
||||||
return;
|
return;
|
||||||
|
@ -13,7 +13,6 @@ use rustc::ty::Ty;
|
|||||||
use rustc::ty::layout::{Align, Size};
|
use rustc::ty::layout::{Align, Size};
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use syntax::ast::AsmDialect;
|
use syntax::ast::AsmDialect;
|
||||||
|
|
||||||
@ -39,11 +38,9 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
|
|||||||
fn cx(&self) -> &Self::CodegenCx;
|
fn cx(&self) -> &Self::CodegenCx;
|
||||||
fn llfn(&self) -> Self::Value;
|
fn llfn(&self) -> Self::Value;
|
||||||
fn llbb(&self) -> Self::BasicBlock;
|
fn llbb(&self) -> Self::BasicBlock;
|
||||||
fn count_insn(&self, category: &str);
|
|
||||||
|
|
||||||
fn set_value_name(&mut self, value: Self::Value, name: &str);
|
fn set_value_name(&mut self, value: Self::Value, name: &str);
|
||||||
fn position_at_end(&mut self, llbb: Self::BasicBlock);
|
fn position_at_end(&mut self, llbb: Self::BasicBlock);
|
||||||
fn position_at_start(&mut self, llbb: Self::BasicBlock);
|
|
||||||
fn ret_void(&mut self);
|
fn ret_void(&mut self);
|
||||||
fn ret(&mut self, v: Self::Value);
|
fn ret(&mut self, v: Self::Value);
|
||||||
fn br(&mut self, dest: Self::BasicBlock);
|
fn br(&mut self, dest: Self::BasicBlock);
|
||||||
@ -161,7 +158,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
|
|||||||
fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||||
fn fcmp(&mut self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
fn fcmp(&mut self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||||
|
|
||||||
fn empty_phi(&mut self, ty: Self::Type) -> Self::Value;
|
|
||||||
fn phi(
|
fn phi(
|
||||||
&mut self,
|
&mut self,
|
||||||
ty: Self::Type,
|
ty: Self::Type,
|
||||||
@ -206,8 +202,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
|
|||||||
flags: MemFlags,
|
flags: MemFlags,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn minnum(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
|
||||||
fn maxnum(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
|
||||||
fn select(
|
fn select(
|
||||||
&mut self,
|
&mut self,
|
||||||
cond: Self::Value,
|
cond: Self::Value,
|
||||||
@ -215,34 +209,8 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
|
|||||||
else_val: Self::Value,
|
else_val: Self::Value,
|
||||||
) -> Self::Value;
|
) -> Self::Value;
|
||||||
|
|
||||||
fn va_arg(&mut self, list: Self::Value, ty: Self::Type) -> Self::Value;
|
|
||||||
fn extract_element(&mut self, vec: Self::Value, idx: Self::Value) -> Self::Value;
|
fn extract_element(&mut self, vec: Self::Value, idx: Self::Value) -> Self::Value;
|
||||||
fn insert_element(
|
|
||||||
&mut self,
|
|
||||||
vec: Self::Value,
|
|
||||||
elt: Self::Value,
|
|
||||||
idx: Self::Value,
|
|
||||||
) -> Self::Value;
|
|
||||||
fn shuffle_vector(
|
|
||||||
&mut self,
|
|
||||||
v1: Self::Value,
|
|
||||||
v2: Self::Value,
|
|
||||||
mask: Self::Value,
|
|
||||||
) -> Self::Value;
|
|
||||||
fn vector_splat(&mut self, num_elts: usize, elt: Self::Value) -> Self::Value;
|
fn vector_splat(&mut self, num_elts: usize, elt: Self::Value) -> Self::Value;
|
||||||
fn vector_reduce_fadd_fast(&mut self, acc: Self::Value, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_fmul_fast(&mut self, acc: Self::Value, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_add(&mut self, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_mul(&mut self, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_and(&mut self, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_or(&mut self, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_xor(&mut self, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_fmin(&mut self, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_fmax(&mut self, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_fmin_fast(&mut self, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_fmax_fast(&mut self, src: Self::Value) -> Self::Value;
|
|
||||||
fn vector_reduce_min(&mut self, src: Self::Value, is_signed: bool) -> Self::Value;
|
|
||||||
fn vector_reduce_max(&mut self, src: Self::Value, is_signed: bool) -> Self::Value;
|
|
||||||
fn extract_value(&mut self, agg_val: Self::Value, idx: u64) -> Self::Value;
|
fn extract_value(&mut self, agg_val: Self::Value, idx: u64) -> Self::Value;
|
||||||
fn insert_value(&mut self, agg_val: Self::Value, elt: Self::Value, idx: u64) -> Self::Value;
|
fn insert_value(&mut self, agg_val: Self::Value, elt: Self::Value, idx: u64) -> Self::Value;
|
||||||
|
|
||||||
@ -252,7 +220,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
|
|||||||
pers_fn: Self::Value,
|
pers_fn: Self::Value,
|
||||||
num_clauses: usize,
|
num_clauses: usize,
|
||||||
) -> Self::Value;
|
) -> Self::Value;
|
||||||
fn add_clause(&mut self, landing_pad: Self::Value, clause: Self::Value);
|
|
||||||
fn set_cleanup(&mut self, landing_pad: Self::Value);
|
fn set_cleanup(&mut self, landing_pad: Self::Value);
|
||||||
fn resume(&mut self, exn: Self::Value) -> Self::Value;
|
fn resume(&mut self, exn: Self::Value) -> Self::Value;
|
||||||
fn cleanup_pad(&mut self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet;
|
fn cleanup_pad(&mut self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet;
|
||||||
@ -262,7 +229,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
|
|||||||
unwind: Option<Self::BasicBlock>,
|
unwind: Option<Self::BasicBlock>,
|
||||||
) -> Self::Value;
|
) -> Self::Value;
|
||||||
fn catch_pad(&mut self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet;
|
fn catch_pad(&mut self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet;
|
||||||
fn catch_ret(&mut self, funclet: &Self::Funclet, unwind: Self::BasicBlock) -> Self::Value;
|
|
||||||
fn catch_switch(
|
fn catch_switch(
|
||||||
&mut self,
|
&mut self,
|
||||||
parent: Option<Self::Value>,
|
parent: Option<Self::Value>,
|
||||||
@ -293,19 +259,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
|
|||||||
fn add_incoming_to_phi(&mut self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock);
|
fn add_incoming_to_phi(&mut self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock);
|
||||||
fn set_invariant_load(&mut self, load: Self::Value);
|
fn set_invariant_load(&mut self, load: Self::Value);
|
||||||
|
|
||||||
/// Returns the ptr value that should be used for storing `val`.
|
|
||||||
fn check_store(&mut self, val: Self::Value, ptr: Self::Value) -> Self::Value;
|
|
||||||
|
|
||||||
/// Returns the args that should be used for a call to `llfn`.
|
|
||||||
fn check_call<'b>(
|
|
||||||
&mut self,
|
|
||||||
typ: &str,
|
|
||||||
llfn: Self::Value,
|
|
||||||
args: &'b [Self::Value],
|
|
||||||
) -> Cow<'b, [Self::Value]>
|
|
||||||
where
|
|
||||||
[Self::Value]: ToOwned;
|
|
||||||
|
|
||||||
/// Called for `StorageLive`
|
/// Called for `StorageLive`
|
||||||
fn lifetime_start(&mut self, ptr: Self::Value, size: Size);
|
fn lifetime_start(&mut self, ptr: Self::Value, size: Size);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user