things that don't work

This commit is contained in:
nora 2022-05-23 09:52:31 +02:00
parent 04dd019806
commit b8157f2ceb
11 changed files with 368 additions and 104 deletions

View file

@ -1,6 +1,7 @@
use std::fmt::{Debug, Formatter};
use bumpalo::Bump;
use dbg_pls::DebugPls;
use crate::{
parse::{Ast, Instr, Span},
@ -16,7 +17,13 @@ pub struct Hir<'hir> {
impl Debug for Hir<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.stmts.fmt(f)
Debug::fmt(&self.stmts, f)
}
}
impl DebugPls for Hir<'_> {
fn fmt(&self, f: dbg_pls::Formatter<'_>) {
DebugPls::fmt(&self.stmts.iter().collect::<Vec<_>>(), f)
}
}
@ -38,11 +45,17 @@ impl<'hir> Stmt<'hir> {
impl Debug for Stmt<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.kind.fmt(f)
Debug::fmt(&self.kind, f)
}
}
#[derive(Debug, Clone)]
impl DebugPls for Stmt<'_> {
fn fmt(&self, f: dbg_pls::Formatter<'_>) {
DebugPls::fmt(&self.kind, f)
}
}
#[derive(Debug, Clone, DebugPls)]
pub enum StmtKind<'hir> {
Add(i32, u8),
Sub(i32, u8),

View file

@ -15,11 +15,13 @@ pub fn optimize<'hir>(alloc: &'hir Bump, hir: &mut Hir<'hir>) {
pass_cancel_left_right_add_sub(hir);
pass_add_sub_offset(hir);
pass_move_add_to(hir);
// pass_unroll_loops(hir);
// pass_cancel_left_right_add_sub(hir);
}
/// pass that replaces things like `Sub(1) Sub(1)` with `Sub(2)`
// TODO: This pass is really slow, speed it up please
#[tracing::instrument]
#[tracing::instrument(skip(alloc, ir_param))]
fn pass_group<'hir>(alloc: &'hir Bump, ir_param: &mut Hir<'hir>) {
let empty_ir = Hir {
stmts: Vec::new_in(alloc),
@ -85,8 +87,12 @@ fn pass_group<'hir>(alloc: &'hir Bump, ir_param: &mut Hir<'hir>) {
}
/// pass that replaces `Loop([Sub(_)])` to `SetNull`
#[tracing::instrument]
#[tracing::instrument(skip(ir))]
fn pass_find_set_null(ir: &mut Hir<'_>) {
pass_find_set_null_inner(ir)
}
fn pass_find_set_null_inner(ir: &mut Hir<'_>) {
for stmt in &mut ir.stmts {
if let Stmt {
kind: StmtKind::Loop(body),
@ -101,16 +107,19 @@ fn pass_find_set_null(ir: &mut Hir<'_>) {
trace!(?span, "Replacing Statement with SetNull");
*stmt = Stmt::new(StmtKind::SetN(0), *span);
} else {
pass_find_set_null(body);
pass_find_set_null_inner(body);
}
}
}
}
/// pass that replaces `SetN(n) Add(m)` with `SetN(n + m)`
#[tracing::instrument]
#[tracing::instrument(skip(ir))]
fn pass_set_n(ir: &mut Hir<'_>) {
window_pass(ir, pass_set_n, |[a, b]| {
pass_set_n_inner(ir)
}
fn pass_set_n_inner(ir: &mut Hir<'_>) {
window_pass(ir, pass_set_n_inner, |[a, b]| {
if let StmtKind::SetN(before) = a.kind() {
let new = match b.kind() {
StmtKind::Add(0, n) => StmtKind::SetN(before.wrapping_add(*n)),
@ -126,9 +135,13 @@ fn pass_set_n(ir: &mut Hir<'_>) {
}
/// pass that replaces `Left(5) Right(3)` with `Left(2)`
#[tracing::instrument]
#[tracing::instrument(skip(ir))]
fn pass_cancel_left_right_add_sub(ir: &mut Hir<'_>) {
window_pass(ir, pass_cancel_left_right_add_sub, |[a, b]| {
pass_cancel_left_right_add_sub_inner(ir)
}
fn pass_cancel_left_right_add_sub_inner(ir: &mut Hir<'_>) {
window_pass(ir, pass_cancel_left_right_add_sub_inner, |[a, b]| {
match (a.kind(), b.kind()) {
(StmtKind::Right(r), StmtKind::Left(l)) | (StmtKind::Left(l), StmtKind::Right(r)) => {
let new = match r.cmp(l) {
@ -159,9 +172,12 @@ fn pass_cancel_left_right_add_sub(ir: &mut Hir<'_>) {
}
/// pass that replaces `Right(9) Add(5) Left(9)` with `AddOffset(9, 5)`
#[tracing::instrument]
#[tracing::instrument(skip(ir))]
fn pass_add_sub_offset(ir: &mut Hir<'_>) {
window_pass(ir, pass_add_sub_offset, |[a, b, c]| {
pass_add_sub_offset_inner(ir)
}
fn pass_add_sub_offset_inner(ir: &mut Hir<'_>) {
window_pass(ir, pass_add_sub_offset_inner, |[a, b, c]| {
match (a.kind(), b.kind(), c.kind()) {
(StmtKind::Right(r), StmtKind::Add(0, n), StmtKind::Left(l)) if r == l => {
WindowPassAction::Merge(StmtKind::Add(i32::try_from(*r).unwrap(), *n))
@ -181,8 +197,12 @@ fn pass_add_sub_offset(ir: &mut Hir<'_>) {
}
/// pass that replaces `Loop([Sub(1) AddOffset(o, 1)])` with `MoveAddTo(o)`
#[tracing::instrument]
#[tracing::instrument(skip(ir))]
fn pass_move_add_to(ir: &mut Hir<'_>) {
pass_move_add_to_inner(ir)
}
fn pass_move_add_to_inner(ir: &mut Hir<'_>) {
for stmt in &mut ir.stmts {
if let Stmt {
kind: StmtKind::Loop(body),
@ -207,22 +227,47 @@ fn pass_move_add_to(ir: &mut Hir<'_>) {
trace!(?span, ?offset, "Replacing Statement with MoveAddTo");
*stmt = Stmt::new(StmtKind::MoveAddTo { offset: *offset }, *span);
} else {
pass_move_add_to(body);
pass_move_add_to_inner(body);
}
}
}
}
enum WindowPassAction<'hir> {
#[tracing::instrument(skip(ir))]
fn pass_unroll_loops(ir: &mut Hir<'_>) {
let alloc = Bump::new();
pass_unroll_loops_inner(&alloc, ir);
}
fn pass_unroll_loops_inner(alloc: &Bump, ir: &mut Hir<'_>) {
window_pass(ir, pass_unroll_loops, |[a, b]| {
if let (StmtKind::SetN(n), StmtKind::Loop(body)) = (a.kind(), b.kind()) {
let mut stmts_vec = BumpVec::new_in(alloc);
let stmts = std::iter::repeat(body.stmts.iter())
.take(usize::from(*n))
.flatten()
.cloned();
stmts_vec.extend(stmts);
WindowPassAction::MergeMany(stmts_vec)
} else {
WindowPassAction::None
}
})
}
enum WindowPassAction<'hir, 'pass> {
None,
Merge(StmtKind<'hir>),
MergeMany(BumpVec<'pass, Stmt<'hir>>),
RemoveAll,
}
fn window_pass<'hir, P, F, const N: usize>(ir: &mut Hir<'hir>, pass_recur: P, action: F)
fn window_pass<'hir, 'pass, P, F, const N: usize>(ir: &mut Hir<'hir>, pass_recur: P, action: F)
where
P: Fn(&mut Hir<'hir>),
F: Fn([&Stmt<'hir>; N]) -> WindowPassAction<'hir>,
F: Fn([&Stmt<'hir>; N]) -> WindowPassAction<'hir, 'pass>,
{
assert!(N > 0);
@ -262,6 +307,15 @@ where
}
stmts[i] = Stmt::new(new, merged_span);
}
WindowPassAction::MergeMany(new) => {
trace!(?elements, ?new, "Merging many");
for _ in 0..N {
stmts.remove(i);
}
for stmt in new.into_iter().rev() {
stmts.insert(i, stmt);
}
}
}
}
}

View file

@ -23,8 +23,8 @@ pub mod parse;
#[derive(clap::Parser, Default)]
#[clap(author, about)]
pub struct Args {
/// Print colored source code depending on how often it was run.
/// Makes the interpreter ~30% slower.
/// Print colored source code depending on how often it was run.
/// Makes the interpreter ~30% slower.
#[clap(short, long)]
pub profile: bool,
/// Dump the IR info (ast, hir, mir, lir)
@ -85,7 +85,7 @@ where
let optimized_hir = hir::optimized_hir(&hir_alloc, &parsed);
if let Some(DumpKind::Hir) = config.dump {
println!("{optimized_hir:#?}");
println!("{}", dbg_pls::color(&optimized_hir));
return Ok(());
}

View file

@ -1,8 +1,11 @@
use std::{cmp, fmt::Debug};
use std::{
cmp,
fmt::{Debug, Formatter},
};
use bumpalo::Bump;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[derive(Clone, Copy, PartialEq, Eq, Default)]
pub struct Span {
start: u32,
len: u32,
@ -62,6 +65,12 @@ impl Span {
}
}
impl Debug for Span {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&(self.start..(self.start + self.len)), f)
}
}
pub type Ast<'ast> = Vec<(Instr<'ast>, Span), &'ast Bump>;
#[derive(Debug, Clone, PartialEq, Eq)]

View file

@ -1,95 +1,61 @@
---
source: src/parse.rs
assertion_line: 164
expression: instrs
---
Ok(
[
(
Add,
Span {
start: 0,
len: 1,
},
0..1,
),
(
Loop(
[
(
Sub,
Span {
start: 2,
len: 1,
},
2..3,
),
(
Loop(
[
(
Sub,
Span {
start: 4,
len: 1,
},
4..5,
),
(
Loop(
[
(
Sub,
Span {
start: 6,
len: 1,
},
6..7,
),
],
),
Span {
start: 5,
len: 3,
},
5..8,
),
],
),
Span {
start: 3,
len: 6,
},
3..9,
),
(
Add,
Span {
start: 9,
len: 1,
},
9..10,
),
(
Right,
Span {
start: 10,
len: 1,
},
10..11,
),
(
Right,
Span {
start: 11,
len: 1,
},
11..12,
),
(
Right,
Span {
start: 12,
len: 1,
},
12..13,
),
],
),
Span {
start: 1,
len: 13,
},
1..14,
),
],
)

View file

@ -1,68 +1,43 @@
---
source: src/parse.rs
assertion_line: 155
expression: instrs
---
Ok(
[
(
Right,
Span {
start: 0,
len: 1,
},
0..1,
),
(
Add,
Span {
start: 1,
len: 1,
},
1..2,
),
(
Left,
Span {
start: 2,
len: 1,
},
2..3,
),
(
Add,
Span {
start: 3,
len: 1,
},
3..4,
),
(
Add,
Span {
start: 4,
len: 1,
},
4..5,
),
(
Loop(
[
(
Sub,
Span {
start: 6,
len: 1,
},
6..7,
),
],
),
Span {
start: 5,
len: 3,
},
5..8,
),
(
Out,
Span {
start: 8,
len: 1,
},
8..9,
),
],
)