Add signatures and ext_funcs tables to DataFlowGraph.
These two tables are used to keep track of type signatures of function calls as well as external function references used in direct function calls. Also add an ExtFuncData struct representing an external function that can be called directly.
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
//! Data flow graph tracking Instructions, Values, and EBBs.
|
//! Data flow graph tracking Instructions, Values, and EBBs.
|
||||||
|
|
||||||
use ir::{Ebb, Inst, Value, Type};
|
use ir::{Ebb, Inst, Value, Type, SigRef, Signature, FuncRef};
|
||||||
use ir::entities::{NO_VALUE, ExpandedValue};
|
use ir::entities::{NO_VALUE, ExpandedValue};
|
||||||
use ir::instructions::InstructionData;
|
use ir::instructions::InstructionData;
|
||||||
|
use ir::extfunc::ExtFuncData;
|
||||||
use entity_map::{EntityMap, PrimaryEntityData};
|
use entity_map::{EntityMap, PrimaryEntityData};
|
||||||
|
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
@@ -33,10 +34,19 @@ pub struct DataFlowGraph {
|
|||||||
/// This is implemented directly with a `Vec` rather than an `EntityMap<Value, ...>` because
|
/// This is implemented directly with a `Vec` rather than an `EntityMap<Value, ...>` because
|
||||||
/// the Value entity references can refer to two things -- an instruction or an extended value.
|
/// the Value entity references can refer to two things -- an instruction or an extended value.
|
||||||
extended_values: Vec<ValueData>,
|
extended_values: Vec<ValueData>,
|
||||||
|
|
||||||
|
/// Function signature table. These signatures are referenced by indirect call instructions as
|
||||||
|
/// well as the external function references.
|
||||||
|
pub signatures: EntityMap<SigRef, Signature>,
|
||||||
|
|
||||||
|
/// External function references. These are functions that can be called directly.
|
||||||
|
pub ext_funcs: EntityMap<FuncRef, ExtFuncData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrimaryEntityData for InstructionData {}
|
impl PrimaryEntityData for InstructionData {}
|
||||||
impl PrimaryEntityData for EbbData {}
|
impl PrimaryEntityData for EbbData {}
|
||||||
|
impl PrimaryEntityData for Signature {}
|
||||||
|
impl PrimaryEntityData for ExtFuncData {}
|
||||||
|
|
||||||
impl DataFlowGraph {
|
impl DataFlowGraph {
|
||||||
/// Create a new empty `DataFlowGraph`.
|
/// Create a new empty `DataFlowGraph`.
|
||||||
@@ -45,6 +55,8 @@ impl DataFlowGraph {
|
|||||||
insts: EntityMap::new(),
|
insts: EntityMap::new(),
|
||||||
ebbs: EntityMap::new(),
|
ebbs: EntityMap::new(),
|
||||||
extended_values: Vec::new(),
|
extended_values: Vec::new(),
|
||||||
|
signatures: EntityMap::new(),
|
||||||
|
ext_funcs: EntityMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
//! This module declares the data types used to represent external functions and call signatures.
|
//! This module declares the data types used to represent external functions and call signatures.
|
||||||
|
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
use ir::Type;
|
use ir::{Type, FunctionName, SigRef};
|
||||||
|
|
||||||
/// Function signature.
|
/// Function signature.
|
||||||
///
|
///
|
||||||
@@ -104,6 +104,21 @@ pub enum ArgumentExtension {
|
|||||||
Sext,
|
Sext,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An external function.
|
||||||
|
///
|
||||||
|
/// Information about a function that can be called directly with a direct `call` instruction.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ExtFuncData {
|
||||||
|
pub name: FunctionName,
|
||||||
|
pub signature: SigRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ExtFuncData {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{} {}", self.signature, self.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ mod extfunc;
|
|||||||
mod builder;
|
mod builder;
|
||||||
|
|
||||||
pub use ir::funcname::FunctionName;
|
pub use ir::funcname::FunctionName;
|
||||||
pub use ir::extfunc::{Signature, ArgumentType, ArgumentExtension};
|
pub use ir::extfunc::{Signature, ArgumentType, ArgumentExtension, ExtFuncData};
|
||||||
pub use ir::types::Type;
|
pub use ir::types::Type;
|
||||||
pub use ir::entities::{Ebb, Inst, Value, StackSlot, JumpTable, FuncRef, SigRef};
|
pub use ir::entities::{Ebb, Inst, Value, StackSlot, JumpTable, FuncRef, SigRef};
|
||||||
pub use ir::instructions::{Opcode, InstructionData, VariableArgs};
|
pub use ir::instructions::{Opcode, InstructionData, VariableArgs};
|
||||||
|
|||||||
@@ -43,6 +43,17 @@ fn write_preamble(w: &mut Write, func: &Function) -> result::Result<bool, Error>
|
|||||||
try!(writeln!(w, " {} = {}", ss, func.stack_slots[ss]));
|
try!(writeln!(w, " {} = {}", ss, func.stack_slots[ss]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write out all signatures before functions since function decls can refer to signatures.
|
||||||
|
for sig in func.dfg.signatures.keys() {
|
||||||
|
any = true;
|
||||||
|
try!(writeln!(w, " {} = signature{}", sig, func.dfg.signatures[sig]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for fnref in func.dfg.ext_funcs.keys() {
|
||||||
|
any = true;
|
||||||
|
try!(writeln!(w, " {} = {}", fnref, func.dfg.ext_funcs[fnref]));
|
||||||
|
}
|
||||||
|
|
||||||
for jt in func.jump_tables.keys() {
|
for jt in func.jump_tables.keys() {
|
||||||
any = true;
|
any = true;
|
||||||
try!(writeln!(w, " {} = {}", jt, func.jump_tables[jt]));
|
try!(writeln!(w, " {} = {}", jt, func.jump_tables[jt]));
|
||||||
|
|||||||
Reference in New Issue
Block a user