Generate an InstBuilder trait.
All of the instruction format an opcode methods are emitted as an InstBuilder trait instead of adding them to the Bulder struct directly. The methods only make use of the InstBuilderBase methods to create new instructions. This makes it possible to reuse the InstBuilder trait for different ways of inserting instructions.
This commit is contained in:
@@ -9,6 +9,42 @@ use ir::{Opcode, Type, Inst, Value, Ebb, JumpTable, VariableArgs, SigRef, FuncRe
|
||||
use ir::immediates::{Imm64, Uimm8, Ieee32, Ieee64, ImmVector};
|
||||
use ir::condcodes::{IntCC, FloatCC};
|
||||
|
||||
/// Base trait for instruction builders.
|
||||
///
|
||||
/// The `InstBuilderBase` trait provides the basic functionality required by the methods of the
|
||||
/// generated `InstBuilder` trait. These methods should not normally be used directly. Use the
|
||||
/// methods in the `InstBuilder trait instead.
|
||||
///
|
||||
/// Any data type that implements `InstBuilderBase` also gets all the methods of the `InstBuilder`
|
||||
/// trait.
|
||||
pub trait InstBuilderBase {
|
||||
/// Get an immutable reference to the data flow graph that will hold the constructed
|
||||
/// instructions.
|
||||
fn data_flow_graph(&self) -> &DataFlowGraph;
|
||||
|
||||
/// Insert a simple instruction and return a reference to it.
|
||||
///
|
||||
/// A 'simple' instruction has at most one result, and the `data.ty` field must contain the
|
||||
/// result type or `VOID` for an instruction with no result values.
|
||||
fn simple_instruction(&mut self, data: InstructionData) -> Inst;
|
||||
|
||||
/// Insert a simple instruction and return a reference to it.
|
||||
///
|
||||
/// A 'complex' instruction may produce multiple results, and the result types may depend on a
|
||||
/// controlling type variable. For non-polymorphic instructions with multiple results, pass
|
||||
/// `VOID` for the `ctrl_typevar` argument.
|
||||
fn complex_instruction(&mut self, data: InstructionData, ctrl_typevar: Type) -> Inst;
|
||||
}
|
||||
|
||||
// Include trait code generated by `meta/gen_instr.py`.
|
||||
//
|
||||
// This file defines the `InstBuilder` trait as an extension of `InstBuilderBase` with methods per
|
||||
// instruction format and per opcode.
|
||||
include!(concat!(env!("OUT_DIR"), "/builder.rs"));
|
||||
|
||||
/// Any type implementing `InstBuilderBase` gets all the `InstBuilder` methods for free.
|
||||
impl<T: InstBuilderBase> InstBuilder for T {}
|
||||
|
||||
/// Instruction builder.
|
||||
///
|
||||
/// A `Builder` holds mutable references to a data flow graph and a layout cursor. It provides
|
||||
@@ -40,16 +76,23 @@ impl<'a> Builder<'a> {
|
||||
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 {
|
||||
impl<'a> InstBuilderBase for Builder<'a> {
|
||||
fn data_flow_graph(&self) -> &DataFlowGraph {
|
||||
self.dfg
|
||||
}
|
||||
|
||||
fn simple_instruction(&mut self, data: InstructionData) -> Inst {
|
||||
let inst = self.dfg.make_inst(data);
|
||||
self.pos.insert_inst(inst);
|
||||
inst
|
||||
}
|
||||
}
|
||||
|
||||
// Include code generated by `meta/gen_instr.py`. This file includes `Builder` methods per
|
||||
// instruction format and per opcode for inserting instructions.
|
||||
include!(concat!(env!("OUT_DIR"), "/builder.rs"));
|
||||
fn complex_instruction(&mut self, data: InstructionData, ctrl_typevar: Type) -> Inst {
|
||||
let inst = self.dfg.make_inst(data);
|
||||
self.dfg.make_inst_results(inst, ctrl_typevar);
|
||||
self.pos.insert_inst(inst);
|
||||
inst
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ pub use ir::jumptable::JumpTableData;
|
||||
pub use ir::dfg::{DataFlowGraph, ValueDef};
|
||||
pub use ir::layout::{Layout, Cursor};
|
||||
pub use ir::function::Function;
|
||||
pub use ir::builder::Builder;
|
||||
pub use ir::builder::{Builder, InstBuilder};
|
||||
|
||||
Reference in New Issue
Block a user