fixing float conversion constant folding
This commit is contained in:
parent
bedffa9b32
commit
63a1c7feb4
|
@ -267,7 +267,7 @@ impl TokenKind {
|
||||||
Self::Float => (value as f64).to_bits() as _,
|
Self::Float => (value as f64).to_bits() as _,
|
||||||
Self::Number => {
|
Self::Number => {
|
||||||
debug_assert!(float);
|
debug_assert!(float);
|
||||||
f64::from_bits(value as _).to_bits() as _
|
f64::from_bits(value as _) as _
|
||||||
}
|
}
|
||||||
s => todo!("{s}"),
|
s => todo!("{s}"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2321,7 +2321,7 @@ impl<'a> Codegen<'a> {
|
||||||
{
|
{
|
||||||
panic!("{e} {}", vc);
|
panic!("{e} {}", vc);
|
||||||
} else {
|
} else {
|
||||||
log::trace!("{}", vc);
|
log::info!("{}", vc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4579,7 +4579,7 @@ mod tests {
|
||||||
fn generate(ident: &'static str, input: &'static str, output: &mut String) {
|
fn generate(ident: &'static str, input: &'static str, output: &mut String) {
|
||||||
_ = log::set_logger(&crate::fs::Logger);
|
_ = log::set_logger(&crate::fs::Logger);
|
||||||
log::set_max_level(log::LevelFilter::Info);
|
log::set_max_level(log::LevelFilter::Info);
|
||||||
// log::set_max_level(log::LevelFilter::Trace);
|
//log::set_max_level(log::LevelFilter::Trace);
|
||||||
|
|
||||||
let mut ctx = CodegenCtx::default();
|
let mut ctx = CodegenCtx::default();
|
||||||
let (ref files, embeds) = crate::test_parse_files(ident, input, &mut ctx.parser);
|
let (ref files, embeds) = crate::test_parse_files(ident, input, &mut ctx.parser);
|
||||||
|
|
|
@ -10,7 +10,7 @@ use {
|
||||||
Offset, PLoc, Reloc, Sig, TypedReloc, Types,
|
Offset, PLoc, Reloc, Sig, TypedReloc, Types,
|
||||||
},
|
},
|
||||||
alloc::{borrow::ToOwned, vec::Vec},
|
alloc::{borrow::ToOwned, vec::Vec},
|
||||||
core::{mem, ops::Range},
|
core::{mem, ops::Range, u32, usize},
|
||||||
hbbytecode::{self as instrs},
|
hbbytecode::{self as instrs},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ impl HbvmBackend {
|
||||||
self.emit(instrs::st(reg::RET_ADDR + fuc.tail as u8, reg::STACK_PTR, 0, 0));
|
self.emit(instrs::st(reg::RET_ADDR + fuc.tail as u8, reg::STACK_PTR, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.node_to_reg[MEM as usize] = res.bundles.len() as u8 + 1;
|
||||||
|
|
||||||
let reg_offset = if fuc.tail { reg::RET + 12 } else { reg::RET_ADDR + 1 };
|
let reg_offset = if fuc.tail { reg::RET + 12 } else { reg::RET_ADDR + 1 };
|
||||||
|
|
||||||
res.node_to_reg.iter_mut().filter(|r| **r != 0).for_each(|r| {
|
res.node_to_reg.iter_mut().filter(|r| **r != 0).for_each(|r| {
|
||||||
|
@ -82,6 +84,7 @@ impl HbvmBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = &fuc.nodes[nid];
|
let node = &fuc.nodes[nid];
|
||||||
|
let bref = mem::replace(&mut fuc.backrefs[nid as usize], u16::MAX);
|
||||||
|
|
||||||
let extend = |base: ty::Id, dest: ty::Id, from: Nid, to: Nid| {
|
let extend = |base: ty::Id, dest: ty::Id, from: Nid, to: Nid| {
|
||||||
let (bsize, dsize) = (tys.size_of(base), tys.size_of(dest));
|
let (bsize, dsize) = (tys.size_of(base), tys.size_of(dest));
|
||||||
|
@ -114,50 +117,98 @@ impl HbvmBackend {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
self.emit(extend(fuc.nodes[lhs].ty, fuc.nodes[lhs].ty.extend(), 0, 0));
|
self.emit(extend(
|
||||||
self.emit(extend(fuc.nodes[rhs].ty, fuc.nodes[rhs].ty.extend(), 1, 1));
|
fuc.nodes[lhs].ty,
|
||||||
|
fuc.nodes[lhs].ty.extend(),
|
||||||
|
lhs,
|
||||||
|
lhs,
|
||||||
|
));
|
||||||
|
self.emit(extend(
|
||||||
|
fuc.nodes[rhs].ty,
|
||||||
|
fuc.nodes[rhs].ty.extend(),
|
||||||
|
rhs,
|
||||||
|
rhs,
|
||||||
|
));
|
||||||
|
|
||||||
let rel = Reloc::new(self.code.len(), 3, 2);
|
let rel = Reloc::new(self.code.len(), 3, 2);
|
||||||
self.jump_relocs.push((node.outputs[!swapped as usize], rel));
|
self.jump_relocs.push((node.outputs[!swapped as usize], rel));
|
||||||
self.emit(op(atr(lhs), atr(rhs), 0));
|
self.emit(op(atr(lhs), atr(rhs), 0));
|
||||||
} else {
|
} else {
|
||||||
self.emit(extend(fuc.nodes[cnd].ty, fuc.nodes[cnd].ty.extend(), 0, 0));
|
self.emit(extend(
|
||||||
|
fuc.nodes[cnd].ty,
|
||||||
|
fuc.nodes[cnd].ty.extend(),
|
||||||
|
cnd,
|
||||||
|
cnd,
|
||||||
|
));
|
||||||
let rel = Reloc::new(self.code.len(), 3, 2);
|
let rel = Reloc::new(self.code.len(), 3, 2);
|
||||||
self.jump_relocs.push((node.outputs[0], rel));
|
self.jump_relocs.push((node.outputs[0], rel));
|
||||||
self.emit(instrs::jne(atr(cnd), reg::ZERO, 0));
|
self.emit(instrs::jne(atr(cnd), reg::ZERO, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Loop | Kind::Region => {
|
Kind::Loop | Kind::Region => {
|
||||||
if (mem::replace(&mut fuc.backrefs[nid as usize], u16::MAX) != u16::MAX)
|
let mut emit_moves = |index| {
|
||||||
^ (node.kind == Kind::Loop)
|
let mut moves = vec![];
|
||||||
{
|
|
||||||
let index = (node.kind == Kind::Loop) as usize + 1;
|
|
||||||
for &out in node.outputs.iter() {
|
for &out in node.outputs.iter() {
|
||||||
if fuc.nodes[out].is_data_phi()
|
if fuc.nodes[out].is_data_phi() {
|
||||||
&& atr(out) != atr(fuc.nodes[out].inputs[index])
|
debug_assert_eq!(
|
||||||
{
|
fuc.backrefs[fuc.nodes[out].inputs[index] as usize],
|
||||||
self.emit(instrs::cp(
|
u16::MAX,
|
||||||
atr(out),
|
"{:?}\n{:?}",
|
||||||
atr(fuc.nodes[out].inputs[index]),
|
node,
|
||||||
));
|
fuc.nodes[fuc.nodes[out].inputs[index]]
|
||||||
|
);
|
||||||
|
if atr(out) != atr(fuc.nodes[out].inputs[index]) {
|
||||||
|
if atr(out) == 34 && atr(fuc.nodes[out].inputs[index]) == 32
|
||||||
|
{
|
||||||
|
std::dbg!(&node, out, &fuc.nodes[out]);
|
||||||
|
}
|
||||||
|
moves.push([
|
||||||
|
atr(out),
|
||||||
|
atr(fuc.nodes[out].inputs[index]),
|
||||||
|
0,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moves.sort_unstable_by(|[aa, ab, _], [ba, bb, _]| {
|
||||||
|
if aa == bb && ab == ba {
|
||||||
|
core::cmp::Ordering::Equal
|
||||||
|
} else if aa == bb {
|
||||||
|
core::cmp::Ordering::Greater
|
||||||
|
} else {
|
||||||
|
core::cmp::Ordering::Less
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
moves.dedup_by(|[aa, ab, _], [ba, bb, kind]| {
|
||||||
|
if aa == bb && ab == ba {
|
||||||
|
*kind = 1;
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for [dst, src, kind] in moves {
|
||||||
|
if kind == 0 {
|
||||||
|
self.emit(instrs::cp(dst, src));
|
||||||
|
} else {
|
||||||
|
self.emit(instrs::swa(dst, src));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (bref != u16::MAX) ^ (node.kind == Kind::Loop) {
|
||||||
|
let index = (node.kind == Kind::Loop) as usize + 1;
|
||||||
|
emit_moves(index);
|
||||||
|
|
||||||
let rel = Reloc::new(self.code.len(), 1, 4);
|
let rel = Reloc::new(self.code.len(), 1, 4);
|
||||||
self.jump_relocs.push((nid, rel));
|
self.jump_relocs.push((nid, rel));
|
||||||
self.emit(instrs::jmp(0));
|
self.emit(instrs::jmp(0));
|
||||||
} else {
|
} else {
|
||||||
let index = (node.kind != Kind::Loop) as usize + 1;
|
let index = (node.kind != Kind::Loop) as usize + 1;
|
||||||
for &out in node.outputs.iter() {
|
emit_moves(index);
|
||||||
if fuc.nodes[out].is_data_phi()
|
|
||||||
&& atr(out) != atr(fuc.nodes[out].inputs[index])
|
|
||||||
{
|
|
||||||
self.emit(instrs::cp(
|
|
||||||
atr(out),
|
|
||||||
atr(fuc.nodes[out].inputs[index]),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Return => {
|
Kind::Return => {
|
||||||
|
@ -241,8 +292,18 @@ impl HbvmBackend {
|
||||||
} else if let Some(against) = op.cmp_against() {
|
} else if let Some(against) = op.cmp_against() {
|
||||||
let op_ty = fuc.nodes[lhs].ty;
|
let op_ty = fuc.nodes[lhs].ty;
|
||||||
|
|
||||||
self.emit(extend(fuc.nodes[lhs].ty, fuc.nodes[lhs].ty.extend(), 0, 0));
|
self.emit(extend(
|
||||||
self.emit(extend(fuc.nodes[rhs].ty, fuc.nodes[rhs].ty.extend(), 1, 1));
|
fuc.nodes[lhs].ty,
|
||||||
|
fuc.nodes[lhs].ty.extend(),
|
||||||
|
lhs,
|
||||||
|
lhs,
|
||||||
|
));
|
||||||
|
self.emit(extend(
|
||||||
|
fuc.nodes[rhs].ty,
|
||||||
|
fuc.nodes[rhs].ty.extend(),
|
||||||
|
rhs,
|
||||||
|
rhs,
|
||||||
|
));
|
||||||
|
|
||||||
if op_ty.is_float() && matches!(op, TokenKind::Le | TokenKind::Ge) {
|
if op_ty.is_float() && matches!(op, TokenKind::Le | TokenKind::Ge) {
|
||||||
let opop = match op {
|
let opop = match op {
|
||||||
|
@ -253,7 +314,7 @@ impl HbvmBackend {
|
||||||
let op_fn = opop.float_cmp(op_ty).unwrap();
|
let op_fn = opop.float_cmp(op_ty).unwrap();
|
||||||
self.emit(op_fn(atr(nid), atr(lhs), atr(rhs)));
|
self.emit(op_fn(atr(nid), atr(lhs), atr(rhs)));
|
||||||
self.emit(instrs::not(atr(nid), atr(nid)));
|
self.emit(instrs::not(atr(nid), atr(nid)));
|
||||||
} else if op_ty.is_integer() {
|
} else {
|
||||||
let op_fn =
|
let op_fn =
|
||||||
if op_ty.is_signed() { instrs::cmps } else { instrs::cmpu };
|
if op_ty.is_signed() { instrs::cmps } else { instrs::cmpu };
|
||||||
self.emit(op_fn(atr(nid), atr(lhs), atr(rhs)));
|
self.emit(op_fn(atr(nid), atr(lhs), atr(rhs)));
|
||||||
|
@ -261,8 +322,6 @@ impl HbvmBackend {
|
||||||
if matches!(op, TokenKind::Eq | TokenKind::Lt | TokenKind::Gt) {
|
if matches!(op, TokenKind::Eq | TokenKind::Lt | TokenKind::Gt) {
|
||||||
self.emit(instrs::not(atr(nid), atr(nid)));
|
self.emit(instrs::not(atr(nid), atr(nid)));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
todo!("unhandled operator: {op}");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
todo!("unhandled operator: {op}");
|
todo!("unhandled operator: {op}");
|
||||||
|
@ -787,11 +846,7 @@ impl<'a> Env<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_bundle(&mut self, inst: Nid, bundle: &mut Bundle, use_buf: &mut Vec<Nid>) {
|
fn append_bundle(&mut self, inst: Nid, bundle: &mut Bundle, use_buf: &mut Vec<Nid>) {
|
||||||
let mut dom = self.ctx.idom_of(inst);
|
let dom = self.ctx.idom_of(inst);
|
||||||
if self.ctx.nodes[dom].kind == Kind::Loop && self.ctx.nodes[inst].kind == Kind::Phi {
|
|
||||||
dom = self.ctx.nodes.idom(dom);
|
|
||||||
dom = self.ctx.idom_of(dom);
|
|
||||||
}
|
|
||||||
self.ctx.uses_of(inst, use_buf);
|
self.ctx.uses_of(inst, use_buf);
|
||||||
for uinst in use_buf.drain(..) {
|
for uinst in use_buf.drain(..) {
|
||||||
let cursor = self.ctx.use_block(inst, uinst);
|
let cursor = self.ctx.use_block(inst, uinst);
|
||||||
|
|
Loading…
Reference in a new issue