From 6057e880345c38a2d4844575a401c23f34dedb26 Mon Sep 17 00:00:00 2001 From: mlokr Date: Fri, 20 Sep 2024 19:01:44 +0200 Subject: [PATCH] fixing a bug and preparing form memory manipulation with optimizations --- Cargo.lock | 221 ++++++++++++++++++++++++++++++++++++++++++ hblang/Cargo.toml | 5 +- hblang/src/codegen.rs | 2 +- hblang/src/lib.rs | 1 + hblang/src/son.rs | 209 +++++++++++++++++++++------------------ 5 files changed, 340 insertions(+), 98 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b52caf..6d2d8a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,93 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -20,6 +107,7 @@ version = "0.1.0" name = "hblang" version = "0.1.0" dependencies = [ + "env_logger", "hbbytecode", "hbvm", "regalloc2", @@ -40,12 +128,36 @@ dependencies = [ "memmap2", ] +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "libc" version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + [[package]] name = "memmap2" version = "0.9.5" @@ -61,10 +173,40 @@ version = "0.10.2" source = "git+https://github.com/jakubDoka/regalloc2#52b2bbe908e78af1715de88f562f62a83e36ca96" dependencies = [ "hashbrown", + "log", "rustc-hash", "smallvec", ] +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + [[package]] name = "rustc-hash" version = "2.0.0" @@ -77,6 +219,85 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "xtask" version = "0.1.0" diff --git a/hblang/Cargo.toml b/hblang/Cargo.toml index a2f7887..d059410 100644 --- a/hblang/Cargo.toml +++ b/hblang/Cargo.toml @@ -10,4 +10,7 @@ path = "src/main.rs" [dependencies] hbbytecode = { version = "0.1.0", path = "../hbbytecode" } hbvm = { path = "../hbvm", features = ["nightly"] } -regalloc2 = { git = "https://github.com/jakubDoka/regalloc2" } +regalloc2 = { git = "https://github.com/jakubDoka/regalloc2", features = ["trace-log"] } + +[dev-dependencies] +env_logger = "0.11.5" diff --git a/hblang/src/codegen.rs b/hblang/src/codegen.rs index c1e451b..eb4796d 100644 --- a/hblang/src/codegen.rs +++ b/hblang/src/codegen.rs @@ -12,7 +12,7 @@ use { Types, }, core::panic, - std::{fmt::Display, usize}, + std::fmt::Display, }; type Offset = u32; diff --git a/hblang/src/lib.rs b/hblang/src/lib.rs index abb3b4a..3ab0dd1 100644 --- a/hblang/src/lib.rs +++ b/hblang/src/lib.rs @@ -1,4 +1,5 @@ #![feature( + assert_matches, let_chains, if_let_guard, macro_metavar_expr, diff --git a/hblang/src/son.rs b/hblang/src/son.rs index c146d7d..ce7cc86 100644 --- a/hblang/src/son.rs +++ b/hblang/src/son.rs @@ -12,11 +12,12 @@ use { }, task, ty::{self}, - Field, Func, HashMap, Reloc, Sig, Struct, SymKey, TypedReloc, Types, + Field, Func, HashMap, Offset, Reloc, Sig, Size, Struct, SymKey, TypedReloc, Types, }, core::fmt, regalloc2::VReg, std::{ + assert_matches::debug_assert_matches, cell::RefCell, collections::hash_map, fmt::{Debug, Display, Write}, @@ -24,6 +25,7 @@ use { mem::{self, MaybeUninit}, ops::{self, Deref, DerefMut, Not}, ptr::Unique, + u32, }, }; @@ -493,18 +495,11 @@ impl Nodes { fn peephole(&mut self, target: Nid) -> Option { match self[target].kind { - Kind::Start => {} - Kind::End => {} Kind::BinOp { op } => return self.peephole_binop(target, op), Kind::UnOp { op } => return self.peephole_unop(target, op), - Kind::Return => {} - Kind::Tuple { .. } => {} - Kind::CInt { .. } => {} - Kind::Call { .. } => {} Kind::If => return self.peephole_if(target), - Kind::Region => {} Kind::Phi => return self.peephole_phi(target), - Kind::Loop => {} + _ => {} } None } @@ -701,13 +696,20 @@ impl Nodes { Kind::Return => write!(out, " ret: "), Kind::CInt { value } => write!(out, "cint: #{value:<4}"), Kind::Phi => write!(out, " phi: "), - Kind::Tuple { index } => write!(out, " arg: {index:<5}"), + Kind::Arg { index } => write!(out, " arg: {index:<5}"), Kind::BinOp { op } | Kind::UnOp { op } => { write!(out, "{:>4}: ", op.name()) } Kind::Call { func } => { write!(out, "call: {func} {} ", self[node].depth) } + Kind::Ctrl { index: u32::MAX } => write!(out, "ctrl: {:<5}", "entry"), + Kind::Ctrl { index: 0 } => write!(out, "ctrl: {:<5}", "then"), + Kind::Ctrl { index: 1 } => write!(out, "ctrl: {:<5}", "else"), + Kind::Stck { size } => write!(out, "stck: {size:<5}"), + Kind::Load { offset } => write!(out, "load: {offset:<5}"), + Kind::Stre { offset } => write!(out, "stre: {offset:<5}"), + _ => unreachable!(), }?; if self[node].kind != Kind::Loop && self[node].kind != Kind::Region { @@ -731,7 +733,7 @@ impl Nodes { let mut cfg_index = Nid::MAX; for o in iter(self, node) { self.basic_blocks_instr(out, o)?; - if self[o].kind == (Kind::Tuple { index: 0 }) { + if self[o].kind.is_cfg() { cfg_index = o; } } @@ -775,7 +777,7 @@ impl Nodes { Kind::Return => { node = self[node].outputs[0]; } - Kind::Tuple { .. } => { + Kind::Ctrl { .. } => { writeln!( out, "b{node}: {} {} {:?}", @@ -805,7 +807,14 @@ impl Nodes { } node = cfg_index; } - Kind::CInt { .. } | Kind::Phi | Kind::BinOp { .. } | Kind::UnOp { .. } => { + Kind::Arg { .. } + | Kind::Stck { .. } + | Kind::Load { .. } + | Kind::Stre { .. } + | Kind::CInt { .. } + | Kind::Phi + | Kind::BinOp { .. } + | Kind::UnOp { .. } => { unreachable!() } } @@ -996,27 +1005,53 @@ impl ops::IndexMut for Nodes { pub enum Kind { #[default] Start, + // [terms...] End, + // [ctrl, cond] If, + // [lhs, rhs] Region, + // [entry, back] Loop, + // [ctrl, ?value] Return, + // [ctrl] CInt { value: i64, }, + // [ctrl, lhs, rhs] Phi, - Tuple { + Arg { index: u32, }, + // [ctrl] + Ctrl { + index: u32, + }, + // [ctrl, oper] UnOp { op: lexer::TokenKind, }, + // [ctrl, lhs, rhs] BinOp { op: lexer::TokenKind, }, + // [ctrl, ...args] Call { func: ty::Func, }, + // [ctrl] + Stck { + size: Size, + }, + // [ctrl, memory] + Load { + offset: Offset, + }, + // [ctrl, memory] + Stre { + offset: Offset, + }, } impl Kind { @@ -1030,7 +1065,8 @@ impl Kind { Self::Start | Self::End | Self::Return - | Self::Tuple { .. } + | Self::Ctrl { .. } + | Self::Arg { .. } | Self::Call { .. } | Self::If | Self::Region @@ -1043,7 +1079,7 @@ impl Kind { } fn starts_basic_block(&self) -> bool { - matches!(self, Self::Start | Self::End | Self::Tuple { .. } | Self::Region | Self::Loop) + matches!(self, Self::Start | Self::End | Self::Ctrl { .. } | Self::Region | Self::Loop) } } @@ -1051,7 +1087,9 @@ impl fmt::Display for Kind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Kind::CInt { value } => write!(f, "#{value}"), - Kind::Tuple { index } => write!(f, "tupl[{index}]"), + Kind::Ctrl { index: u32::MAX } => write!(f, "ctrl[entry]"), + Kind::Ctrl { index: 0 } => write!(f, "ctrl[then]"), + Kind::Ctrl { index: 1 } => write!(f, "ctrl[else]"), Kind::BinOp { op } => write!(f, "{op}"), Kind::Call { func, .. } => write!(f, "call {func}"), slf => write!(f, "{slf:?}"), @@ -1087,8 +1125,6 @@ impl Node { } } -type Offset = u32; -type Size = u32; type RallocBRef = u16; type LoopDepth = u16; type CallCount = u16; @@ -1321,13 +1357,11 @@ impl Codegen { self.ci.nodes.lock(el.value); } - self.ci.ctrl = - self.ci.nodes.new_node(ty::VOID, Kind::Tuple { index: 0 }, [if_node]); + self.ci.ctrl = self.ci.nodes.new_node(ty::VOID, Kind::Ctrl { index: 0 }, [if_node]); let lcntrl = self.expr(then).map_or(Nid::MAX, |_| self.ci.ctrl); let mut then_scope = std::mem::replace(&mut self.ci.vars, else_scope); - self.ci.ctrl = - self.ci.nodes.new_node(ty::VOID, Kind::Tuple { index: 1 }, [if_node]); + self.ci.ctrl = self.ci.nodes.new_node(ty::VOID, Kind::Ctrl { index: 1 }, [if_node]); let rcntrl = if let Some(else_) = else_ { self.expr(else_).map_or(Nid::MAX, |_| self.ci.ctrl) } else { @@ -1671,7 +1705,7 @@ impl Codegen { debug_assert_eq!(start, VOID); let end = self.ci.nodes.new_node(ty::NEVER, Kind::End, []); debug_assert_eq!(end, NEVER); - self.ci.ctrl = self.ci.nodes.new_node(ty::VOID, Kind::Tuple { index: 0 }, [VOID]); + self.ci.ctrl = self.ci.nodes.new_node(ty::VOID, Kind::Ctrl { index: u32::MAX }, [VOID]); let Expr::BinOp { left: Expr::Ident { .. }, @@ -1683,9 +1717,9 @@ impl Codegen { }; let mut sig_args = sig.args.range(); - for (arg, index) in args.iter().zip(1u32..) { + for (arg, index) in args.iter().zip(0u32..) { let ty = self.tys.args[sig_args.next().unwrap()]; - let value = self.ci.nodes.new_node(ty, Kind::Tuple { index }, [VOID]); + let value = self.ci.nodes.new_node(ty, Kind::Arg { index }, [VOID]); self.ci.nodes.lock(value); let sym = parser::find_symbol(&ast.symbols, arg.id); assert!(sym.flags & idfl::COMPTIME == 0, "TODO"); @@ -1715,7 +1749,7 @@ impl Codegen { self.ci.emit(instrs::st(reg::RET_ADDR, reg::STACK_PTR, 0, 0)); } - //self.ci.nodes.basic_blocks(); + self.ci.nodes.basic_blocks(); //self.ci.nodes.graphviz(); self.ci.vars = orig_vars; @@ -1816,8 +1850,6 @@ impl Codegen { let allocs = output.inst_allocs(inst); let node = &func.nodes[nid]; match node.kind { - Kind::Start => todo!(), - Kind::End => todo!(), Kind::If => { let &[_, cond] = node.inputs.as_slice() else { unreachable!() }; if let Kind::BinOp { op } = func.nodes[cond].kind @@ -1848,8 +1880,6 @@ impl Codegen { Kind::CInt { value } => { self.ci.emit(instrs::li64(atr(allocs[0]), value as _)); } - Kind::Phi => todo!(), - Kind::Tuple { .. } => todo!(), Kind::UnOp { op } => { let op = op.unop().expect("TODO: unary operator not supported"); let &[dst, oper] = allocs else { unreachable!() }; @@ -1881,6 +1911,12 @@ impl Codegen { }); self.ci.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0)); } + Kind::Start | Kind::End | Kind::Phi | Kind::Arg { .. } | Kind::Ctrl { .. } => { + unreachable!() + } + Kind::Stck { .. } => todo!(), + Kind::Load { .. } => todo!(), + Kind::Stre { .. } => todo!(), } } } @@ -2219,7 +2255,12 @@ impl<'a> Function<'a> { let node = self.nodes[nid].clone(); match node.kind { - Kind::Start => self.emit_node(node.outputs[0], VOID), + Kind::Start => { + debug_assert_matches!(self.nodes[node.outputs[0]].kind, Kind::Ctrl { + index: u32::MAX + }); + self.emit_node(node.outputs[0], VOID) + } Kind::End => {} Kind::If => { self.nodes[nid].ralloc_backref = self.nodes[prev].ralloc_backref; @@ -2288,45 +2329,37 @@ impl<'a> Function<'a> { self.add_instr(nid, ops); } } - Kind::Phi => {} - Kind::Tuple { index } => { - let is_start = self.nodes[node.inputs[0]].kind == Kind::Start && index == 0; - if is_start || (self.nodes[node.inputs[0]].kind == Kind::If && index < 2) { - self.nodes[nid].ralloc_backref = self.add_block(nid); - self.bridge(prev, nid); + Kind::Ctrl { index: u32::MAX } => { + self.nodes[nid].ralloc_backref = self.add_block(nid); + self.bridge(prev, nid); - if is_start { - let mut parama = self.tys.parama(self.sig.ret); - for (arg, ti) in self.nodes[VOID] - .clone() - .outputs - .into_iter() - .skip(1) - .zip(self.sig.args.range()) - { - let ty = self.tys.args[ti]; - match self.tys.size_of(ty) { - 0 => continue, - 1..=8 => { - self.def_nid(arg); - self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def( - self.rg(arg), - regalloc2::PReg::new( - parama.next() as _, - regalloc2::RegClass::Int, - ), - )]); - } - _ => todo!(), - } + let mut parama = self.tys.parama(self.sig.ret); + for (arg, ti) in + self.nodes[VOID].clone().outputs.into_iter().skip(1).zip(self.sig.args.range()) + { + let ty = self.tys.args[ti]; + match self.tys.size_of(ty) { + 0 => continue, + 1..=8 => { + self.def_nid(arg); + self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def( + self.rg(arg), + regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int), + )]); } + _ => todo!(), } + } - for o in node.outputs.into_iter().rev() { - self.emit_node(o, nid); - } - } else { - todo!(); + for o in node.outputs.into_iter().rev() { + self.emit_node(o, nid); + } + } + Kind::Ctrl { .. } => { + self.nodes[nid].ralloc_backref = self.add_block(nid); + self.bridge(prev, nid); + for o in node.outputs.into_iter().rev() { + self.emit_node(o, nid); } } Kind::BinOp { op } => { @@ -2385,6 +2418,10 @@ impl<'a> Function<'a> { } } } + Kind::Phi | Kind::Arg { .. } => {} + Kind::Stck { .. } => todo!(), + Kind::Load { .. } => todo!(), + Kind::Stre { .. } => todo!(), } } @@ -2439,7 +2476,7 @@ impl<'a> regalloc2::Function for Function<'a> { fn is_branch(&self, insn: regalloc2::Inst) -> bool { matches!( self.nodes[self.instrs[insn.index()].nid].kind, - Kind::If | Kind::Tuple { .. } | Kind::Loop | Kind::Region + Kind::If | Kind::Ctrl { .. } | Kind::Loop | Kind::Region ) } @@ -2492,7 +2529,7 @@ fn loop_depth(target: Nid, nodes: &mut Nodes) -> LoopDepth { } nodes[target].loop_depth = match nodes[target].kind { - Kind::Tuple { .. } | Kind::Call { .. } | Kind::Return | Kind::If => { + Kind::Ctrl { .. } | Kind::Call { .. } | Kind::Return | Kind::If => { loop_depth(nodes[target].inputs[0], nodes) } Kind::Region => { @@ -2514,15 +2551,11 @@ fn loop_depth(target: Nid, nodes: &mut Nodes) -> LoopDepth { idom(nodes, cursor) }; debug_assert_ne!(next, VOID); - if let Kind::Tuple { index } = nodes[cursor].kind - && nodes[next].kind == Kind::If - { + if let Kind::Ctrl { index: index @ ..=1 } = nodes[cursor].kind { let other = *nodes[next] .outputs .iter() - .find( - |&&n| matches!(nodes[n].kind, Kind::Tuple { index: oi } if index != oi), - ) + .find(|&&n| nodes[n].kind != Kind::Ctrl { index }) .unwrap(); if nodes[other].loop_depth == 0 { nodes[other].loop_depth = depth - 1; @@ -2533,9 +2566,7 @@ fn loop_depth(target: Nid, nodes: &mut Nodes) -> LoopDepth { depth } Kind::Start | Kind::End => 1, - Kind::CInt { .. } | Kind::Phi | Kind::BinOp { .. } | Kind::UnOp { .. } => { - unreachable!() - } + _ => unreachable!(), }; if target == 19 { @@ -2558,18 +2589,10 @@ fn idepth(nodes: &mut Nodes, target: Nid) -> IDomDepth { if nodes[target].depth == 0 { nodes[target].depth = match nodes[target].kind { Kind::End | Kind::Start => unreachable!(), - Kind::Loop - | Kind::CInt { .. } - | Kind::BinOp { .. } - | Kind::UnOp { .. } - | Kind::Call { .. } - | Kind::Phi - | Kind::Tuple { .. } - | Kind::Return - | Kind::If => idepth(nodes, nodes[target].inputs[0]), Kind::Region => { idepth(nodes, nodes[target].inputs[0]).max(idepth(nodes, nodes[target].inputs[1])) } + _ => idepth(nodes, nodes[target].inputs[0]), } + 1; } nodes[target].depth @@ -2689,19 +2712,11 @@ fn idom(nodes: &mut Nodes, target: Nid) -> Nid { match nodes[target].kind { Kind::Start => VOID, Kind::End => unreachable!(), - Kind::Loop - | Kind::CInt { .. } - | Kind::BinOp { .. } - | Kind::UnOp { .. } - | Kind::Call { .. } - | Kind::Phi - | Kind::Tuple { .. } - | Kind::Return - | Kind::If => nodes[target].inputs[0], Kind::Region => { let &[lcfg, rcfg] = nodes[target].inputs.as_slice() else { unreachable!() }; common_dom(lcfg, rcfg, nodes) } + _ => nodes[target].inputs[0], } } @@ -2725,6 +2740,8 @@ mod tests { const README: &str = include_str!("../README.md"); fn generate(ident: &'static str, input: &'static str, output: &mut String) { + _ = env_logger::builder().is_test(true).try_init(); + let mut codegen = super::Codegen { files: crate::test_parse_files(ident, input), ..Default::default() };