Skip to content

Commit

Permalink
Add a method for emiting a switch.
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Mar 1, 2019
1 parent d7a528c commit 018747b
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 14 deletions.
15 changes: 9 additions & 6 deletions src/librustc_codegen_llvm/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ fn noname() -> *const c_char {

impl BackendTypes for Builder<'_, 'll, 'tcx> {
type Value = <CodegenCx<'ll, 'tcx> as BackendTypes>::Value;
type Switch = <CodegenCx<'ll, 'tcx> as BackendTypes>::Switch;
type BasicBlock = <CodegenCx<'ll, 'tcx> as BackendTypes>::BasicBlock;
type Type = <CodegenCx<'ll, 'tcx> as BackendTypes>::Type;
type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;
Expand Down Expand Up @@ -165,7 +166,7 @@ impl ControlFlowBuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}

fn switch(
fn switch_new(
&mut self,
v: &'ll Value,
else_llbb: &'ll BasicBlock,
Expand All @@ -176,12 +177,14 @@ impl ControlFlowBuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}

fn add_case(&mut self, s: &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock) {
fn switch_add_case(&mut self, s: &mut &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock) {
unsafe {
llvm::LLVMAddCase(s, on_val, dest)
llvm::LLVMAddCase(*s, on_val, dest)
}
}

fn switch_emit(&mut self, _: &'ll Value) {}

fn unreachable(&mut self) {
self.count_insn("unreachable");
unsafe {
Expand Down Expand Up @@ -506,15 +509,15 @@ impl MemoryBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
}

fn write_operand_repeatedly(
mut self,
&mut self,
cg_elem: OperandRef<'tcx, &'ll Value>,
count: u64,
dest: PlaceRef<'tcx, &'ll Value>,
) -> Self {
let zero = self.const_usize(0);
let count = self.const_usize(count);
let start = dest.project_index(&mut self, zero).llval;
let end = dest.project_index(&mut self, count).llval;
let start = dest.project_index(self, zero).llval;
let end = dest.project_index(self, count).llval;

let mut header_bx = self.build_sibling_block("repeat_loop_header");
let mut body_bx = self.build_sibling_block("repeat_loop_body");
Expand Down
1 change: 1 addition & 0 deletions src/librustc_codegen_llvm/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ impl Funclet<'ll> {

impl BackendTypes for CodegenCx<'ll, 'tcx> {
type Value = &'ll Value;
type Switch = &'ll Value;
type BasicBlock = &'ll BasicBlock;
type Type = &'ll Type;
type Funclet = Funclet<'ll>;
Expand Down
11 changes: 7 additions & 4 deletions src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,20 @@ 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 mut switch = bx.switch_new(
discr.immediate(),
helper.llblock(self, *otherwise),
values.len(),
);
let switch_llty = bx.immediate_backend_type(
bx.layout_of(switch_ty)
);
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)
bx.switch_add_case(&mut switch, llval, llbb)
}
bx.switch_emit(switch);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc_codegen_ssa/traits/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use syntax_pos::symbol::InternedString;

pub trait BackendTypes {
type Value: CodegenObject;
type Switch;
type BasicBlock: Copy;
type Type: CodegenObject;
type Funclet;
Expand Down
15 changes: 11 additions & 4 deletions src/librustc_codegen_ssa/traits/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,20 @@ pub trait ControlFlowBuilderMethods<'a, 'tcx: 'a>: HasCodegen<'tcx> {
then_llbb: Self::BasicBlock,
else_llbb: Self::BasicBlock,
);
fn switch(
fn switch_new(
&mut self,
v: Self::Value,
else_llbb: Self::BasicBlock,
num_cases: usize,
) -> Self::Value;
fn add_case(&mut self, s: Self::Value, on_val: Self::Value, dest: Self::BasicBlock);
) -> Self::Switch;
fn switch_add_case(
&mut self,
s: &mut Self::Switch,
on_val: Self::Value,
dest: Self::BasicBlock,
);
fn switch_emit(&mut self, s: Self::Switch);

fn unreachable(&mut self);
}

Expand Down Expand Up @@ -116,7 +123,7 @@ pub trait MemoryBuilderMethods<'tcx>: HasCodegen<'tcx> {

/// Called for Rvalue::Repeat when the elem is neither a ZST nor optimizable using memset.
fn write_operand_repeatedly(
self,
&mut self,
elem: OperandRef<'tcx, Self::Value>,
count: u64,
dest: PlaceRef<'tcx, Self::Value>,
Expand Down

0 comments on commit 018747b

Please sign in to comment.