Implement block/statement interference graph algorithm.
This commit is contained in:
parent
c91bb35d8d
commit
272d288213
@ -5,7 +5,6 @@ use crate::ir::ir_expression::IrExpression;
|
||||
use crate::ir::ir_operation::IrOperation;
|
||||
use crate::ir::ir_statement::IrStatement;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use crate::symbol::ExpressibleSymbol;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use crate::type_info::TypeInfo;
|
||||
|
||||
@ -40,7 +39,7 @@ pub fn expression_to_ir_expression(
|
||||
}
|
||||
Expression::Identifier(identifier) => {
|
||||
let expressible_symbol = identifier.expressible_symbol();
|
||||
Some(IrExpression::Variable(expressible_symbol.ir_variable()))
|
||||
Some(expressible_symbol.ir_expression())
|
||||
}
|
||||
Expression::Additive(additive_expression) => {
|
||||
let ir_add = additive_expression.to_ir(builder, symbol_table);
|
||||
|
||||
@ -7,6 +7,7 @@ use crate::ast::type_use::TypeUse;
|
||||
use crate::constants_table::ConstantsTable;
|
||||
use crate::diagnostic::Diagnostic;
|
||||
use crate::ir::ir_function::IrFunction;
|
||||
use crate::ir::ir_parameter::IrParameter;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::symbol::FunctionSymbol;
|
||||
@ -167,13 +168,13 @@ impl Function {
|
||||
// parameters
|
||||
for parameter in &self.parameters {
|
||||
let parameter_symbol = parameter.parameter_symbol();
|
||||
let ir_variable = IrVariable::new(
|
||||
let ir_parameter = IrParameter::new(
|
||||
parameter_symbol.borrow().name(),
|
||||
parameter_symbol.borrow().type_info().clone(),
|
||||
);
|
||||
let as_rc = Rc::new(RefCell::new(ir_variable));
|
||||
let as_rc = Rc::new(ir_parameter);
|
||||
builder.parameters_mut().push(as_rc.clone());
|
||||
parameter_symbol.borrow_mut().set_ir_variable(as_rc);
|
||||
parameter_symbol.borrow_mut().set_ir_parameter(as_rc);
|
||||
}
|
||||
|
||||
let entry_block_id = builder.new_block();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::ir::ir_block::IrBlock;
|
||||
use crate::ir::ir_parameter::IrParameter;
|
||||
use crate::ir::ir_statement::IrStatement;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use std::cell::RefCell;
|
||||
@ -6,7 +7,7 @@ use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct IrBuilder {
|
||||
parameters: Vec<Rc<RefCell<IrVariable>>>,
|
||||
parameters: Vec<Rc<IrParameter>>,
|
||||
block_counter: usize,
|
||||
t_var_counter: usize,
|
||||
blocks: HashMap<usize, Rc<RefCell<IrBlock>>>,
|
||||
@ -24,11 +25,11 @@ impl IrBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> &[Rc<RefCell<IrVariable>>] {
|
||||
pub fn parameters(&self) -> &[Rc<IrParameter>] {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> &mut Vec<Rc<RefCell<IrVariable>>> {
|
||||
pub fn parameters_mut(&mut self) -> &mut Vec<Rc<IrParameter>> {
|
||||
&mut self.parameters
|
||||
}
|
||||
|
||||
@ -86,6 +87,6 @@ impl IrBlockBuilder {
|
||||
}
|
||||
|
||||
pub fn build(self) -> IrBlock {
|
||||
IrBlock::new(self.id, &format!("b{}:", self.id), self.statements)
|
||||
IrBlock::new(self.id, &format!("b{}", self.id), self.statements)
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,9 +96,9 @@ impl LetStatement {
|
||||
Expression::String(string_literal) => {
|
||||
IrOperation::Load(IrExpression::String(string_literal.content().into()))
|
||||
}
|
||||
Expression::Identifier(identifier) => IrOperation::Load(IrExpression::Variable(
|
||||
identifier.expressible_symbol().ir_variable(),
|
||||
)),
|
||||
Expression::Identifier(identifier) => {
|
||||
IrOperation::Load(identifier.expressible_symbol().ir_expression())
|
||||
}
|
||||
Expression::Additive(additive_expression) => {
|
||||
IrOperation::Add(additive_expression.to_ir(builder, symbol_table))
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
use crate::ir::ir_expression::IrExpression;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct IrAdd {
|
||||
left: Box<IrExpression>,
|
||||
@ -20,3 +23,12 @@ impl Display for IrAdd {
|
||||
write!(f, "{} + {}", self.left, self.right)
|
||||
}
|
||||
}
|
||||
|
||||
impl IrAdd {
|
||||
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
|
||||
let mut set = HashSet::new();
|
||||
set.extend(self.left.uses());
|
||||
set.extend(self.right.uses());
|
||||
set
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +1,33 @@
|
||||
use crate::ir::ir_operation::IrOperation;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct IrAssign {
|
||||
destination: Rc<RefCell<IrVariable>>,
|
||||
destination: Rc<IrVariable>,
|
||||
initializer: Box<IrOperation>,
|
||||
}
|
||||
|
||||
impl IrAssign {
|
||||
pub fn new(destination: IrVariable, initializer: IrOperation) -> Self {
|
||||
Self {
|
||||
destination: Rc::new(RefCell::new(destination)),
|
||||
destination: Rc::new(destination),
|
||||
initializer: initializer.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destination(&self) -> &Rc<RefCell<IrVariable>> {
|
||||
pub fn destination(&self) -> &Rc<IrVariable> {
|
||||
&self.destination
|
||||
}
|
||||
|
||||
pub fn initializer(&self) -> &IrOperation {
|
||||
&self.initializer
|
||||
}
|
||||
|
||||
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
|
||||
self.initializer.uses()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for IrAssign {
|
||||
@ -27,8 +35,8 @@ impl Display for IrAssign {
|
||||
write!(
|
||||
f,
|
||||
"{}: {} = {}",
|
||||
self.destination.borrow(),
|
||||
self.destination.borrow().type_info(),
|
||||
self.destination,
|
||||
self.destination.type_info(),
|
||||
self.initializer
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
use crate::ir::ir_statement::IrStatement;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -29,14 +31,136 @@ impl IrBlock {
|
||||
pub fn statements(&self) -> &[IrStatement] {
|
||||
&self.statements
|
||||
}
|
||||
|
||||
fn definitions(&self) -> HashSet<Rc<IrVariable>> {
|
||||
let mut set = HashSet::new();
|
||||
for statement in &self.statements {
|
||||
set.extend(statement.definitions())
|
||||
}
|
||||
set
|
||||
}
|
||||
|
||||
fn uses(&self) -> HashSet<Rc<IrVariable>> {
|
||||
let mut set = HashSet::new();
|
||||
for statement in &self.statements {
|
||||
set.extend(statement.uses());
|
||||
}
|
||||
set
|
||||
}
|
||||
|
||||
fn live_in_live_out(
|
||||
&self,
|
||||
) -> (
|
||||
HashMap<usize, HashSet<Rc<IrVariable>>>,
|
||||
HashMap<usize, HashSet<Rc<IrVariable>>>,
|
||||
) {
|
||||
let mut live_in: HashMap<usize, HashSet<Rc<IrVariable>>> = HashMap::new();
|
||||
let mut live_out: HashMap<usize, HashSet<Rc<IrVariable>>> = HashMap::new();
|
||||
|
||||
loop {
|
||||
let mut did_work = false;
|
||||
for (statement_index, statement) in self.statements.iter().enumerate().rev() {
|
||||
// init if necessary
|
||||
if !live_in.contains_key(&statement_index) {
|
||||
live_in.insert(statement_index, HashSet::new());
|
||||
}
|
||||
if !live_out.contains_key(&statement_index) {
|
||||
live_out.insert(statement_index, HashSet::new());
|
||||
}
|
||||
|
||||
// out (union of successors ins)
|
||||
// for now, a statement can only have one successor
|
||||
// this will need to be updated when we add jumps
|
||||
if let Some(successor_live_in) = live_in.get(&(statement_index + 1)) {
|
||||
let statement_live_out = live_out.get_mut(&statement_index).unwrap();
|
||||
for ir_variable in successor_live_in {
|
||||
if statement_live_out.insert(ir_variable.clone()) {
|
||||
did_work = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// in: use(s) U ( out(s) - def(s) )
|
||||
let mut new_ins = statement.uses();
|
||||
let statement_live_out = live_out.get(&statement_index).unwrap();
|
||||
let defs = statement.definitions();
|
||||
let rhs = statement_live_out - &defs;
|
||||
new_ins.extend(rhs);
|
||||
|
||||
let statement_live_in = live_in.get_mut(&statement_index).unwrap();
|
||||
for new_in in new_ins {
|
||||
if statement_live_in.insert(new_in) {
|
||||
did_work = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if !did_work {
|
||||
break;
|
||||
}
|
||||
}
|
||||
(live_in, live_out)
|
||||
}
|
||||
|
||||
fn interference_graph(&self) -> HashMap<Rc<IrVariable>, HashSet<Rc<IrVariable>>> {
|
||||
let mut all_variables: HashSet<Rc<IrVariable>> = HashSet::new();
|
||||
for statement in &self.statements {
|
||||
all_variables.extend(statement.definitions());
|
||||
all_variables.extend(statement.uses());
|
||||
}
|
||||
|
||||
let mut graph: HashMap<Rc<IrVariable>, HashSet<Rc<IrVariable>>> = HashMap::new();
|
||||
for variable in all_variables {
|
||||
graph.insert(variable, HashSet::new());
|
||||
}
|
||||
|
||||
let (_, live_out) = self.live_in_live_out();
|
||||
|
||||
for (statement_index, statement) in self.statements.iter().enumerate() {
|
||||
let statement_live_out = live_out.get(&statement_index).unwrap();
|
||||
for definition_variable in statement.definitions() {
|
||||
for live_out_variable in statement_live_out {
|
||||
if definition_variable != *live_out_variable {
|
||||
graph
|
||||
.get_mut(&definition_variable)
|
||||
.unwrap()
|
||||
.insert(live_out_variable.clone());
|
||||
graph
|
||||
.get_mut(live_out_variable)
|
||||
.unwrap()
|
||||
.insert(definition_variable.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
graph
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for IrBlock {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, " {}", self.debug_label)?;
|
||||
for statement in &self.statements {
|
||||
writeln!(f, " {}", statement)?;
|
||||
writeln!(f, " {}:", self.debug_label)?;
|
||||
|
||||
let (live_in, live_out) = self.live_in_live_out();
|
||||
|
||||
for (statement_index, statement) in self.statements.iter().enumerate() {
|
||||
let statement_live_in = live_in.get(&statement_index).unwrap();
|
||||
let statement_live_out = live_out.get(&statement_index).unwrap();
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
" {} // live_in: {:?}, live_out: {:?}",
|
||||
statement, statement_live_in, statement_live_out
|
||||
)?;
|
||||
}
|
||||
writeln!(f, " // ---- {} meta ----", self.debug_label)?;
|
||||
writeln!(f, " // definitions: {:?}", self.definitions())?;
|
||||
writeln!(f, " // uses: {:?}", self.uses())?;
|
||||
writeln!(
|
||||
f,
|
||||
" // interference graph: {:?}",
|
||||
self.interference_graph()
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
use crate::ir::ir_expression::IrExpression;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -14,6 +16,14 @@ impl IrCall {
|
||||
arguments,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
|
||||
let mut set = HashSet::new();
|
||||
for argument in &self.arguments {
|
||||
set.extend(argument.uses());
|
||||
}
|
||||
set
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for IrCall {
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
use crate::ir::ir_parameter::IrParameter;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub enum IrExpression {
|
||||
Variable(Rc<RefCell<IrVariable>>),
|
||||
Parameter(Rc<IrParameter>),
|
||||
Variable(Rc<IrVariable>),
|
||||
Int(i32),
|
||||
String(Rc<str>),
|
||||
}
|
||||
@ -12,8 +14,11 @@ pub enum IrExpression {
|
||||
impl Display for IrExpression {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
IrExpression::Parameter(ir_parameter) => {
|
||||
write!(f, "{}", ir_parameter)
|
||||
}
|
||||
IrExpression::Variable(ir_variable) => {
|
||||
write!(f, "{}", ir_variable.borrow())
|
||||
write!(f, "{}", ir_variable)
|
||||
}
|
||||
IrExpression::Int(i) => {
|
||||
write!(f, "{}", i)
|
||||
@ -24,3 +29,24 @@ impl Display for IrExpression {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IrExpression {
|
||||
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
|
||||
let mut set = HashSet::new();
|
||||
match self {
|
||||
IrExpression::Parameter(_) => {
|
||||
// no-op
|
||||
}
|
||||
IrExpression::Variable(ir_variable) => {
|
||||
set.insert(ir_variable.clone());
|
||||
}
|
||||
IrExpression::Int(_) => {
|
||||
// no-op
|
||||
}
|
||||
IrExpression::String(_) => {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
set
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::ir::ir_block::IrBlock;
|
||||
use crate::ir::ir_parameter::IrParameter;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use crate::type_info::TypeInfo;
|
||||
use std::cell::RefCell;
|
||||
@ -7,7 +8,7 @@ use std::rc::Rc;
|
||||
|
||||
pub struct IrFunction {
|
||||
name: Rc<str>,
|
||||
parameters: Vec<Rc<RefCell<IrVariable>>>,
|
||||
parameters: Vec<Rc<IrParameter>>,
|
||||
return_type_info: TypeInfo,
|
||||
entry: Rc<RefCell<IrBlock>>,
|
||||
}
|
||||
@ -15,7 +16,7 @@ pub struct IrFunction {
|
||||
impl IrFunction {
|
||||
pub fn new(
|
||||
name: Rc<str>,
|
||||
parameters: &[Rc<RefCell<IrVariable>>],
|
||||
parameters: &[Rc<IrParameter>],
|
||||
return_type_info: TypeInfo,
|
||||
entry: Rc<RefCell<IrBlock>>,
|
||||
) -> Self {
|
||||
@ -32,12 +33,7 @@ impl Display for IrFunction {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "fn {}(", self.name)?;
|
||||
for (i, parameter) in self.parameters.iter().enumerate() {
|
||||
write!(
|
||||
f,
|
||||
"{}: {}",
|
||||
parameter.borrow(),
|
||||
parameter.borrow().type_info()
|
||||
)?;
|
||||
write!(f, "{}: {}", parameter, parameter.type_info())?;
|
||||
if i < self.parameters.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use crate::ir::ir_add::IrAdd;
|
||||
use crate::ir::ir_call::IrCall;
|
||||
use crate::ir::ir_expression::IrExpression;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub enum IrOperation {
|
||||
Load(IrExpression),
|
||||
@ -24,3 +27,13 @@ impl Display for IrOperation {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IrOperation {
|
||||
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
|
||||
match self {
|
||||
IrOperation::Load(ir_expression) => ir_expression.uses(),
|
||||
IrOperation::Add(ir_add) => ir_add.uses(),
|
||||
IrOperation::Call(ir_call) => ir_call.uses(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
dmc-lib/src/ir/ir_parameter.rs
Normal file
27
dmc-lib/src/ir/ir_parameter.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use crate::type_info::TypeInfo;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct IrParameter {
|
||||
name: Rc<str>,
|
||||
type_info: TypeInfo,
|
||||
}
|
||||
|
||||
impl IrParameter {
|
||||
pub fn new(name: &str, type_info: TypeInfo) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
type_info,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_info(&self) -> &TypeInfo {
|
||||
&self.type_info
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for IrParameter {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
use crate::ir::ir_expression::IrExpression;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct IrReturn {
|
||||
value: Option<IrExpression>,
|
||||
@ -9,6 +12,10 @@ impl IrReturn {
|
||||
pub fn new(value: Option<IrExpression>) -> Self {
|
||||
Self { value }
|
||||
}
|
||||
|
||||
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
|
||||
self.value.as_ref().map_or(HashSet::new(), |v| v.uses())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for IrReturn {
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use crate::ir::ir_assign::IrAssign;
|
||||
use crate::ir::ir_call::IrCall;
|
||||
use crate::ir::ir_return::IrReturn;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub enum IrStatement {
|
||||
Assign(IrAssign),
|
||||
@ -9,6 +12,38 @@ pub enum IrStatement {
|
||||
Return(IrReturn),
|
||||
}
|
||||
|
||||
impl IrStatement {
|
||||
pub fn definitions(&self) -> HashSet<Rc<IrVariable>> {
|
||||
let mut set = HashSet::new();
|
||||
match self {
|
||||
IrStatement::Assign(ir_assign) => {
|
||||
set.insert(ir_assign.destination().clone());
|
||||
}
|
||||
IrStatement::Call(_) => {
|
||||
// no-op
|
||||
}
|
||||
IrStatement::Return(_) => {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
set
|
||||
}
|
||||
|
||||
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
|
||||
let mut set = HashSet::new();
|
||||
match self {
|
||||
IrStatement::Assign(ir_assign) => {
|
||||
set.extend(ir_assign.uses());
|
||||
}
|
||||
IrStatement::Call(ir_call) => {
|
||||
set.extend(ir_call.uses());
|
||||
}
|
||||
IrStatement::Return(ir_return) => set.extend(ir_return.uses()),
|
||||
}
|
||||
set
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for IrStatement {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
use crate::type_info::TypeInfo;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Represents a virtual register
|
||||
pub struct IrVariable {
|
||||
name: Rc<str>,
|
||||
type_info: TypeInfo,
|
||||
@ -15,6 +17,10 @@ impl IrVariable {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn type_info(&self) -> &TypeInfo {
|
||||
&self.type_info
|
||||
}
|
||||
@ -25,3 +31,23 @@ impl Display for IrVariable {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for IrVariable {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for IrVariable {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.name.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for IrVariable {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for IrVariable {}
|
||||
|
||||
@ -5,6 +5,7 @@ pub mod ir_call;
|
||||
pub mod ir_expression;
|
||||
pub mod ir_function;
|
||||
pub mod ir_operation;
|
||||
pub mod ir_parameter;
|
||||
pub mod ir_return;
|
||||
pub mod ir_statement;
|
||||
pub mod ir_variable;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use crate::ir::ir_expression::IrExpression;
|
||||
use crate::ir::ir_parameter::IrParameter;
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
use crate::type_info::TypeInfo;
|
||||
use std::cell::RefCell;
|
||||
@ -48,7 +50,7 @@ impl FunctionSymbol {
|
||||
pub struct ParameterSymbol {
|
||||
name: Rc<str>,
|
||||
type_info: TypeInfo,
|
||||
ir_variable: Option<Rc<RefCell<IrVariable>>>,
|
||||
ir_parameter: Option<Rc<IrParameter>>,
|
||||
|
||||
#[deprecated]
|
||||
stack_frame_offset: Option<isize>,
|
||||
@ -59,7 +61,7 @@ impl ParameterSymbol {
|
||||
Self {
|
||||
name: name.into(),
|
||||
type_info,
|
||||
ir_variable: None,
|
||||
ir_parameter: None,
|
||||
stack_frame_offset: None,
|
||||
}
|
||||
}
|
||||
@ -76,14 +78,12 @@ impl ParameterSymbol {
|
||||
&self.type_info
|
||||
}
|
||||
|
||||
pub fn set_ir_variable(&mut self, ir_variable: Rc<RefCell<IrVariable>>) {
|
||||
self.ir_variable = Some(ir_variable);
|
||||
pub fn set_ir_parameter(&mut self, ir_parameter: Rc<IrParameter>) {
|
||||
self.ir_parameter = Some(ir_parameter);
|
||||
}
|
||||
|
||||
pub fn ir_variable(&self) -> &Rc<RefCell<IrVariable>> {
|
||||
self.ir_variable
|
||||
.as_ref()
|
||||
.expect("ir_variable not yet initialized")
|
||||
pub fn ir_parameter(&self) -> &Rc<IrParameter> {
|
||||
self.ir_parameter.as_ref().unwrap()
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
@ -100,7 +100,7 @@ impl ParameterSymbol {
|
||||
pub struct VariableSymbol {
|
||||
name: Rc<str>,
|
||||
type_info: Option<TypeInfo>,
|
||||
ir_variable: Option<Rc<RefCell<IrVariable>>>,
|
||||
ir_variable: Option<Rc<IrVariable>>,
|
||||
|
||||
#[deprecated]
|
||||
register: Option<usize>,
|
||||
@ -134,11 +134,11 @@ impl VariableSymbol {
|
||||
.expect("TypeInfo not initialized. Did you type check?")
|
||||
}
|
||||
|
||||
pub fn set_ir_variable(&mut self, ir_variable: Rc<RefCell<IrVariable>>) {
|
||||
pub fn set_ir_variable(&mut self, ir_variable: Rc<IrVariable>) {
|
||||
self.ir_variable = Some(ir_variable);
|
||||
}
|
||||
|
||||
pub fn ir_variable(&self) -> &Rc<RefCell<IrVariable>> {
|
||||
pub fn ir_variable(&self) -> &Rc<IrVariable> {
|
||||
self.ir_variable
|
||||
.as_ref()
|
||||
.expect("ir_variable not yet initialized")
|
||||
@ -160,16 +160,16 @@ pub enum ExpressibleSymbol {
|
||||
}
|
||||
|
||||
impl ExpressibleSymbol {
|
||||
pub fn ir_variable(&self) -> Rc<RefCell<IrVariable>> {
|
||||
pub fn ir_expression(&self) -> IrExpression {
|
||||
match self {
|
||||
ExpressibleSymbol::Function(_) => {
|
||||
panic!("Cannot get ir_variable for FunctionSymbol");
|
||||
}
|
||||
ExpressibleSymbol::Parameter(parameter_symbol) => {
|
||||
parameter_symbol.borrow().ir_variable().clone()
|
||||
IrExpression::Parameter(parameter_symbol.borrow().ir_parameter().clone())
|
||||
}
|
||||
ExpressibleSymbol::Variable(variable_symbol) => {
|
||||
variable_symbol.borrow().ir_variable().clone()
|
||||
IrExpression::Variable(variable_symbol.borrow().ir_variable().clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,4 +8,5 @@ fn main()
|
||||
let y = add(1, 2)
|
||||
println(y)
|
||||
println(add(3, add(4, 5)))
|
||||
println(y)
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user