TOO MUCH!!!! InternPool use everywhere in old ast

This commit is contained in:
Janis 2024-12-23 02:34:02 +01:00
parent 7801fefa17
commit 7c01afbf2f
6 changed files with 360 additions and 385 deletions

View file

@ -1,6 +1,9 @@
use std::num::NonZero; use std::num::NonZero;
use crate::string_table::{self, ImmOrIndex}; use crate::{
ast2::intern,
string_table::{self, ImmOrIndex},
};
pub type Node = NonZero<u32>; pub type Node = NonZero<u32>;
@ -33,8 +36,8 @@ pub enum Tag {
PointerQualifier { PointerQualifier {
constness: bool, constness: bool,
}, },
IntegralType(IntegralType), IntegralType(intern::Index),
PrimitiveType(PrimitiveType), PrimitiveType(intern::Index),
FunctionDecl { FunctionDecl {
/// FunctionProto /// FunctionProto
proto: Node, proto: Node,
@ -42,10 +45,11 @@ pub enum Tag {
body: Node, body: Node,
}, },
Ident { Ident {
name: string_table::Index, name: intern::Index,
}, },
/// bytes might be an integer, float, double, or Bytes
Constant { Constant {
bytes: ImmOrIndex, bytes: intern::Index,
ty: Type, ty: Type,
}, },
Block { Block {

View file

@ -6,7 +6,7 @@ use std::{
num::NonZero, num::NonZero,
}; };
use intern::{InternPool, PointerFlags, StructFlags}; use intern::{InternPool, PointerFlags, StructFlags, AMD64_POINTER_TYPE_INFO};
use num_bigint::BigInt; use num_bigint::BigInt;
use crate::{ use crate::{
@ -66,7 +66,7 @@ enum Tag {
TypeDeclRef, TypeDeclRef,
/// `data` is an inlined key into the symbol table (scope: index, name: intern) /// `data` is an inlined key into the symbol table (scope: index, name: intern)
TypeDeclRefUnresolved, TypeDeclRefUnresolved,
/// `data` is an index to a Type and u32 PointerFlags /// `data` is an index to a Type and u32 PointerFlags (extra offset)
PointerType, PointerType,
/// `data` is an index to a length expression, and an underlying pointer type /// `data` is an index to a length expression, and an underlying pointer type
ArrayType, ArrayType,
@ -263,6 +263,7 @@ union Data {
two_interns: (intern::Index, intern::Index), two_interns: (intern::Index, intern::Index),
intern_and_extra_offset: (intern::Index, u32), intern_and_extra_offset: (intern::Index, u32),
index_and_extra_offset: (Index, u32), index_and_extra_offset: (Index, u32),
index_and_opaque: (Index, u32),
} }
#[derive(Debug)] #[derive(Debug)]
@ -279,6 +280,7 @@ enum ExpandedData {
TwoInterns(intern::Index, intern::Index), TwoInterns(intern::Index, intern::Index),
InternAndExtraOffset(intern::Index, usize), InternAndExtraOffset(intern::Index, usize),
IndexAndExtraOffset(Index, usize), IndexAndExtraOffset(Index, usize),
IndexAndOpaque(Index, u32),
} }
impl ExpandedData { impl ExpandedData {
@ -324,6 +326,10 @@ impl ExpandedData {
let data = data.as_index_and_extra_offset(); let data = data.as_index_and_extra_offset();
Self::IndexAndExtraOffset(data.0, data.1) Self::IndexAndExtraOffset(data.0, data.1)
} }
fn from_index_and_opaque(data: Data) -> Self {
let data = data.as_index_and_opaque();
Self::IndexAndExtraOffset(data.0, data.1)
}
} }
impl From<(Tag, Data)> for ExpandedData { impl From<(Tag, Data)> for ExpandedData {
@ -428,6 +434,10 @@ impl Data {
let (i, e) = unsafe { self.intern_and_extra_offset }; let (i, e) = unsafe { self.intern_and_extra_offset };
(i, e as usize) (i, e as usize)
} }
fn as_index_and_opaque(self) -> (Index, usize) {
let (i, e) = unsafe { self.index_and_opaque };
(i, e as usize)
}
} }
impl Data { impl Data {
@ -476,6 +486,11 @@ impl Data {
index_and_extra_offset: (index, offset), index_and_extra_offset: (index, offset),
} }
} }
fn index_and_opaque(index: Index, value: u32) -> Self {
Self {
index_and_opaque: (index, value),
}
}
} }
pub struct Ast { pub struct Ast {
@ -1822,7 +1837,7 @@ impl Ast {
} }
} }
fn comptime_number_to_interned_type_and_value( pub fn comptime_number_to_interned_type_and_value(
ip: &mut InternPool, ip: &mut InternPool,
pointer_bits: u16, pointer_bits: u16,
comptime: ComptimeNumber, comptime: ComptimeNumber,
@ -1898,7 +1913,7 @@ fn comptime_number_to_interned_type_and_value(
(value, ty) (value, ty)
} }
fn interned_type_and_value_to_comptime_number( pub fn interned_type_and_value_to_comptime_number(
ip: &InternPool, ip: &InternPool,
pointer_bits: u16, pointer_bits: u16,
ty: intern::Index, ty: intern::Index,
@ -1908,10 +1923,11 @@ fn interned_type_and_value_to_comptime_number(
use crate::comptime::*; use crate::comptime::*;
let ty_key = ip.get_key(ty); let ty_key = ip.get_key(ty);
let signed = ip.is_type_signed(ty, AMD64_POINTER_TYPE_INFO);
match ty_key { match ty_key {
intern::Key::SIntType { bit_width: bits } intern::Key::SIntType { bit_width: bits }
| intern::Key::UIntType { bit_width: bits } => { | intern::Key::UIntType { bit_width: bits } => {
let ty = IntegralType::new(false, bits); let ty = IntegralType::new(signed, bits);
match ip.get_key(val) { match ip.get_key(val) {
intern::Key::SIntSmall { bits } => { intern::Key::SIntSmall { bits } => {
ComptimeNumber::Integral(ComptimeInt::Native { ComptimeNumber::Integral(ComptimeInt::Native {
@ -2467,7 +2483,7 @@ pub mod ast_gen {
}); });
let names = self.ast.extra[names] let names = self.ast.extra[names]
.iter() .iter()
.map(|&i| intern::Index(i)); .map(|&i| intern::Index::from_u32(i));
self.intern.insert_or_replace_struct_type( self.intern.insert_or_replace_struct_type(
name, name,
@ -4248,17 +4264,16 @@ pub mod ast_gen {
} }
pub mod ir_gen { pub mod ir_gen {
use intern::InternPool;
use super::*; use super::*;
use crate::{symbol_table::syms2::Symbols, triples::*}; use crate::{symbol_table::syms2::Symbols, triples::*};
struct IRGen<'a> { struct IRGen {
ast: Ast, ast: Ast,
syms: Symbols, syms: Symbols,
intern: InternPool, ir: IR,
ir: IR<'a>, ip: intern::InternPool,
} }
impl IRGen<'_> {} impl IRGen {}
} }

View file

@ -12,6 +12,7 @@ fn ast_tree(tokens: &Tokenizer) -> Tree {
let mut tree = Tree::new(); let mut tree = Tree::new();
tree.parse(tokens.iter()).unwrap(); tree.parse(tokens.iter()).unwrap();
tree.fold_comptime(); tree.fold_comptime();
tree.intern_types();
tree tree
} }
@ -63,8 +64,7 @@ fn main() {
} }
"ir" => { "ir" => {
let mut tree = ast_tree(&tokens); let mut tree = ast_tree(&tokens);
let mut intern = InternPool::new(); let mut ir = IR::new();
let mut ir = IR::new(&mut intern);
let builder = ir.build(&mut tree); let builder = ir.build(&mut tree);
let mut buf = String::new(); let mut buf = String::new();
builder.render(&mut buf).unwrap(); builder.render(&mut buf).unwrap();
@ -72,15 +72,16 @@ fn main() {
} }
"mir" => { "mir" => {
let mut tree = ast_tree(&tokens); let mut tree = ast_tree(&tokens);
let mut intern = InternPool::new(); let mut ir = IR::new();
let mut ir = IR::new(&mut intern);
ir.build(&mut tree); ir.build(&mut tree);
let mut mir = MirBuilder::new(&ir, tree.strings); let mut mir = MirBuilder::new(&ir, tree.intern_pool);
mir.build(); mir.build();
let MirBuilder { let MirBuilder {
strings, functions, .. intern_pool: strings,
functions,
..
} = mir; } = mir;
for (name, mir) in functions { for (name, mir) in functions {
@ -93,16 +94,15 @@ fn main() {
} }
"asm" => { "asm" => {
let mut tree = ast_tree(&tokens); let mut tree = ast_tree(&tokens);
let mut intern = InternPool::new(); let mut ir = IR::new();
let mut ir = IR::new(&mut intern);
_ = ir.build(&mut tree); _ = ir.build(&mut tree);
let mut mir = MirBuilder::new(&ir, tree.strings); let mut mir = MirBuilder::new(&ir, tree.intern_pool);
mir.build(); mir.build();
let MirBuilder { let MirBuilder {
globals, globals,
strings, intern_pool: strings,
functions, functions,
.. ..
} = mir; } = mir;

View file

@ -1,5 +1,3 @@
use std::collections::HashMap;
use itertools::Itertools; use itertools::Itertools;
use num_bigint::{BigInt, BigUint}; use num_bigint::{BigInt, BigUint};
@ -8,13 +6,14 @@ use crate::{
self, FloatingType, IntegralType, LetOrVar, Node, PrimitiveType, Tag, self, FloatingType, IntegralType, LetOrVar, Node, PrimitiveType, Tag,
Type, Type,
}, },
ast2::intern::{self, AMD64_POINTER_BITS},
common::NextIf, common::NextIf,
comptime::{self, ComptimeNumber}, comptime::{self, ComptimeNumber},
error::{AnalysisError, AnalysisErrorTag}, error::{AnalysisError, AnalysisErrorTag},
lexer::{Radix, TokenIterator}, lexer::{Radix, TokenIterator},
string_table::{ImmOrIndex, Index, StringTable},
symbol_table::{SymbolKind, SymbolTable}, symbol_table::{SymbolKind, SymbolTable},
tokens::{Token, PRECEDENCE_MAP}, tokens::{Token, PRECEDENCE_MAP},
BitSize,
}; };
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@ -98,7 +97,7 @@ impl Nodes {
pub struct Tree { pub struct Tree {
pub nodes: Nodes, pub nodes: Nodes,
pub st: SymbolTable, pub st: SymbolTable,
pub strings: StringTable, pub intern_pool: intern::InternPool,
pub global_decls: Vec<Node>, pub global_decls: Vec<Node>,
} }
@ -137,7 +136,7 @@ impl Tree {
Self { Self {
nodes: Nodes::new(), nodes: Nodes::new(),
st: SymbolTable::new(), st: SymbolTable::new(),
strings: StringTable::new(), intern_pool: intern::InternPool::new(),
global_decls: Vec::new(), global_decls: Vec::new(),
} }
} }
@ -318,14 +317,14 @@ impl Tree {
fn parse_ident(&mut self, tokens: &mut TokenIterator) -> Result<Node> { fn parse_ident(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
let ident = tokens.expect_token(Token::Ident)?; let ident = tokens.expect_token(Token::Ident)?;
let name = self.strings.insert(ident.lexeme().as_bytes()); let name = self.intern_pool.insert_string(ident.lexeme());
Ok(self.nodes.push_tag(Tag::Ident { name })) Ok(self.nodes.push_tag(Tag::Ident { name }))
} }
fn ident_index(&self, node: Node) -> Index { fn ident_index(&self, node: Node) -> intern::Index {
match &self.nodes[node] { match &self.nodes[node] {
Tag::Ident { name } => *name, Tag::Ident { name } => *name,
_ => Index::new(0, 0), _ => intern::Index::EMPTY_STRING,
} }
} }
@ -335,10 +334,10 @@ impl Tree {
) -> Result<Node> { ) -> Result<Node> {
let token = tokens.next().ok_or(Error::UnexpectedEndOfTokens)?; let token = tokens.next().ok_or(Error::UnexpectedEndOfTokens)?;
let prim = match token.token() { let prim = match token.token() {
Token::Void => PrimitiveType::Void, Token::Void => intern::Index::VOID,
Token::Bool => PrimitiveType::Bool, Token::Bool => intern::Index::BOOL,
Token::F32 => PrimitiveType::FloatingType(FloatingType::Binary32), Token::F32 => intern::Index::F32,
Token::F64 => PrimitiveType::FloatingType(FloatingType::Binary64), Token::F64 => intern::Index::F64,
_ => { _ => {
return Err(Error::ExpectedPrimitiveType); return Err(Error::ExpectedPrimitiveType);
} }
@ -368,11 +367,14 @@ impl Tree {
let token = tokens.next().unwrap(); let token = tokens.next().unwrap();
match Self::try_parse_integral_type(token.lexeme())? { match Self::try_parse_integral_type(token.lexeme())? {
Some(int) => { Some(int) => {
Ok(self.nodes.push_tag(Tag::IntegralType(int))) let ty =
self.intern_pool.get_int_type(int.signed, int.bits);
Ok(self.nodes.push_tag(Tag::IntegralType(ty)))
} }
None => { None => {
let name = let name =
self.strings.insert(token.lexeme().as_bytes()); self.intern_pool.insert_string(token.lexeme());
Ok(self.nodes.push_tag(Tag::Ident { name })) Ok(self.nodes.push_tag(Tag::Ident { name }))
} }
} }
@ -404,7 +406,8 @@ impl Tree {
None None
}; };
let name_str = self.strings.get_str(self.ident_index(name)).to_owned(); let name_str =
self.intern_pool.get_str(self.ident_index(name)).to_owned();
let decl = self.nodes.reserve_node(); let decl = self.nodes.reserve_node();
let assignment = if tokens.eat_token(Token::Equal).is_some() { let assignment = if tokens.eat_token(Token::Equal).is_some() {
@ -550,7 +553,7 @@ impl Tree {
let return_type = if tokens.eat_token(Token::MinusGreater).is_some() { let return_type = if tokens.eat_token(Token::MinusGreater).is_some() {
self.parse_typename(tokens)? self.parse_typename(tokens)?
} else { } else {
self.nodes.push_tag(Tag::PrimitiveType(PrimitiveType::Void)) self.nodes.push_tag(Tag::PrimitiveType(intern::Index::VOID))
}; };
let proto = self.nodes.push_tag(Tag::FunctionProto { let proto = self.nodes.push_tag(Tag::FunctionProto {
@ -1026,19 +1029,18 @@ impl Tree {
0..2 => { 0..2 => {
let (buf, _) = let (buf, _) =
buf.split_at(core::mem::size_of::<u32>()); buf.split_at(core::mem::size_of::<u32>());
let dw = u32::from_le_bytes(buf.try_into().unwrap()); self.intern_pool.get_unsigned_integer(
ImmOrIndex::U32(dw) u32::from_le_bytes(buf.try_into().unwrap()) as u64,
)
} }
0..4 => { 0..4 => {
let (buf, _) = let (buf, _) =
buf.split_at(core::mem::size_of::<u64>()); buf.split_at(core::mem::size_of::<u64>());
let qw = u64::from_le_bytes(buf.try_into().unwrap()); self.intern_pool.get_unsigned_integer(
ImmOrIndex::U64(qw) u64::from_le_bytes(buf.try_into().unwrap()),
} )
0.. => {
let idx = self.strings.insert(bytes);
ImmOrIndex::Index(idx)
} }
0.. => self.intern_pool.insert_bytes(&bytes),
}; };
let ty = match ty { let ty = match ty {
@ -1059,8 +1061,16 @@ impl Tree {
); );
let bytes = match ty { let bytes = match ty {
FloatingType::Binary32 => ImmOrIndex::U32(bits as u32), FloatingType::Binary32 => {
FloatingType::Binary64 => ImmOrIndex::U64(bits as u64), self.intern_pool.get_or_insert(intern::Key::F32 {
bits: f32::from_bits(bits as u32),
})
}
FloatingType::Binary64 => {
self.intern_pool.get_or_insert(intern::Key::F64 {
bits: f64::from_bits(bits),
})
}
}; };
Ok(self.nodes.push_tag(Tag::Constant { Ok(self.nodes.push_tag(Tag::Constant {
@ -1210,7 +1220,7 @@ impl Tree {
pub fn get_ident_str(&self, node: Node) -> Option<&str> { pub fn get_ident_str(&self, node: Node) -> Option<&str> {
match &self.nodes[node] { match &self.nodes[node] {
Tag::Ident { name } => Some(self.strings.get_str(*name)), Tag::Ident { name } => Some(self.intern_pool.get_str(*name)),
_ => None, _ => None,
} }
} }
@ -1218,7 +1228,9 @@ impl Tree {
fn get_typename_str(&self, node: Node) -> Option<String> { fn get_typename_str(&self, node: Node) -> Option<String> {
match self.nodes.get_node(node) { match self.nodes.get_node(node) {
Tag::IntegralType(i) => Some(i.to_string()), Tag::IntegralType(i) => Some(i.to_string()),
Tag::Ident { name } => Some(self.strings.get_str(*name).to_owned()), Tag::Ident { name } => {
Some(self.intern_pool.get_str(*name).to_owned())
}
Tag::Pointer { pointee } => self.get_typename_str(*pointee), Tag::Pointer { pointee } => self.get_typename_str(*pointee),
Tag::PrimitiveType(prim) => Some(prim.to_string()), Tag::PrimitiveType(prim) => Some(prim.to_string()),
_ => None, _ => None,
@ -1429,7 +1441,7 @@ impl Tree {
writer, writer,
"%{} = identifier(\"{}\")", "%{} = identifier(\"{}\")",
node.get(), node.get(),
self.strings.get_str(name) self.intern_pool.get_str(name)
) )
} }
Tag::Block { Tag::Block {
@ -1898,10 +1910,10 @@ impl Tree {
writeln_indented!( writeln_indented!(
indent, indent,
writer, writer,
"%{} = constant{{ ty: {}, bytes: {}}}", "%{} = constant{{ ty: {}, bytes: {:?}}}",
node.get(), node.get(),
ty, ty,
self.strings.display_idx(bytes) self.intern_pool.get_key(bytes)
) )
} }
Tag::ExprStatement { expr } => { Tag::ExprStatement { expr } => {
@ -2019,12 +2031,15 @@ impl Tree {
pointee: Box::new(self.type_of_node(*pointee)), pointee: Box::new(self.type_of_node(*pointee)),
}, },
Tag::Constant { ty, .. } => ty.clone(), Tag::Constant { ty, .. } => ty.clone(),
Tag::IntegralType(t) => Type::Integer(*t), Tag::IntegralType(t) => {
Tag::PrimitiveType(t) => match t { self.intern_pool.as_ast1_type(AMD64_POINTER_BITS, *t)
PrimitiveType::FloatingType(t) => Type::Floating(*t), }
PrimitiveType::IntegralType(t) => Type::Integer(*t), Tag::PrimitiveType(t) => match *t {
PrimitiveType::Bool => Type::bool(), intern::Index::F32 => Type::Floating(FloatingType::Binary32),
PrimitiveType::Void => Type::void(), intern::Index::F64 => Type::Floating(FloatingType::Binary64),
intern::Index::BOOL => Type::Bool,
intern::Index::VOID => Type::Void,
_ => self.intern_pool.as_ast1_type(AMD64_POINTER_BITS, *t),
}, },
Tag::Block { trailing_expr, .. } => trailing_expr Tag::Block { trailing_expr, .. } => trailing_expr
.map(|n| self.type_of_node(n)) .map(|n| self.type_of_node(n))
@ -2197,45 +2212,16 @@ impl Tree {
pub fn value_of_comptime_node(&self, node: Node) -> Option<ComptimeNumber> { pub fn value_of_comptime_node(&self, node: Node) -> Option<ComptimeNumber> {
match self.nodes.get_node(node) { match self.nodes.get_node(node) {
Tag::Constant { bytes, ty } => { Tag::Constant { bytes, ty } => {
let bytes = match bytes { let ty =
ImmOrIndex::U64(v) => &v.to_le_bytes()[..], self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty);
let number =
crate::ast2::interned_type_and_value_to_comptime_number(
&self.intern_pool,
AMD64_POINTER_BITS,
ty,
*bytes,
);
ImmOrIndex::U32(v) => &v.to_le_bytes()[..],
ImmOrIndex::Index(idx) => self.strings.get_bytes(*idx),
};
let number: ComptimeNumber = match ty {
Type::Bool => (bytes[0] != 0).into(),
Type::ComptimeNumber => {
BigInt::from_bytes_le(num_bigint::Sign::Plus, bytes)
.into()
}
Type::Integer(ty) => {
if bytes.len() > core::mem::size_of::<u128>() {
let bits = BigInt::from_bytes_le(
num_bigint::Sign::Plus,
bytes,
);
(bits, *ty).into()
} else {
let mut buf = [0u8; core::mem::size_of::<u128>()];
buf[..bytes.len()].copy_from_slice(bytes);
let bits = u128::from_le_bytes(buf);
(bits, *ty).into()
}
}
Type::Floating(ty) => match ty {
FloatingType::Binary32 => (f32::from_le_bytes(
(&bytes[..4]).try_into().unwrap(),
))
.into(),
FloatingType::Binary64 => (f64::from_le_bytes(
(&bytes[..8]).try_into().unwrap(),
))
.into(),
},
_ => unimplemented!(),
};
Some(number) Some(number)
} }
Tag::Block { .. } => todo!(), Tag::Block { .. } => todo!(),
@ -2272,13 +2258,17 @@ impl Tree {
|_: &mut Tree, _| {}, |_: &mut Tree, _| {},
|tree: &mut Tree, node| { |tree: &mut Tree, node| {
if let Ok(value) = tree.fold_comptime_inner(node, false) { if let Ok(value) = tree.fold_comptime_inner(node, false) {
let (bytes, ty) = value.into_bytes_and_type(); let (value, ty) =
let idx = tree.strings.insert(bytes); crate::ast2::comptime_number_to_interned_type_and_value(
&mut tree.intern_pool,
AMD64_POINTER_BITS,
value,
);
let ty =
tree.intern_pool.as_ast1_type(AMD64_POINTER_BITS, ty);
*tree.nodes.get_node_mut(node) = Tag::Constant { *tree.nodes.get_node_mut(node) =
bytes: ImmOrIndex::Index(idx), Tag::Constant { bytes: value, ty };
ty,
};
} }
}, },
) )
@ -2293,46 +2283,16 @@ impl Tree {
if self.is_node_comptime(decl, check_declrefs) { if self.is_node_comptime(decl, check_declrefs) {
match self.nodes.get_node(decl) { match self.nodes.get_node(decl) {
Tag::Constant { bytes, ty } => { Tag::Constant { bytes, ty } => {
let bytes = match bytes { let ty =
ImmOrIndex::U64(v) => &v.to_le_bytes()[..], self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty);
let number =
crate::ast2::interned_type_and_value_to_comptime_number(
&self.intern_pool,
AMD64_POINTER_BITS,
ty,
*bytes,
);
ImmOrIndex::U32(v) => &v.to_le_bytes()[..],
ImmOrIndex::Index(idx) => self.strings.get_bytes(*idx),
};
let number: ComptimeNumber = match ty {
Type::Bool => (bytes[0] != 0).into(),
Type::ComptimeNumber => {
BigInt::from_bytes_le(num_bigint::Sign::Plus, bytes)
.into()
}
Type::Integer(ty) => {
if bytes.len() > core::mem::size_of::<u128>() {
let bits = BigInt::from_bytes_le(
num_bigint::Sign::Plus,
bytes,
);
(bits, *ty).into()
} else {
let mut buf =
[0u8; core::mem::size_of::<u128>()];
buf[..bytes.len()].copy_from_slice(bytes);
let bits = u128::from_le_bytes(buf);
(bits, *ty).into()
}
}
Type::Floating(ty) => match ty {
FloatingType::Binary32 => (f32::from_le_bytes(
(&bytes[..4]).try_into().unwrap(),
))
.into(),
FloatingType::Binary64 => (f64::from_le_bytes(
(&bytes[..8]).try_into().unwrap(),
))
.into(),
},
_ => unimplemented!(),
};
return Ok(number); return Ok(number);
} }
Tag::Negate { lhs } => { Tag::Negate { lhs } => {
@ -2515,6 +2475,20 @@ impl Tree {
} }
} }
pub fn intern_types(&mut self) {
for decl in self.global_decls.clone() {
ast::tree_visitor::Visitor::new(
decl,
|_: &mut Tree, _| {},
|tree: &mut Tree, node| {
let ty = tree.type_of_node(node);
tree.intern_pool.insert_ast1_type(AMD64_POINTER_BITS, &ty);
},
)
.visit_mut(self);
}
}
pub fn fold_comptime(&mut self) { pub fn fold_comptime(&mut self) {
for decl in self.global_decls.clone() { for decl in self.global_decls.clone() {
match self.nodes.get_node(decl) { match self.nodes.get_node(decl) {
@ -2565,9 +2539,10 @@ impl Tree {
}; };
if let Some(expr) = trailing_expr { if let Some(expr) = trailing_expr {
let ty = self.nodes.push_tag(Tag::PrimitiveType( let ty = self.nodes.push_tag(Tag::PrimitiveType(
peer_t self.intern_pool.from_ast1_type(
.as_primitive_type() AMD64_POINTER_BITS,
.expect("comptime cannot be cast into a non-primitive type"), &peer_t,
),
)); ));
let expr = self.nodes.push_tag(Tag::ExplicitCast { let expr = self.nodes.push_tag(Tag::ExplicitCast {
lhs: expr, lhs: expr,
@ -2589,7 +2564,16 @@ impl Tree {
} }
} }
Tag::Constant { bytes, ty } => { Tag::Constant { bytes, ty } => {
let bits = self.strings.count_bits(bytes); let bits = match self.intern_pool.get_key(bytes) {
intern::Key::F32 { .. } => 32,
intern::Key::F64 { .. } => 64,
intern::Key::UInt64 { bits } => bits.bits(),
intern::Key::UIntSmall { bits } => bits.bits(),
intern::Key::Bytes { bytes } => bytes.bits(),
_ => {
unreachable!()
}
};
if bits < ty.bit_width() as u32 { if bits < ty.bit_width() as u32 {
errors.push(AnalysisError::new( errors.push(AnalysisError::new(
AnalysisErrorTag::InsufficientBitsInTypeForConstant( AnalysisErrorTag::InsufficientBitsInTypeForConstant(

View file

@ -159,15 +159,17 @@ pub enum Inst {
/// list of arguments /// list of arguments
/// start, (inlinetype)end /// start, (inlinetype)end
Call(Node), Call(Node),
/// Value /// (name: intern, ty: intern)
/// lhs /// lhs: value node
GlobalConstant(StringsIndex, intern::Index), GlobalConstant(intern::Index, intern::Index),
/// u32 /// u32
ConstantU32, ConstantU32,
/// lo, hi /// lo, hi
ConstantU64, ConstantU64,
/// index /// index
ConstantMultiByte, ConstantMultiByte,
/// type, value
Constant,
/// size, align /// size, align
Alloca, Alloca,
/// src /// src
@ -233,9 +235,10 @@ pub enum Inst {
impl Inst { impl Inst {
fn is_constant(self) -> bool { fn is_constant(self) -> bool {
match self { match self {
Inst::ConstantU32 | Inst::ConstantU64 | Inst::ConstantMultiByte => { Inst::ConstantU32
true | Inst::ConstantU64
} | Inst::ConstantMultiByte
| Inst::Constant => true,
_ => false, _ => false,
} }
@ -263,11 +266,14 @@ impl Data {
fn as_u64(&self) -> u64 { fn as_u64(&self) -> u64 {
self.lhs as u64 | (self.rhs as u64) << u32::BITS as u64 self.lhs as u64 | (self.rhs as u64) << u32::BITS as u64
} }
fn as_index(&self) -> StringsIndex { fn as_index(&self) -> intern::Index {
crate::string_table::Index { intern::Index::from_u32(self.lhs)
start: self.lhs, }
end: self.rhs, fn as_index_index(&self) -> (intern::Index, intern::Index) {
} (
intern::Index::from_u32(self.lhs),
intern::Index::from_u32(self.rhs),
)
} }
fn as_lhs_rhs(&self) -> (u32, u32) { fn as_lhs_rhs(&self) -> (u32, u32) {
(self.lhs, self.rhs) (self.lhs, self.rhs)
@ -297,6 +303,24 @@ impl From<crate::string_table::ImmOrIndex> for Data {
} }
} }
impl From<intern::Index> for Data {
fn from(value: intern::Index) -> Self {
Self {
lhs: value.into_u32(),
rhs: 0,
}
}
}
impl From<(intern::Index, intern::Index)> for Data {
fn from(value: (intern::Index, intern::Index)) -> Self {
Self {
lhs: value.0.into_u32(),
rhs: value.1.into_u32(),
}
}
}
impl From<crate::string_table::Index> for Data { impl From<crate::string_table::Index> for Data {
fn from(value: crate::string_table::Index) -> Self { fn from(value: crate::string_table::Index) -> Self {
Self { Self {
@ -306,15 +330,15 @@ impl From<crate::string_table::Index> for Data {
} }
} }
pub struct IRBuilder<'tree, 'ir, 'intern> { pub struct IRBuilder<'tree, 'ir> {
ir: &'ir mut IR<'intern>, ir: &'ir mut IR,
tree: &'tree mut Tree, tree: &'tree mut Tree,
type_map: HashMap<AstNode, Type>, type_map: HashMap<AstNode, Type>,
lookup: HashMap<AstNode, NodeOrList>, lookup: HashMap<AstNode, NodeOrList>,
fixup: Vec<Node>, fixup: Vec<Node>,
} }
impl core::ops::Index<Node> for IR<'_> { impl core::ops::Index<Node> for IR {
type Output = Inst; type Output = Inst;
fn index(&self, index: Node) -> &Self::Output { fn index(&self, index: Node) -> &Self::Output {
@ -322,8 +346,8 @@ impl core::ops::Index<Node> for IR<'_> {
} }
} }
impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
fn new(ir: &'ir mut IR<'intern>, tree: &'tree mut Tree) -> Self { fn new(ir: &'ir mut IR, tree: &'tree mut Tree) -> Self {
Self { Self {
ir, ir,
tree, tree,
@ -333,6 +357,13 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
} }
} }
fn intern_pool_mut(&mut self) -> &mut InternPool {
&mut self.tree.intern_pool
}
fn intern_pool(&self) -> &InternPool {
&self.tree.intern_pool
}
fn peer_type_of_nodes(&self, lhs: AstNode, rhs: AstNode) -> Option<Type> { fn peer_type_of_nodes(&self, lhs: AstNode, rhs: AstNode) -> Option<Type> {
let lty = self.tree.type_of_node(lhs); let lty = self.tree.type_of_node(lhs);
let rty = self.tree.type_of_node(rhs); let rty = self.tree.type_of_node(rhs);
@ -396,8 +427,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let size = ty.size_of(); let size = ty.size_of();
let align = ty.align_of(); let align = ty.align_of();
let ty = self let ty = self
.ir .intern_pool()
.intern_pool
.from_ast1_type(AMD64_POINTER_BITS, &ty); .from_ast1_type(AMD64_POINTER_BITS, &ty);
let ir = self.ir.push( let ir = self.ir.push(
Inst::Parameter(ty), Inst::Parameter(ty),
@ -414,8 +444,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
if value != !0 { if value != !0 {
let ty = self.tree.type_of_node(*body); let ty = self.tree.type_of_node(*body);
let ty = self let ty = self
.ir .intern_pool()
.intern_pool
.from_ast1_type(AMD64_POINTER_BITS, &ty); .from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir.push( self.ir.push(
Inst::ReturnValue(ty.into()), Inst::ReturnValue(ty.into()),
@ -441,8 +470,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let start = self.ir.nodes.len(); let start = self.ir.nodes.len();
for (arg, ty) in args { for (arg, ty) in args {
let ty = self let ty = self
.ir .intern_pool()
.intern_pool
.from_ast1_type(AMD64_POINTER_BITS, &ty); .from_ast1_type(AMD64_POINTER_BITS, &ty);
_ = self.ir.push( _ = self.ir.push(
Inst::Argument(ty.into()), Inst::Argument(ty.into()),
@ -461,7 +489,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
)); ));
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir.push(Inst::InlineType(ty.into()), None); self.ir.push(Inst::InlineType(ty.into()), None);
let func = self.visit(*lhs); let func = self.visit(*lhs);
@ -490,7 +518,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
Some(Data::new(ty.size_of(), ty.align_of())), Some(Data::new(ty.size_of(), ty.align_of())),
); );
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
if let Some(assignment) = assignment { if let Some(assignment) = assignment {
let value = self.visit(*assignment); let value = self.visit(*assignment);
@ -513,7 +541,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
variant!(self.tree.nodes.get_node(*name) => Tag::Ident { name }); variant!(self.tree.nodes.get_node(*name) => Tag::Ident { name });
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
let global = self.ir.push( let global = self.ir.push(
Inst::GlobalConstant(*name, ty.into()), Inst::GlobalConstant(*name, ty.into()),
Some(Data::lhs(value)), Some(Data::lhs(value)),
@ -526,7 +554,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
Tag::GlobalRef(decl) => { Tag::GlobalRef(decl) => {
let ty = self.tree.type_of_node(*decl); let ty = self.tree.type_of_node(*decl);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
let node = self.ir.push( let node = self.ir.push(
Inst::ExternRef(ty.into()), Inst::ExternRef(ty.into()),
Some(Data::lhs(decl.get())), Some(Data::lhs(decl.get())),
@ -548,7 +576,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let source = self.visit(*rhs); let source = self.visit(*rhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir self.ir
.push(Inst::Store(ty.into()), Some(Data::new(source, dest))) .push(Inst::Store(ty.into()), Some(Data::new(source, dest)))
} }
@ -556,8 +584,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
if let Some(expr) = expr { if let Some(expr) = expr {
let ty = self.tree.type_of_node(*expr); let ty = self.tree.type_of_node(*expr);
let ty = self let ty = self
.ir .intern_pool()
.intern_pool
.from_ast1_type(AMD64_POINTER_BITS, &ty); .from_ast1_type(AMD64_POINTER_BITS, &ty);
let expr = self.visit(*expr); let expr = self.visit(*expr);
self.ir.push( self.ir.push(
@ -574,7 +601,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
self.tree.type_of_node(*lhs).pointee().unwrap().clone(); self.tree.type_of_node(*lhs).pointee().unwrap().clone();
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs))) self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs)))
} }
Tag::Add { lhs, rhs } => { Tag::Add { lhs, rhs } => {
@ -582,7 +609,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let rhs = self.visit(*rhs); let rhs = self.visit(*rhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir self.ir
.push(Inst::Add(ty.into()), Some(Data::new(lhs, rhs))) .push(Inst::Add(ty.into()), Some(Data::new(lhs, rhs)))
} }
@ -591,7 +618,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let rhs = self.visit(*rhs); let rhs = self.visit(*rhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir self.ir
.push(Inst::Sub(ty.into()), Some(Data::new(lhs, rhs))) .push(Inst::Sub(ty.into()), Some(Data::new(lhs, rhs)))
} }
@ -600,7 +627,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let rhs = self.visit(*rhs); let rhs = self.visit(*rhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir self.ir
.push(Inst::BitAnd(ty.into()), Some(Data::new(lhs, rhs))) .push(Inst::BitAnd(ty.into()), Some(Data::new(lhs, rhs)))
} }
@ -609,7 +636,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let rhs = self.visit(*rhs); let rhs = self.visit(*rhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir self.ir
.push(Inst::BitOr(ty.into()), Some(Data::new(lhs, rhs))) .push(Inst::BitOr(ty.into()), Some(Data::new(lhs, rhs)))
} }
@ -618,7 +645,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let rhs = self.visit(*rhs); let rhs = self.visit(*rhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir self.ir
.push(Inst::BitXOr(ty.into()), Some(Data::new(lhs, rhs))) .push(Inst::BitXOr(ty.into()), Some(Data::new(lhs, rhs)))
} }
@ -639,7 +666,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
.into(); .into();
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
let inst = match tag { let inst = match tag {
Tag::Eq { .. } => Inst::Eq(ty), Tag::Eq { .. } => Inst::Eq(ty),
Tag::NEq { .. } => Inst::Neq(ty), Tag::NEq { .. } => Inst::Neq(ty),
@ -659,7 +686,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let rhs = self.visit(*rhs); let rhs = self.visit(*rhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir self.ir
.push(Inst::Mul(ty.into()), Some(Data::new(lhs, rhs))) .push(Inst::Mul(ty.into()), Some(Data::new(lhs, rhs)))
} }
@ -667,14 +694,14 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let ty = self.tree.type_of_node(node); let ty = self.tree.type_of_node(node);
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir.push(Inst::Negate(ty.into()), Some(Data::lhs(lhs))) self.ir.push(Inst::Negate(ty.into()), Some(Data::lhs(lhs)))
} }
Tag::Not { lhs } => { Tag::Not { lhs } => {
let ty = self.tree.type_of_node(node); let ty = self.tree.type_of_node(node);
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir.push(Inst::Not(ty.into()), Some(Data::lhs(lhs))) self.ir.push(Inst::Not(ty.into()), Some(Data::lhs(lhs)))
} }
Tag::Shl { lhs, rhs } => { Tag::Shl { lhs, rhs } => {
@ -682,7 +709,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let rhs = self.visit(*rhs); let rhs = self.visit(*rhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir self.ir
.push(Inst::ShiftLeft(ty.into()), Some(Data::new(lhs, rhs))) .push(Inst::ShiftLeft(ty.into()), Some(Data::new(lhs, rhs)))
} }
@ -691,7 +718,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let lhs = self.visit(*lhs); let lhs = self.visit(*lhs);
let rhs = self.visit(*rhs); let rhs = self.visit(*rhs);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir.push( self.ir.push(
Inst::ShiftRight(ty.into()), Inst::ShiftRight(ty.into()),
Some(Data::new(lhs, rhs)), Some(Data::new(lhs, rhs)),
@ -703,23 +730,17 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
// self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs))) // self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs)))
// nothing happens here because lhs is of type pointer // nothing happens here because lhs is of type pointer
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
self.ir.push( self.ir.push(
Inst::GetElementPtr(ty.into()), Inst::GetElementPtr(ty.into()),
Some(Data::new(lhs, 0)), Some(Data::new(lhs, 0)),
) )
} }
Tag::Constant { bytes, .. } => match bytes { Tag::Constant { bytes, ty } => {
ImmOrIndex::U64(v) => { let ty =
self.ir.push(Inst::ConstantU64, Some((*v).into())) self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, ty);
} self.ir.push(Inst::Constant, Some((ty, *bytes).into()))
ImmOrIndex::U32(v) => { }
self.ir.push(Inst::ConstantU32, Some((*v).into()))
}
ImmOrIndex::Index(idx) => {
self.ir.push(Inst::ConstantMultiByte, Some((*idx).into()))
}
},
Tag::ExplicitCast { lhs, typename } => { Tag::ExplicitCast { lhs, typename } => {
let l_ty = self.tree.type_of_node(*lhs).clone(); let l_ty = self.tree.type_of_node(*lhs).clone();
let r_ty = self.tree.type_of_node(*typename).clone(); let r_ty = self.tree.type_of_node(*typename).clone();
@ -731,12 +752,10 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
lhs lhs
} else { } else {
let l_ty = self let l_ty = self
.ir .intern_pool()
.intern_pool
.from_ast1_type(AMD64_POINTER_BITS, &l_ty); .from_ast1_type(AMD64_POINTER_BITS, &l_ty);
let r_ty = self let r_ty = self
.ir .intern_pool()
.intern_pool
.from_ast1_type(AMD64_POINTER_BITS, &r_ty); .from_ast1_type(AMD64_POINTER_BITS, &r_ty);
self.ir.push( self.ir.push(
Inst::ExplicitCast(l_ty.into(), r_ty.into()), Inst::ExplicitCast(l_ty.into(), r_ty.into()),
@ -750,14 +769,16 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
let condition = self.visit(*condition); let condition = self.visit(*condition);
let br = self.ir.push(Inst::Branch(condition), None); let br = self.ir.push(Inst::Branch(condition), None);
let label_lhs = self let label_lhs = self.ir.push(
.ir Inst::Label,
.push(Inst::Label, Some(StringsIndex::none().into())); Some(intern::Index::EMPTY_STRING.into()),
);
let _ = self.visit(*body); let _ = self.visit(*body);
let jmp = self.ir.push(Inst::Jump, None); let jmp = self.ir.push(Inst::Jump, None);
let nojump = self let nojump = self.ir.push(
.ir Inst::Label,
.push(Inst::Label, Some(StringsIndex::none().into())); Some(intern::Index::EMPTY_STRING.into()),
);
self.ir.data[br as usize] = Some(Data::new(label_lhs, nojump)); self.ir.data[br as usize] = Some(Data::new(label_lhs, nojump));
self.ir.data[jmp as usize] = Some(Data::lhs(nojump)); self.ir.data[jmp as usize] = Some(Data::lhs(nojump));
@ -771,26 +792,29 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
assert_eq!(self.tree.type_of_node(*condition), Type::Bool); assert_eq!(self.tree.type_of_node(*condition), Type::Bool);
let ty = self.tree.peer_type_of_nodes_unwrap(*body, *else_expr); let ty = self.tree.peer_type_of_nodes_unwrap(*body, *else_expr);
let ty = let ty =
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
let condition = self.visit(*condition); let condition = self.visit(*condition);
let br = self.ir.push(Inst::Branch(condition), None); let br = self.ir.push(Inst::Branch(condition), None);
let label_lhs = self let label_lhs = self.ir.push(
.ir Inst::Label,
.push(Inst::Label, Some(StringsIndex::none().into())); Some(intern::Index::EMPTY_STRING.into()),
);
let lhs = self.visit(*body); let lhs = self.visit(*body);
let ljmp = self.ir.push(Inst::Jump, None); let ljmp = self.ir.push(Inst::Jump, None);
let label_rhs = self let label_rhs = self.ir.push(
.ir Inst::Label,
.push(Inst::Label, Some(StringsIndex::none().into())); Some(intern::Index::EMPTY_STRING.into()),
);
let rhs = self.visit(*else_expr); let rhs = self.visit(*else_expr);
let rjmp = self.ir.push(Inst::Jump, None); let rjmp = self.ir.push(Inst::Jump, None);
let nojump = self let nojump = self.ir.push(
.ir Inst::Label,
.push(Inst::Label, Some(StringsIndex::none().into())); Some(intern::Index::EMPTY_STRING.into()),
let phi = if ty != self.ir.intern_pool.get_void_type() { );
let phi = if ty != intern::Index::VOID {
self.ir.push(Inst::Phi2(ty), Some(Data::new(lhs, rhs))) self.ir.push(Inst::Phi2(ty), Some(Data::new(lhs, rhs)))
} else { } else {
br br
@ -810,16 +834,15 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
} }
} }
pub struct IR<'a> { pub struct IR {
nodes: Vec<Inst>, nodes: Vec<Inst>,
data: Vec<Option<Data>>, data: Vec<Option<Data>>,
intern_pool: &'a mut InternPool, // intern_pool: &'a mut InternPool,
} }
impl<'a> IR<'a> { impl IR {
pub fn new(intern_pool: &'a mut InternPool) -> Self { pub fn new() -> Self {
Self { Self {
intern_pool,
nodes: Vec::new(), nodes: Vec::new(),
data: Vec::new(), data: Vec::new(),
} }
@ -834,10 +857,7 @@ impl<'a> IR<'a> {
pub fn build<'b, 'tree>( pub fn build<'b, 'tree>(
&'b mut self, &'b mut self,
tree: &'tree mut Tree, tree: &'tree mut Tree,
) -> IRBuilder<'tree, 'b, 'a> ) -> IRBuilder<'tree, 'b> {
where
'a: 'b,
{
let global_decls = tree.global_decls.clone(); let global_decls = tree.global_decls.clone();
let mut builder = IRBuilder::new(self, tree); let mut builder = IRBuilder::new(self, tree);
@ -873,7 +893,7 @@ impl<'a> IR<'a> {
} }
} }
impl IRBuilder<'_, '_, '_> { impl IRBuilder<'_, '_> {
fn render_node<W: core::fmt::Write>( fn render_node<W: core::fmt::Write>(
&self, &self,
w: &mut W, w: &mut W,
@ -886,7 +906,7 @@ impl IRBuilder<'_, '_, '_> {
let inst = self.ir.nodes[node as usize]; let inst = self.ir.nodes[node as usize];
match inst { match inst {
Inst::Label => { Inst::Label => {
let label = self.tree.strings.get_str(data.as_index()); let label = self.intern_pool().get_str(data.as_index());
writeln_indented!( writeln_indented!(
indent - 1, indent - 1,
w, w,
@ -895,7 +915,7 @@ impl IRBuilder<'_, '_, '_> {
)?; )?;
} }
Inst::FunctionStart => { Inst::FunctionStart => {
let label = self.tree.strings.get_str(data.as_index()); let label = self.intern_pool().get_str(data.as_index());
writeln_indented!(indent - 1, w, "%{} = func {label}:", node)?; writeln_indented!(indent - 1, w, "%{} = func {label}:", node)?;
} }
Inst::FunctionEnd => { Inst::FunctionEnd => {
@ -931,6 +951,17 @@ impl IRBuilder<'_, '_, '_> {
} }
writeln_indented!(indent, w, ")")?; writeln_indented!(indent, w, ")")?;
} }
Inst::Constant => {
let (ty, val) = data.as_index_index();
writeln_indented!(
indent,
w,
"%{} = const {} {}",
node,
self.intern_pool().display_key(ty),
self.intern_pool().display_key(val),
)?;
}
Inst::ConstantU32 => { Inst::ConstantU32 => {
writeln_indented!( writeln_indented!(
indent, indent,
@ -950,7 +981,7 @@ impl IRBuilder<'_, '_, '_> {
)?; )?;
} }
Inst::ConstantMultiByte => { Inst::ConstantMultiByte => {
let value = self.tree.strings.get_bytes(data.as_index()); let value = self.intern_pool().get_bytes(data.as_index());
writeln_indented!( writeln_indented!(
indent, indent,
w, w,
@ -1159,8 +1190,9 @@ impl IRBuilder<'_, '_, '_> {
writeln_indented!( writeln_indented!(
indent, indent,
w, w,
"%{node} = extern reference {ty} '{}'", "%{node} = extern ref {} '{}'",
self.tree.strings.get_str(idx) self.intern_pool().display_key(ty),
self.intern_pool().get_str(idx)
)?; )?;
} }
Inst::Branch(condition) => { Inst::Branch(condition) => {
@ -1184,7 +1216,7 @@ impl IRBuilder<'_, '_, '_> {
)?; )?;
} }
Inst::GlobalConstant(name, ty) => { Inst::GlobalConstant(name, ty) => {
let label = self.tree.strings.get_str(name); let label = self.intern_pool().get_str(name);
let value = data.lhs; let value = data.lhs;
writeln_indented!( writeln_indented!(
indent, indent,
@ -1207,18 +1239,18 @@ impl IRBuilder<'_, '_, '_> {
} }
} }
struct IRIter<'a, 'b> { struct IRIter<'a> {
ir: &'a IR<'b>, ir: &'a IR,
offset: usize, offset: usize,
item: Option<(Inst, Option<Data>)>, item: Option<(Inst, Option<Data>)>,
} }
impl IRIter<'_, '_> { impl IRIter<'_> {
fn node(&self) -> u32 { fn node(&self) -> u32 {
self.offset as Node self.offset as Node
} }
} }
impl Iterator for IRIter<'_, '_> { impl Iterator for IRIter<'_> {
type Item = (Inst, Option<Data>); type Item = (Inst, Option<Data>);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -1232,23 +1264,25 @@ impl Iterator for IRIter<'_, '_> {
use crate::mir; use crate::mir;
pub struct MirBuilder<'a, 'b> { pub struct MirBuilder<'a> {
ir: IRIter<'a, 'b>, ir: IRIter<'a>,
pub strings: StringTable, pub intern_pool: intern::InternPool,
pub functions: HashMap<StringsIndex, mir::Mir>, pub functions: HashMap<intern::Index, mir::Mir>,
pub globals: HashMap<StringsIndex, mir::Mir>, pub globals: HashMap<intern::Index, mir::Mir>,
} }
struct IrToMirMapping<'a> { struct IrToMirMapping<'a> {
ir: &'a IR<'a>, ir: &'a IR,
mapping: BTreeMap<Node, mir::NodeRef>, mapping: BTreeMap<Node, mir::NodeRef>,
ip: &'a intern::InternPool,
} }
impl<'a> IrToMirMapping<'a> { impl<'a> IrToMirMapping<'a> {
fn new(ir: &'a IR) -> Self { fn new(ir: &'a IR, ip: &'a intern::InternPool) -> Self {
Self { Self {
ir, ir,
mapping: BTreeMap::new(), mapping: BTreeMap::new(),
ip,
} }
} }
fn insert(&mut self, ir: Node, mir: mir::NodeRef) { fn insert(&mut self, ir: Node, mir: mir::NodeRef) {
@ -1265,10 +1299,7 @@ impl<'a> IrToMirMapping<'a> {
eprintln!( eprintln!(
"does this even get hit anymore???????????????????//" "does this even get hit anymore???????????????????//"
); );
let ty = self let ty = self.ip.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let ext = mir::NodeRef(mir.gen_extern(Some(ty), name)); let ext = mir::NodeRef(mir.gen_extern(Some(ty), name));
self.insert(ir, ext); self.insert(ir, ext);
Some(ext) Some(ext)
@ -1278,23 +1309,30 @@ impl<'a> IrToMirMapping<'a> {
} }
} }
impl<'a, 'b> MirBuilder<'a, 'b> { impl<'a> MirBuilder<'a> {
pub fn new(ir: &'a IR<'b>, strings: StringTable) -> MirBuilder<'a, 'b> { pub fn new(ir: &'a IR, intern_pool: intern::InternPool) -> MirBuilder<'a> {
Self { Self {
ir: IRIter { ir: IRIter {
ir, ir,
offset: 0, offset: 0,
item: None, item: None,
}, },
strings, intern_pool,
functions: HashMap::new(), functions: HashMap::new(),
globals: HashMap::new(), globals: HashMap::new(),
} }
} }
fn build_function(&mut self, name: StringsIndex) { fn intern_pool(&self) -> &intern::InternPool {
&self.intern_pool
}
fn intern_pool_mut(&mut self) -> &mut intern::InternPool {
&mut self.intern_pool
}
fn build_function(&mut self, name: intern::Index) {
let mut mir = mir::Mir::new(name); let mut mir = mir::Mir::new(name);
let mut mapping = IrToMirMapping::new(&self.ir.ir); let mut mapping = IrToMirMapping::new(&self.ir.ir, &self.intern_pool);
// map of label -> unresolved mir jump or branch instruction // map of label -> unresolved mir jump or branch instruction
// stored as a tree of (label, unresolved) // stored as a tree of (label, unresolved)
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
@ -1371,6 +1409,13 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
label label
} }
Inst::Constant => {
let (ty, val) = data.unwrap().as_index_index();
let mir_ty = self
.intern_pool()
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
mir.push_const(val, mir_ty)
}
Inst::ConstantU32 => mir.push( Inst::ConstantU32 => mir.push(
mir::Inst::ConstantDWord, mir::Inst::ConstantDWord,
mir::Data::imm32(data.unwrap().as_u32()), mir::Data::imm32(data.unwrap().as_u32()),
@ -1381,7 +1426,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
), ),
Inst::ConstantMultiByte => { Inst::ConstantMultiByte => {
let bytes = let bytes =
self.strings.get_bytes(data.unwrap().as_index()); self.intern_pool().get_bytes(data.unwrap().as_index());
let mut buf = [0u8; 8]; let mut buf = [0u8; 8];
match bytes.len() { match bytes.len() {
1 => mir.gen_u8(bytes[0]), 1 => mir.gen_u8(bytes[0]),
@ -1413,9 +1458,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
} }
Inst::Load(ty) => { Inst::Load(ty) => {
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let src = mapping let src = mapping
.get(&mut mir, data.unwrap().as_u32()) .get(&mut mir, data.unwrap().as_u32())
@ -1425,9 +1468,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
} }
Inst::Store(ty) => { Inst::Store(ty) => {
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let (src, dst) = data.unwrap().as_lhs_rhs(); let (src, dst) = data.unwrap().as_lhs_rhs();
let src = mapping.get(&mut mir, src).unwrap().0; let src = mapping.get(&mut mir, src).unwrap().0;
@ -1436,9 +1477,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
} }
Inst::GetElementPtr(ty) => { Inst::GetElementPtr(ty) => {
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let (ptr, idx) = data.unwrap().as_lhs_rhs(); let (ptr, idx) = data.unwrap().as_lhs_rhs();
let src = mapping.get(&mut mir, ptr).unwrap().0; let src = mapping.get(&mut mir, ptr).unwrap().0;
@ -1447,9 +1486,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
Inst::Parameter(ty) => { Inst::Parameter(ty) => {
// let (size, _) = data.unwrap().as_lhs_rhs(); // let (size, _) = data.unwrap().as_lhs_rhs();
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
mir.gen_param(ty.into()) mir.gen_param(ty.into())
} }
@ -1475,14 +1512,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
}; };
let signed = self let signed = self
.ir .intern_pool()
.ir
.intern_pool
.is_type_signed(ty, AMD64_POINTER_TYPE_INFO); .is_type_signed(ty, AMD64_POINTER_TYPE_INFO);
let mir_ty = self let mir_ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
mir.gen_cmp_byte(mir_ty, signed, ord, invert, lhs, rhs) mir.gen_cmp_byte(mir_ty, signed, ord, invert, lhs, rhs)
} }
@ -1492,14 +1525,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let rhs = mapping.get(&mut mir, dst).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0;
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
match info.bitsize { match info.bitsize {
@ -1524,14 +1553,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let rhs = mapping.get(&mut mir, dst).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0;
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1547,14 +1572,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let (lhs, rhs) = data.unwrap().as_lhs_rhs();
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1573,14 +1594,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let (lhs, rhs) = data.unwrap().as_lhs_rhs();
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1599,14 +1616,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let (lhs, rhs) = data.unwrap().as_lhs_rhs();
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1625,14 +1638,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let (lhs, rhs) = data.unwrap().as_lhs_rhs();
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1658,14 +1667,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let (lhs, rhs) = data.unwrap().as_lhs_rhs();
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1701,14 +1706,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let rhs = mapping.get(&mut mir, rhs).unwrap().0; let rhs = mapping.get(&mut mir, rhs).unwrap().0;
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1726,14 +1727,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let rhs = mapping.get(&mut mir, dst).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0;
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1755,14 +1752,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let rhs = mapping.get(&mut mir, dst).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0;
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1783,14 +1776,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let lhs = mapping.get(&mut mir, lhs).unwrap().0; let lhs = mapping.get(&mut mir, lhs).unwrap().0;
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1807,14 +1796,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let lhs = mapping.get(&mut mir, lhs).unwrap().0; let lhs = mapping.get(&mut mir, lhs).unwrap().0;
let info = self let info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(ty, AMD64_POINTER_TYPE_INFO); .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let unalignment = let unalignment =
mir_unalignment(info.signed, info.bitsize); mir_unalignment(info.signed, info.bitsize);
@ -1831,27 +1816,19 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let lhs = mapping.get(&mut mir, lhs).unwrap().0; let lhs = mapping.get(&mut mir, lhs).unwrap().0;
let to_info = self let to_info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(to, AMD64_POINTER_TYPE_INFO); .size_of_type(to, AMD64_POINTER_TYPE_INFO);
let to_ty = self let to_ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(to, AMD64_POINTER_TYPE_INFO); .to_mir_type(to, AMD64_POINTER_TYPE_INFO);
let to_unalignment = let to_unalignment =
mir_unalignment(to_info.signed, to_info.bitsize); mir_unalignment(to_info.signed, to_info.bitsize);
let from_info = self let from_info = self
.ir .intern_pool()
.ir
.intern_pool
.size_of_type(from, AMD64_POINTER_TYPE_INFO); .size_of_type(from, AMD64_POINTER_TYPE_INFO);
let from_ty = self let from_ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(from, AMD64_POINTER_TYPE_INFO); .to_mir_type(from, AMD64_POINTER_TYPE_INFO);
let from_unalignment = let from_unalignment =
mir_unalignment(from_info.signed, from_info.bitsize); mir_unalignment(from_info.signed, from_info.bitsize);
@ -1890,9 +1867,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let src = mapping.get(&mut mir, src).unwrap().0; let src = mapping.get(&mut mir, src).unwrap().0;
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
mir.gen_ret_val(ty, src) mir.gen_ret_val(ty, src)
@ -1963,18 +1938,14 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
variant!(&ir.nodes[end as usize -1] => Inst::InlineType(ty)); variant!(&ir.nodes[end as usize -1] => Inst::InlineType(ty));
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(*ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
let args = (start..(end - 1)) let args = (start..(end - 1))
.map(|arg| { .map(|arg| {
variant!(&ir.nodes[arg as usize] => Inst::Argument(ty)); variant!(&ir.nodes[arg as usize] => Inst::Argument(ty));
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(*ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
let arg = ir.data[arg as usize].unwrap().lhs; let arg = ir.data[arg as usize].unwrap().lhs;
let arg = mapping.get(&mut mir, arg).unwrap().0; let arg = mapping.get(&mut mir, arg).unwrap().0;
@ -1989,18 +1960,14 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let lhs = mapping.get(&mut mir, src).unwrap().0; let lhs = mapping.get(&mut mir, src).unwrap().0;
let rhs = mapping.get(&mut mir, dst).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0;
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
mir.gen_phi2(ty, lhs, rhs) mir.gen_phi2(ty, lhs, rhs)
} }
Inst::GlobalConstant(name, ty) => { Inst::GlobalConstant(name, ty) => {
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
let ext = mir.gen_extern(Some(ty), name); let ext = mir.gen_extern(Some(ty), name);
@ -2011,9 +1978,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
} }
Inst::ExternRef(ty) => { Inst::ExternRef(ty) => {
let ty = self let ty = self
.ir .intern_pool()
.ir
.intern_pool
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
mir.gen_extern(Some(ty), data.unwrap().as_index()) mir.gen_extern(Some(ty), data.unwrap().as_index())
} }
@ -2047,6 +2012,13 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
let data = self.ir.ir.data[value as usize]; let data = self.ir.ir.data[value as usize];
let inst = self.ir.ir.nodes[value as usize]; let inst = self.ir.ir.nodes[value as usize];
let _value = match inst { let _value = match inst {
Inst::Constant => {
let (ty, val) = data.unwrap().as_index_index();
let mir_ty = self
.intern_pool()
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
mir.push_const(val, mir_ty)
}
Inst::ConstantU32 => mir.push( Inst::ConstantU32 => mir.push(
mir::Inst::ConstantDWord, mir::Inst::ConstantDWord,
mir::Data::imm32(data.unwrap().as_u32()), mir::Data::imm32(data.unwrap().as_u32()),
@ -2057,7 +2029,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
), ),
Inst::ConstantMultiByte => { Inst::ConstantMultiByte => {
let bytes = self let bytes = self
.strings .intern_pool()
.get_bytes(data.unwrap().as_index()); .get_bytes(data.unwrap().as_index());
let mut buf = [0u8; 8]; let mut buf = [0u8; 8];
match bytes.len() { match bytes.len() {
@ -2121,7 +2093,7 @@ fn u10(x: i10) -> i10 {
println!("AST:\n{buf}"); println!("AST:\n{buf}");
let mut intern = InternPool::new(); let mut intern = InternPool::new();
let mut ir = IR::new(&mut intern); let mut ir = IR::new();
{ {
let builder = ir.build(&mut tree); let builder = ir.build(&mut tree);
let mut buf = String::new(); let mut buf = String::new();
@ -2129,7 +2101,7 @@ fn u10(x: i10) -> i10 {
println!("IR:\n{buf}"); println!("IR:\n{buf}");
} }
let mut mir = MirBuilder::new(&ir, tree.strings); let mut mir = MirBuilder::new(&ir, tree.intern_pool);
mir.build(); mir.build();
} }
} }

View file

@ -2,4 +2,4 @@ fn main() -> i32 {
return RANDOM; return RANDOM;
} }
const RANDOM: i32 = 4 + (1 << 3); const RANDOM: i32 = 4i32 + (1i32 << 3i32);