Give Builder a Cursor.
The Builder keeps track of a position in the layout and inserts new instructions there. Add insert_ebb() and ebb() methods to Builder. Use Builder in the cfg tests.
This commit is contained in:
@@ -139,9 +139,7 @@ impl ControlFlowGraph {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ir::Function;
|
||||
|
||||
use test_utils::make_inst;
|
||||
use ir::{Function, Builder, Cursor, VariableArgs, types};
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
@@ -176,23 +174,29 @@ mod tests {
|
||||
fn branches_and_jumps() {
|
||||
let mut func = Function::new();
|
||||
let ebb0 = func.dfg.make_ebb();
|
||||
let cond = func.dfg.append_ebb_arg(ebb0, types::I32);
|
||||
let ebb1 = func.dfg.make_ebb();
|
||||
let ebb2 = func.dfg.make_ebb();
|
||||
func.layout.append_ebb(ebb0);
|
||||
func.layout.append_ebb(ebb1);
|
||||
func.layout.append_ebb(ebb2);
|
||||
|
||||
let br_ebb0_ebb2 = make_inst::branch(&mut func, ebb2);
|
||||
func.layout.append_inst(br_ebb0_ebb2, ebb0);
|
||||
let br_ebb0_ebb2;
|
||||
let br_ebb1_ebb1;
|
||||
let jmp_ebb0_ebb1;
|
||||
let jmp_ebb1_ebb2;
|
||||
|
||||
let jmp_ebb0_ebb1 = make_inst::jump(&mut func, ebb1);
|
||||
func.layout.append_inst(jmp_ebb0_ebb1, ebb0);
|
||||
{
|
||||
let mut cursor = Cursor::new(&mut func.layout);
|
||||
let mut b = Builder::new(&mut func.dfg, &mut cursor);
|
||||
|
||||
let br_ebb1_ebb1 = make_inst::branch(&mut func, ebb1);
|
||||
func.layout.append_inst(br_ebb1_ebb1, ebb1);
|
||||
b.insert_ebb(ebb0);
|
||||
br_ebb0_ebb2 = b.brnz(cond, ebb2, VariableArgs::new());
|
||||
jmp_ebb0_ebb1 = b.jump(ebb1, VariableArgs::new());
|
||||
|
||||
let jmp_ebb1_ebb2 = make_inst::jump(&mut func, ebb2);
|
||||
func.layout.append_inst(jmp_ebb1_ebb2, ebb1);
|
||||
b.insert_ebb(ebb1);
|
||||
br_ebb1_ebb1 = b.brnz(cond, ebb1, VariableArgs::new());
|
||||
jmp_ebb1_ebb2 = b.jump(ebb2, VariableArgs::new());
|
||||
|
||||
b.insert_ebb(ebb2);
|
||||
}
|
||||
|
||||
let cfg = ControlFlowGraph::new(&func);
|
||||
|
||||
|
||||
@@ -4,20 +4,48 @@
|
||||
//! function. Many of its methods are generated from the meta language instruction definitions.
|
||||
|
||||
use ir::{types, instructions};
|
||||
use ir::{InstructionData, DataFlowGraph};
|
||||
use ir::{InstructionData, DataFlowGraph, Cursor};
|
||||
use ir::{Opcode, Type, Inst, Value, Ebb, JumpTable, VariableArgs, FuncRef};
|
||||
use ir::immediates::{Imm64, Uimm8, Ieee32, Ieee64, ImmVector};
|
||||
use ir::condcodes::{IntCC, FloatCC};
|
||||
|
||||
/// Instruction builder.
|
||||
///
|
||||
/// A `Builder` holds mutable references to a data flow graph and a layout cursor. It provides
|
||||
/// convenience method for creating and inserting instructions at the current cursor position.
|
||||
pub struct Builder<'a> {
|
||||
dfg: &'a mut DataFlowGraph,
|
||||
pub dfg: &'a mut DataFlowGraph,
|
||||
pub pos: &'a mut Cursor<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Builder<'a> {
|
||||
/// Create a new builder which inserts instructions at `pos`.
|
||||
/// The `dfg` and `pos.layout` references should be from the same `Function`.
|
||||
pub fn new(dfg: &'a mut DataFlowGraph, pos: &'a mut Cursor<'a>) -> Builder<'a> {
|
||||
Builder {
|
||||
dfg: dfg,
|
||||
pos: pos,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create and insert an EBB. Further instructions will be inserted into the new EBB.
|
||||
pub fn ebb(&mut self) -> Ebb {
|
||||
let ebb = self.dfg.make_ebb();
|
||||
self.insert_ebb(ebb);
|
||||
ebb
|
||||
}
|
||||
|
||||
/// Insert an existing EBB at the current position. Further instructions will be inserted into
|
||||
/// the new EBB.
|
||||
pub fn insert_ebb(&mut self, ebb: Ebb) {
|
||||
self.pos.insert_ebb(ebb);
|
||||
}
|
||||
|
||||
// Create and insert an instruction.
|
||||
// This method is used by the generated format-specific methods.
|
||||
fn insert_inst(&mut self, data: InstructionData) -> Inst {
|
||||
let inst = self.dfg.make_inst(data);
|
||||
self.pos.insert_inst(inst);
|
||||
inst
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user