Skip to content

Commit

Permalink
[ir] Attach expected pointer type to IsPointer instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
SamChou19815 committed Jun 22, 2024
1 parent 45fadaa commit 7bddeaa
Show file tree
Hide file tree
Showing 23 changed files with 134 additions and 76 deletions.
10 changes: 4 additions & 6 deletions crates/samlang-ast/src/lir.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use std::collections::HashMap;

use crate::hir;

use super::{
hir::{BinaryOperator, GlobalString},
mir::{FunctionName, SymbolTable, TypeNameId},
};
use enum_as_inner::EnumAsInner;
use samlang_heap::{Heap, PStr};
use std::collections::HashMap;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PrimitiveType {
Expand Down Expand Up @@ -153,6 +150,7 @@ pub struct GenenalLoopVariable {
pub enum Statement {
IsPointer {
name: PStr,
pointer_type: TypeNameId,
operand: Expression,
},
Not {
Expand Down Expand Up @@ -262,7 +260,7 @@ impl Statement {
collector: &mut String,
) {
match self {
Statement::IsPointer { name, operand } => {
Statement::IsPointer { name, pointer_type: _, operand } => {
Self::append_spaces(collector, level);
collector.push_str("let ");
collector.push_str(name.as_str(heap));
Expand Down Expand Up @@ -621,7 +619,7 @@ impl Sources {
let mut collector = ts_prolog();

let mut str_lookup_table = HashMap::new();
for (i, hir::GlobalString(s)) in self.global_variables.iter().enumerate() {
for (i, GlobalString(s)) in self.global_variables.iter().enumerate() {
collector.push_str("const GLOBAL_STRING_");
collector.push_str(&i.to_string());
collector.push_str(": _Str = [0, `");
Expand Down
8 changes: 6 additions & 2 deletions crates/samlang-ast/src/lir_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod tests {
use super::super::lir::*;
use crate::{
hir::{BinaryOperator, GlobalString},
mir::{FunctionName, SymbolTable},
mir::{FunctionName, SymbolTable, TypeNameId},
};
use pretty_assertions::assert_eq;
use samlang_heap::{Heap, PStr};
Expand Down Expand Up @@ -152,7 +152,11 @@ mod tests {
],
s2: vec![
Statement::Not { name: heap.alloc_str_for_test("dd"), operand: ZERO },
Statement::IsPointer { name: heap.alloc_str_for_test("dd"), operand: ZERO },
Statement::IsPointer {
name: heap.alloc_str_for_test("dd"),
pointer_type: TypeNameId::STR,
operand: ZERO,
},
Statement::binary(heap.alloc_str_for_test("dd"), BinaryOperator::PLUS, ZERO, ZERO),
Statement::binary(heap.alloc_str_for_test("dd"), BinaryOperator::MINUS, ZERO, ZERO),
Statement::binary(
Expand Down
10 changes: 6 additions & 4 deletions crates/samlang-ast/src/mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ impl ClosureTypeDefinition {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum EnumTypeDefinition {
Boxed(Vec<Type>),
Unboxed(Type),
Unboxed(TypeNameId),
Int,
}

Expand All @@ -245,7 +245,7 @@ impl EnumTypeDefinition {
EnumTypeDefinition::Boxed(types) => {
format!("Boxed({})", types.iter().map(|it| it.pretty_print(heap, table)).join(", "))
}
EnumTypeDefinition::Unboxed(t) => format!("Unboxed({})", t.pretty_print(heap, table)),
EnumTypeDefinition::Unboxed(t) => format!("Unboxed({})", t.encoded_for_test(heap, table)),
EnumTypeDefinition::Int => "int".to_string(),
}
}
Expand Down Expand Up @@ -482,6 +482,7 @@ impl GenenalLoopVariable {
pub enum Statement {
IsPointer {
name: PStr,
pointer_type: TypeNameId,
operand: Expression,
},
Not {
Expand Down Expand Up @@ -644,12 +645,13 @@ impl Statement {
collector: &mut Vec<String>,
) {
match self {
Statement::IsPointer { name, operand } => {
Statement::IsPointer { name, pointer_type, operand } => {
collector.push(format!(
"{}let {} = is_pointer({});\n",
"{}let {} = {} is {};\n",
" ".repeat(level),
name.as_str(heap),
operand.debug_print(heap, table),
pointer_type.encoded_for_test(heap, table)
));
}
Statement::Not { name, operand } => {
Expand Down
10 changes: 7 additions & 3 deletions crates/samlang-ast/src/mir_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ mod tests {
name: table.create_type_name_for_test(PStr::UPPER_A),
mappings: TypeDefinitionMappings::Struct(vec![INT_32_TYPE, INT_32_TYPE]),
};
let ed1 = EnumTypeDefinition::Unboxed(Type::Id(table.create_type_name_for_test(PStr::UPPER_D)));
let ed1 = EnumTypeDefinition::Unboxed(table.create_type_name_for_test(PStr::UPPER_D));
let ed2 = EnumTypeDefinition::Boxed(vec![INT_32_TYPE, INT_32_TYPE]);
let ed3 = EnumTypeDefinition::Int;
assert!(ed1.eq(&ed1));
Expand Down Expand Up @@ -235,7 +235,11 @@ mod tests {
],
s2: vec![
Statement::Not { name: heap.alloc_str_for_test("dd"), operand: ZERO },
Statement::IsPointer { name: heap.alloc_str_for_test("dd"), operand: ZERO },
Statement::IsPointer {
name: heap.alloc_str_for_test("dd"),
pointer_type: TypeNameId::STR,
operand: ZERO,
},
Statement::binary(heap.alloc_str_for_test("dd"), BinaryOperator::PLUS, ZERO, ZERO),
Statement::binary(heap.alloc_str_for_test("dd"), BinaryOperator::MINUS, ZERO, ZERO),
Statement::binary(
Expand Down Expand Up @@ -327,7 +331,7 @@ if 0 {
bar = (b1: int);
} else {
let dd = !0;
let dd = is_pointer(0);
let dd = 0 is _Str;
let dd = 0 + 0;
let dd = 0 + 0;
let dd = 0 - -2147483648;
Expand Down
6 changes: 3 additions & 3 deletions crates/samlang-compiler/src/lir_lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ impl<'a> LoweringManager<'a> {

fn lower_stmt(&mut self, stmt: mir::Statement) -> Vec<lir::Statement> {
match stmt {
mir::Statement::IsPointer { name, operand } => {
vec![lir::Statement::IsPointer { name, operand: lower_expression(operand) }]
mir::Statement::IsPointer { name, pointer_type, operand } => {
vec![lir::Statement::IsPointer { name, pointer_type, operand: lower_expression(operand) }]
}
mir::Statement::Not { name, operand } => {
vec![lir::Statement::Not { name, operand: lower_expression(operand) }]
Expand Down Expand Up @@ -809,7 +809,7 @@ mod tests {
name: table.create_type_name_for_test(heap.alloc_str_for_test("Variant")),
mappings: TypeDefinitionMappings::Enum(vec![
EnumTypeDefinition::Int,
EnumTypeDefinition::Unboxed(INT_32_TYPE),
EnumTypeDefinition::Unboxed(TypeNameId::STR),
EnumTypeDefinition::Boxed(vec![INT_32_TYPE, INT_31_TYPE]),
]),
},
Expand Down
6 changes: 5 additions & 1 deletion crates/samlang-compiler/src/lir_unused_name_elimination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ fn collect_used_names_from_statement(
statement: &Statement,
) {
match statement {
Statement::IsPointer { name: _, operand } | Statement::Not { name: _, operand } => {
Statement::IsPointer { name: _, pointer_type, operand } => {
type_set.insert(*pointer_type);
collect_used_names_from_expression(str_name_set, fn_name_set, type_set, operand);
}
Statement::Not { name: _, operand } => {
collect_used_names_from_expression(str_name_set, fn_name_set, type_set, operand);
}
Statement::Binary { name: _, operator: _, e1, e2 } => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ fn rewrite_expr(state: &RewriteState, expr: &mut Expression) {

fn rewrite_stmt(state: &RewriteState, stmt: &mut Statement) {
match stmt {
Statement::IsPointer { name: _, operand } | Statement::Not { name: _, operand } => {
Statement::IsPointer { name: _, pointer_type: _, operand }
| Statement::Not { name: _, operand } => {
rewrite_expr(state, operand);
}
Statement::Binary(Binary { name: _, operator: _, e1, e2 }) => {
Expand Down
11 changes: 6 additions & 5 deletions crates/samlang-compiler/src/mir_generics_specialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,15 @@ impl Rewriter {
// Here we test whether this is a pointer
collector.push(mir::Statement::IsPointer {
name: comparison_temp,
pointer_type: *unboxed_t,
operand: mir::Expression::var_name(casted_int_collector, mir::INT_32_TYPE),
});
let mut nested_stmts = vec![];
// Once we pass the is-pointer check, we can cast the test expression to the underlying
// unboxed pointer type.
nested_stmts.push(mir::Statement::Cast {
name: binded_name,
type_: *unboxed_t,
type_: mir::Type::Id(*unboxed_t),
assigned_expression: test_expr,
});
nested_stmts.append(&mut self.rewrite_stmts(heap, s1, generics_replacement_map));
Expand Down Expand Up @@ -543,13 +544,13 @@ impl Rewriter {
mapping_types.push(self.rewrite_type(heap, t, &solved_targs_replacement_map));
}
if permit_unboxed_optimization
&& already_unused_boxed_optimization.is_none()
&& mapping_types.len() == 2
&& self.type_permit_enum_boxed_optimization(&mapping_types[1])
&& already_unused_boxed_optimization.is_none()
{
let t = mapping_types[1];
let t = mapping_types[1].into_id().unwrap();
mir_variants.push(mir::EnumTypeDefinition::Unboxed(t));
already_unused_boxed_optimization = Some((tag, t));
already_unused_boxed_optimization = Some((tag, mir::Type::Id(t)));
} else {
mir_variants.push(mir::EnumTypeDefinition::Boxed(mapping_types));
}
Expand Down Expand Up @@ -1322,7 +1323,7 @@ function _DUMMY_I$main(): int {
}
let b = 0 as DUMMY_Enum;
let _t1 = (b: DUMMY_Enum) as int;
let _t2 = is_pointer((_t1: int));
let _t2 = (_t1: int) is DUMMY_J;
if (_t2: int) {
let a = (b: DUMMY_Enum) as DUMMY_J;
} else {
Expand Down
10 changes: 5 additions & 5 deletions crates/samlang-compiler/src/mir_type_deduplication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ fn rewrite_expressions(state: &State, expressions: Vec<Expression>) -> Vec<Expre

fn rewrite_stmt(state: &State, stmt: Statement) -> Statement {
match stmt {
Statement::IsPointer { name, operand } => {
Statement::IsPointer { name, operand: rewrite_expr(state, operand) }
Statement::IsPointer { name, pointer_type, operand } => {
Statement::IsPointer { name, pointer_type, operand: rewrite_expr(state, operand) }
}
Statement::Not { name, operand } => {
Statement::Not { name, operand: rewrite_expr(state, operand) }
Expand Down Expand Up @@ -226,7 +226,7 @@ pub(super) fn deduplicate(
types.into_iter().map(|t| rewrite_type(&state, t)).collect(),
),
EnumTypeDefinition::Unboxed(t) => {
EnumTypeDefinition::Unboxed(rewrite_type(&state, t))
EnumTypeDefinition::Unboxed(rewrite_id_type_name(&state, t))
}
EnumTypeDefinition::Int => EnumTypeDefinition::Int,
})
Expand Down Expand Up @@ -332,7 +332,7 @@ mod tests {
name: table.create_type_name_for_test(PStr::UPPER_E),
mappings: TypeDefinitionMappings::Enum(vec![
EnumTypeDefinition::Boxed(vec![INT_32_TYPE]),
EnumTypeDefinition::Unboxed(INT_32_TYPE),
EnumTypeDefinition::Unboxed(TypeNameId::STR),
EnumTypeDefinition::Int,
]),
},
Expand Down Expand Up @@ -406,7 +406,7 @@ mod tests {
r#"closure type _A = () -> int
closure type _C = () -> _C
object type _C = [int, _Str]
variant type _E = [Boxed(int), Unboxed(int), int]
variant type _E = [Boxed(int), Unboxed(_Str), int]
function __$main(): int {
let _: int;
if 1 {
Expand Down
11 changes: 8 additions & 3 deletions crates/samlang-compiler/src/wasm_lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<'a> LoweringManager<'a> {

fn lower_stmt(&mut self, s: &lir::Statement) -> Vec<wasm::Instruction> {
match s {
lir::Statement::IsPointer { name, operand } => {
lir::Statement::IsPointer { name, pointer_type: _, operand } => {
let operand1 = Box::new(self.lower_expr(operand));
let operand2 = Box::new(self.lower_expr(operand));
vec![wasm::Instruction::Inline(self.set(
Expand Down Expand Up @@ -323,7 +323,8 @@ mod tests {
use samlang_ast::{
hir::{BinaryOperator, GlobalString},
lir::{Expression, Function, GenenalLoopVariable, Sources, Statement, Type, INT_32_TYPE, ZERO},
mir, wasm,
mir::{self, TypeNameId},
wasm,
};
use samlang_heap::{Heap, PStr};

Expand Down Expand Up @@ -414,7 +415,11 @@ mod tests {
)],
},
Statement::Not { name: heap.alloc_str_for_test("un1"), operand: ZERO },
Statement::IsPointer { name: heap.alloc_str_for_test("un2"), operand: ZERO },
Statement::IsPointer {
name: heap.alloc_str_for_test("un2"),
pointer_type: TypeNameId::STR,
operand: ZERO,
},
Statement::binary(
heap.alloc_str_for_test("bin"),
BinaryOperator::PLUS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ fn optimize_stmts(
| Statement::StructInit { .. }
| Statement::ClosureInit { .. } => collector.push(stmt),

Statement::IsPointer { name, operand } => {
set.insert(BindedValue::IsPointer(operand));
collector.push(Statement::IsPointer { name, operand });
Statement::IsPointer { name, pointer_type, operand } => {
set.insert(BindedValue::IsPointer(pointer_type, operand));
collector.push(Statement::IsPointer { name, pointer_type, operand });
}
Statement::Not { name, operand } => {
set.insert(BindedValue::Not(operand));
Expand Down Expand Up @@ -73,8 +73,8 @@ fn optimize_stmts(
BindedValue::Binary(BinaryBindedValue { operator, e1, e2 }) => Statement::Binary(
Statement::binary_unwrapped(heap.alloc_temp_str(), operator, e1, e2),
),
BindedValue::IsPointer(operand) => {
Statement::IsPointer { name: heap.alloc_temp_str(), operand }
BindedValue::IsPointer(pointer_type, operand) => {
Statement::IsPointer { name: heap.alloc_temp_str(), pointer_type, operand }
}
BindedValue::Not(operand) => Statement::Not { name: heap.alloc_temp_str(), operand },
})
Expand All @@ -98,7 +98,7 @@ mod tests {
hir::BinaryOperator,
mir::{
Callee, Expression, Function, FunctionName, FunctionNameExpression, Statement, SymbolTable,
Type, VariableName, INT_32_TYPE, ONE, ZERO,
Type, TypeNameId, VariableName, INT_32_TYPE, ONE, ZERO,
},
};
use samlang_heap::{Heap, PStr};
Expand Down Expand Up @@ -130,7 +130,11 @@ mod tests {
s1: vec![
Statement::binary(heap.alloc_str_for_test("ddddd"), BinaryOperator::PLUS, ONE, ONE),
Statement::Not { name: heap.alloc_str_for_test("ud1"), operand: ZERO },
Statement::IsPointer { name: heap.alloc_str_for_test("ud3"), operand: ZERO },
Statement::IsPointer {
name: heap.alloc_str_for_test("ud3"),
pointer_type: TypeNameId::STR,
operand: ZERO,
},
Statement::binary(PStr::LOWER_A, BinaryOperator::PLUS, ONE, ZERO),
Statement::IndexedAccess {
name: heap.alloc_str_for_test("ddd"),
Expand All @@ -153,7 +157,11 @@ mod tests {
],
s2: vec![
Statement::Not { name: heap.alloc_str_for_test("ud2"), operand: ZERO },
Statement::IsPointer { name: heap.alloc_str_for_test("ud4"), operand: ZERO },
Statement::IsPointer {
name: heap.alloc_str_for_test("ud4"),
pointer_type: TypeNameId::STR,
operand: ZERO,
},
Statement::binary(heap.alloc_str_for_test("fd"), BinaryOperator::PLUS, ONE, ZERO),
Statement::IndexedAccess {
name: heap.alloc_str_for_test("eee"),
Expand All @@ -179,7 +187,7 @@ mod tests {
heap,
r#"let _t3: int = 0[3];
let _t2 = 1 + 0;
let _t1 = is_pointer(0);
let _t1 = 0 is _Str;
let _t0 = !0;
if (b: int) {
let ddddd = 1 + 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,12 @@ fn optimize_stmt(
}
false
}
Statement::IsPointer { name, operand } => {
collector
.push(Statement::IsPointer { name: *name, operand: optimize_expr(value_cx, operand) });
Statement::IsPointer { name, pointer_type, operand } => {
collector.push(Statement::IsPointer {
name: *name,
pointer_type: *pointer_type,
operand: optimize_expr(value_cx, operand),
});
false
}
Statement::Binary(Binary { name, operator, e1, e2 }) => {
Expand Down
Loading

0 comments on commit 7bddeaa

Please sign in to comment.