Struct binaryen::Relooper [−][src]
pub struct Relooper { /* fields omitted */ }
Relooper transforms arbitrary control-flow graph into a structured control-flow that used by Binaryen IR.
It takes control-flow graph in form of the blocks of code,
created by add_block
or add_block_with_switch
and connected
with add_branch
and add_branch_for_switch
respectively.
After blocks created and connected render
is used to create
structured control-flow in form of Expr
s.
Examples
let module = Module::new(); let mut relooper = module.relooper(); // Create two blocks that do nothing. let b1 = relooper.add_block(module.nop()); let b2 = relooper.add_block(module.nop()); // Add unconditional branch from `b1` to `b2`. relooper.add_branch(b1, b2, None, None); // Render final expression let result: Expr = relooper.render(b1, 0); result.print();
If you want conditional branch, you can use.
let entry = relooper.add_block(module.nop()); let if_true = relooper.add_block(module.nop()); let if_false = relooper.add_block(module.nop()); let always_true_condition: Expr = module.const_(Literal::I32(1)); relooper.add_branch(entry, if_true, Some(always_true_condition), None); relooper.add_branch(entry, if_false, None, None); let result: Expr = relooper.render(entry, 0); result.print();
Methods
impl Relooper
[src]
impl Relooper
pub fn add_block(&mut self, code: Expr) -> PlainBlock
[src]
pub fn add_block(&mut self, code: Expr) -> PlainBlock
Add a plain block that executes code
and ends with nothing or with simple branching.
Plain blocks can have multiple conditional branches to the other blocks and at most one unconditional.
Be careful with branching in code
, branches to the outside won't work.
pub fn add_block_with_switch(
&mut self,
code: Expr,
condition: Expr
) -> SwitchBlock
[src]
pub fn add_block_with_switch(
&mut self,
code: Expr,
condition: Expr
) -> SwitchBlock
Add a block that executes code
and ends with a switch on the condition
.
Be careful with branching in code
, branches to the outside won't work.
pub fn add_branch<B: Block>(
&self,
from: PlainBlock,
to: B,
condition: Option<Expr>,
code: Option<Expr>
)
[src]
pub fn add_branch<B: Block>(
&self,
from: PlainBlock,
to: B,
condition: Option<Expr>,
code: Option<Expr>
)
Add a branch from PlainBlock
to any other block.
You can provide optional condition
that will be used to decide if the branch should be taken.
The branch can have code
on it, that is executed as the branch happens.
This is useful for phis if you use SSA.
pub fn add_branch_for_switch<B: Block>(
&self,
from: SwitchBlock,
to: B,
indices: &[u32],
code: Option<Expr>
)
[src]
pub fn add_branch_for_switch<B: Block>(
&self,
from: SwitchBlock,
to: B,
indices: &[u32],
code: Option<Expr>
)
Add a switch-style branch to any other block.
The block's switch table will have these indices going to that target
pub fn render<B: Block>(self, entry: B, label_helper: u32) -> Expr
[src]
pub fn render<B: Block>(self, entry: B, label_helper: u32) -> Expr
Render an structured control-flow graph from provided blocks and branches.
Arguments
- entry - Entrypoint of this control-flow graph.
- label_helper - Index of i32 local variable that is free to use. This may be needed to render irreducible control-flow graph.