Add a method for emiting a switch.

This commit is contained in:
bjorn3 2018-12-08 18:42:31 +01:00
parent b2e61946fa
commit 56842b2154
3 changed files with 19 additions and 20 deletions

View File

@ -170,9 +170,16 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
v: &'ll Value,
else_llbb: &'ll BasicBlock,
num_cases: usize,
) -> &'ll Value {
unsafe {
cases: impl Iterator<Item = (u128, &'ll BasicBlock)>,
) {
let switch = unsafe {
llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint)
};
for (on_val, dest) in cases {
let on_val = self.const_uint_big(self.val_ty(v), on_val);
unsafe {
llvm::LLVMAddCase(switch, on_val, dest)
}
}
}
@ -1158,12 +1165,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}
fn add_case(&mut self, s: &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock) {
unsafe {
llvm::LLVMAddCase(s, on_val, dest)
}
}
fn set_invariant_load(&mut self, load: &'ll Value) {
unsafe {
llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint,

View File

@ -214,17 +214,14 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
} else {
let (otherwise, targets) = targets.split_last().unwrap();
let switch = bx.switch(discr.immediate(),
helper.llblock(self, *otherwise),
values.len());
let switch_llty = bx.immediate_backend_type(
bx.layout_of(switch_ty)
bx.switch(
discr.immediate(),
helper.llblock(self, *otherwise),
values.len(),
values.iter().zip(targets).map(|(&value, target)| {
(value, helper.llblock(self, *target))
})
);
for (&value, target) in values.iter().zip(targets) {
let llval = bx.const_uint_big(switch_llty, value);
let llbb = helper.llblock(self, *target);
bx.add_case(switch, llval, llbb)
}
}
}

View File

@ -50,7 +50,8 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
v: Self::Value,
else_llbb: Self::BasicBlock,
num_cases: usize,
) -> Self::Value;
cases: impl Iterator<Item = (u128, Self::BasicBlock)>,
);
fn invoke(
&mut self,
llfn: Self::Value,
@ -60,6 +61,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
funclet: Option<&Self::Funclet>,
) -> Self::Value;
fn unreachable(&mut self);
fn add(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
fn fadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
fn fadd_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
@ -242,7 +244,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
order: AtomicOrdering,
) -> Self::Value;
fn atomic_fence(&mut self, order: AtomicOrdering, scope: SynchronizationScope);
fn add_case(&mut self, s: Self::Value, on_val: Self::Value, dest: Self::BasicBlock);
fn set_invariant_load(&mut self, load: Self::Value);
/// Called for `StorageLive`