Use a macro to factor out some repetitive code.

Similar to the existing macro just above.
This commit is contained in:
Nicholas Nethercote 2024-09-17 16:52:25 +10:00
parent 0d78f1e86b
commit 4ce010efcf

View file

@ -120,7 +120,7 @@ impl<'ll, 'tcx> Deref for Builder<'_, 'll, 'tcx> {
} }
} }
macro_rules! builder_methods_for_value_instructions { macro_rules! math_builder_methods {
($($name:ident($($arg:ident),*) => $llvm_capi:ident),+ $(,)?) => { ($($name:ident($($arg:ident),*) => $llvm_capi:ident),+ $(,)?) => {
$(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value { $(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
unsafe { unsafe {
@ -130,6 +130,18 @@ macro_rules! builder_methods_for_value_instructions {
} }
} }
macro_rules! set_math_builder_methods {
($($name:ident($($arg:ident),*) => ($llvm_capi:ident, $llvm_set_math:ident)),+ $(,)?) => {
$(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
unsafe {
let instr = llvm::$llvm_capi(self.llbuilder, $($arg,)* UNNAMED);
llvm::$llvm_set_math(instr);
instr
}
})+
}
}
impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
type CodegenCx = CodegenCx<'ll, 'tcx>; type CodegenCx = CodegenCx<'ll, 'tcx>;
@ -267,7 +279,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
} }
} }
builder_methods_for_value_instructions! { math_builder_methods! {
add(a, b) => LLVMBuildAdd, add(a, b) => LLVMBuildAdd,
fadd(a, b) => LLVMBuildFAdd, fadd(a, b) => LLVMBuildFAdd,
sub(a, b) => LLVMBuildSub, sub(a, b) => LLVMBuildSub,
@ -299,84 +311,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
unchecked_umul(x, y) => LLVMBuildNUWMul, unchecked_umul(x, y) => LLVMBuildNUWMul,
} }
fn fadd_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { set_math_builder_methods! {
unsafe { fadd_fast(x, y) => (LLVMBuildFAdd, LLVMRustSetFastMath),
let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED); fsub_fast(x, y) => (LLVMBuildFSub, LLVMRustSetFastMath),
llvm::LLVMRustSetFastMath(instr); fmul_fast(x, y) => (LLVMBuildFMul, LLVMRustSetFastMath),
instr fdiv_fast(x, y) => (LLVMBuildFDiv, LLVMRustSetFastMath),
} frem_fast(x, y) => (LLVMBuildFRem, LLVMRustSetFastMath),
} fadd_algebraic(x, y) => (LLVMBuildFAdd, LLVMRustSetAlgebraicMath),
fsub_algebraic(x, y) => (LLVMBuildFSub, LLVMRustSetAlgebraicMath),
fn fsub_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { fmul_algebraic(x, y) => (LLVMBuildFMul, LLVMRustSetAlgebraicMath),
unsafe { fdiv_algebraic(x, y) => (LLVMBuildFDiv, LLVMRustSetAlgebraicMath),
let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED); frem_algebraic(x, y) => (LLVMBuildFRem, LLVMRustSetAlgebraicMath),
llvm::LLVMRustSetFastMath(instr);
instr
}
}
fn fmul_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetFastMath(instr);
instr
}
}
fn fdiv_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetFastMath(instr);
instr
}
}
fn frem_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetFastMath(instr);
instr
}
}
fn fadd_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
}
fn fsub_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
}
fn fmul_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
}
fn fdiv_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
}
fn frem_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
} }
fn checked_binop( fn checked_binop(
@ -459,6 +404,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
val val
} }
} }
fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value { fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value {
if scalar.is_bool() { if scalar.is_bool() {
return self.trunc(val, self.cx().type_i1()); return self.trunc(val, self.cx().type_i1());
@ -1160,6 +1106,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
(val, success) (val, success)
} }
} }
fn atomic_rmw( fn atomic_rmw(
&mut self, &mut self,
op: rustc_codegen_ssa::common::AtomicRmwBinOp, op: rustc_codegen_ssa::common::AtomicRmwBinOp,