Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inlining of (not all) control flow structures #39

Open
wants to merge 92 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
a084c30
Updated rebench config
OctaveLarose Dec 10, 2022
63d2d6c
adding bytecodes send1,2,3
OctaveLarose Dec 10, 2022
bf0e77e
supersend1-2-3 bytecodes
OctaveLarose Dec 10, 2022
9c3eb96
Option type instead of relying like u8::MAX like a maniac
OctaveLarose Dec 10, 2022
bb335ad
push 0, 1, nil
OctaveLarose Dec 10, 2022
3389a7b
push constant 0, 1, 2
OctaveLarose Dec 10, 2022
5eb4f4d
non functional ifTrue inlining, with new JumpOnFalseTopNil opcode
OctaveLarose Dec 10, 2022
d67c0c0
progress with ifTrue inlining, fixed some bugs but still not functional
OctaveLarose Dec 14, 2022
30cbb0b
very WIP commit but getting closer to successful inlining
OctaveLarose Dec 16, 2022
3536084
functional ifTrue inlining at least for running Mandelbrot!
OctaveLarose Dec 16, 2022
01bdda9
Minor cleanups and fixed it for Bounce at least
OctaveLarose Dec 19, 2022
38a331e
Basic bash script for running benchmarks
OctaveLarose Dec 19, 2022
8118773
Fixed other benchmarks. Known issue: breaks variable shadowing in inl…
OctaveLarose Dec 19, 2022
0089092
Inlining ifFalse:, and the associate opcode JumpOnTrueTopNil
OctaveLarose Dec 20, 2022
64769c1
Removed bytecodes NAMES and PADDED_NAMES, since they were annoying an…
OctaveLarose Dec 20, 2022
06fabe5
start of ifTrue:ifFalse: inlining, and some slight refactoring to mak…
OctaveLarose Dec 20, 2022
016e151
successful ifTrue:ifFalse: and ifFalse:ifTrue: inlining. Known issue,…
OctaveLarose Dec 20, 2022
0504ad6
Fixed the self bug, was an oversight
OctaveLarose Dec 20, 2022
ad99e99
Improved some panic messages and left a TODO
OctaveLarose Dec 20, 2022
9840c01
Removed an old TODO and slightly optimized binary ops
OctaveLarose Dec 20, 2022
fdbb7b5
Had forgotten to inline ifFalse:ifTrue:, oops.
OctaveLarose Dec 20, 2022
0e45b1a
Working towards inlining whileTrue:
OctaveLarose Dec 21, 2022
aab089d
Successfully inlining one whileTrue in Bounce
OctaveLarose Dec 21, 2022
e3a1a31
Inlining every ifTrue makes Bounce not crash at least
OctaveLarose Dec 21, 2022
bda7fd7
Progress with whileTrue, seems to occasionally make infinite loops
OctaveLarose Dec 26, 2022
9c3ed08
added whileFalse: but still haven't fixed some issues with whileTrue:…
OctaveLarose Dec 26, 2022
23f6132
Wrote an inliner module because inlining code was getting too sizeabl…
OctaveLarose Dec 26, 2022
3e29715
Setting the stage for patching inner blocks during inlining
OctaveLarose Dec 26, 2022
6f04062
fixed mandelbrot infinite loop, but not Json
OctaveLarose Dec 27, 2022
052c831
Minor refactoring in inlining code for slightly more clarity (include…
OctaveLarose Dec 27, 2022
d02f593
Fixed an infinite loop with whileFalse in Json
OctaveLarose Dec 30, 2022
6446b4f
Removed unused bytecode halt (pysom also has it and never uses it, iirc)
OctaveLarose Dec 30, 2022
39251da
Fixed Richards and added it to run_benchmarks.sh
OctaveLarose Dec 30, 2022
58e9a8b
Added a halt primitive for debugging
OctaveLarose Dec 30, 2022
b044400
while inlining functional in Json, therefore in every benchmark tested!
OctaveLarose Dec 30, 2022
9cecc88
minor jump bytecode code cleanup
OctaveLarose Dec 30, 2022
a63319c
now inlining more than block expressions
OctaveLarose Dec 30, 2022
89eff54
JumpType enum for more clarity
OctaveLarose Dec 30, 2022
bc6e8b9
block inlining now pushes specialzied pushconstant bytecodes when pos…
OctaveLarose Dec 31, 2022
fda6bd9
first attempt at a bc optimizing pass (non functional)
OctaveLarose Dec 31, 2022
a9c907d
better solution for the dup pop_x pop optimization, but doesn't work …
OctaveLarose Dec 31, 2022
bcb6ef3
fixed removing the dup popx pop sequences partly, as it still breaks …
OctaveLarose Jan 2, 2023
41c5a6b
Removed the ugly ast::Block field in the Block struct
OctaveLarose Jan 4, 2023
7089dfe
functional instructions replacement, as far as i can tell
OctaveLarose Jan 4, 2023
4676292
deactivating dup_popx_pop temporarily
OctaveLarose Jan 4, 2023
271875d
only inlining blocks again
OctaveLarose Jan 4, 2023
79f494c
Merge remote-tracking branch 'original/master'
OctaveLarose Jan 13, 2023
cc3ce2d
sticking with this core-lib version for now
OctaveLarose Jan 13, 2023
0b1ee34
Merge branch 'removing-extra-dup-pop'
OctaveLarose Jan 13, 2023
b63f40f
Added a comment to explain how the dup_popx_pop removal function is u…
OctaveLarose Jan 13, 2023
df954cc
Merge remote-tracking branch 'nicolas/master'
OctaveLarose Jan 16, 2024
c7a7355
temporary fix for disassembler
OctaveLarose Jan 17, 2024
6405349
adding the new BCs to the disassembler
OctaveLarose Jan 23, 2024
6671aa6
disas: properly handling all the new BCs
OctaveLarose Jan 23, 2024
112709d
making the inlining work properly with shadowing, slowly but surely. …
OctaveLarose Jan 23, 2024
bcf3aef
inlining is getting there, but odd bugs are present
OctaveLarose Jan 23, 2024
aaf2166
more inlining tweaks. it still doesn't work some of the time though
OctaveLarose Jan 24, 2024
1377300
inlining locals as well, in an ugly way! also added back inline_while…
OctaveLarose Jan 25, 2024
f87dbb4
Proper solution for shadowing: now storing the original scope when in…
OctaveLarose Jan 29, 2024
aeb48a5
functional inlining for ifTrue:ifFalse too!
OctaveLarose Jan 29, 2024
fdaf601
whileTrue/whileFalse inlining! works on the benchmarks (all running 1…
OctaveLarose Jan 29, 2024
89605f4
removing an unneeded literal
OctaveLarose Jan 29, 2024
31ff265
reverting gitignore/rebench.conf for the PR
OctaveLarose Jan 29, 2024
78e46a7
Fixed some bad merge in the interpreter causing some old send functio…
OctaveLarose Jan 30, 2024
3fad7db
Revert "reverting gitignore/rebench.conf for the PR" (for debugging)
OctaveLarose Jan 30, 2024
c1b4a38
moved all the specialized bytecode to their own branch (expecting mor…
OctaveLarose Feb 2, 2024
189630e
minor disassembler tweak for better reasoning about jumps
OctaveLarose Feb 2, 2024
10670c6
config for running benchmarks on yuria1
OctaveLarose Feb 2, 2024
3c9a856
fixed interpreter sftp
OctaveLarose Feb 2, 2024
a90242b
fixed gitlab-ci, maybe
OctaveLarose Feb 2, 2024
0357b31
fixed gitlab-ci, probably!
OctaveLarose Feb 2, 2024
df26e60
inlining: changing core-lib version to the same as master
OctaveLarose Feb 5, 2024
1fe1123
inlining or and and, too
OctaveLarose Feb 5, 2024
5f4d3db
inlining or and and, too
OctaveLarose Feb 5, 2024
7310443
only inlining or, to see if only and breaks
OctaveLarose Feb 6, 2024
ce750a0
basic inlining tests
OctaveLarose Feb 6, 2024
5efc26a
or/and inlining + tests for that
OctaveLarose Feb 7, 2024
dd6b338
some more advanced inlining tests
OctaveLarose Feb 7, 2024
b452df9
yuria2'ing
OctaveLarose Feb 12, 2024
25b7f27
BROKEN: ongoing merge with specialized bc branch
OctaveLarose Feb 20, 2024
fb7ea67
BROKEN: ongoing merge with specialized bc branch. Lacking dup_popx_po…
OctaveLarose Feb 22, 2024
7133fd9
BROKEN: ongoing merge with specialized bc branch. Implemented dup_pop…
OctaveLarose Feb 22, 2024
540956b
functional merge with specialized BC branch
OctaveLarose Feb 26, 2024
1868393
ongoing work: adapt_block_after_outer_inlined(). which will remove th…
OctaveLarose Mar 6, 2024
c06e05a
fixed disassembler bug related to push1
OctaveLarose Mar 6, 2024
355675e
Progress with adapt_block_after_outer_inlined. passes every basic tes…
OctaveLarose Mar 6, 2024
fabf18d
block adaptation after inlining: seems functional, actually!
OctaveLarose Mar 6, 2024
6ee323c
test to see if perf is affected (probably not): changing rules for in…
OctaveLarose Mar 8, 2024
8ba8c58
another test for inlining returnnonlocal (deltablue disabled!). if pe…
OctaveLarose Mar 8, 2024
aabc4ac
reactivated tests, nonlocal case is fine
OctaveLarose Mar 8, 2024
1a900aa
returning to the old "only nonlocal ret" strat, and added an expansiv…
OctaveLarose Mar 8, 2024
5bc87a7
formatting pass too
OctaveLarose Mar 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Progress with whileTrue, seems to occasionally make infinite loops
OctaveLarose committed Dec 26, 2022
commit bda7fd7680c9a05e49ff2161c92c6921413bc192
1 change: 1 addition & 0 deletions som-core/src/bytecode.rs
Original file line number Diff line number Diff line change
@@ -152,6 +152,7 @@ impl fmt::Display for Bytecode {
Self::Jump(idx) => write!(f, "JUMP {}", idx),
Self::JumpBackward(idx) => write!(f, "JUMP_BACKWARD {}", idx),
Self::JumpOnFalseTopNil(idx) => write!(f, "JUMP_ON_FALSE_TOP_NIL {}", idx),
Self::JumpOnFalsePop(idx) => write!(f, "JUMP_ON_FALSE_POP {}", idx),
_ => write!(f, "No display for this bytecode, TODO")
}
}
131 changes: 98 additions & 33 deletions som-interpreter-bc/src/compiler.rs
Original file line number Diff line number Diff line change
@@ -106,6 +106,8 @@ trait InnerGenCtxt: GenCtxt {
fn remove_literal(&mut self, idx: usize) -> Option<Literal>;
fn get_instr_idx(&self) -> usize;
fn backpatch(&mut self, idx_to_backpatch: usize, bytecode_with_new_val: Bytecode);
fn get_body_debug(&self) -> Option<&Vec<Bytecode>>;
fn get_literals_debug(&self) -> IndexSet<Literal>;
}

struct BlockGenCtxt<'a> {
@@ -144,6 +146,14 @@ impl GenCtxt for BlockGenCtxt<'_> {
}

impl InnerGenCtxt for BlockGenCtxt<'_> {
fn get_body_debug(&self) -> Option<&Vec<Bytecode>> {
self.body.as_ref()
}

fn get_literals_debug(&self) -> IndexSet<Literal> {
self.literals.clone()
}

fn as_gen_ctxt(&mut self) -> &mut dyn GenCtxt {
self
}
@@ -216,6 +226,7 @@ impl GenCtxt for MethodGenCtxt<'_> {
}

impl InnerGenCtxt for MethodGenCtxt<'_> {

fn as_gen_ctxt(&mut self) -> &mut dyn GenCtxt {
self
}
@@ -259,6 +270,14 @@ impl InnerGenCtxt for MethodGenCtxt<'_> {
fn backpatch(&mut self, idx_to_backpatch: usize, bytecode_with_new_val: Bytecode) {
self.inner.backpatch(idx_to_backpatch, bytecode_with_new_val);
}

fn get_body_debug(&self) -> Option<&Vec<Bytecode>> {
self.inner.get_body_debug()
}

fn get_literals_debug(&self) -> IndexSet<Literal> {
self.inner.get_literals_debug()
}
}

trait MethodCodegen {
@@ -295,9 +314,6 @@ impl MethodCodegen for ast::Expression {
None => {
match name.as_str() {
"nil" => ctxt.push_instr(Bytecode::PushNil),
// TODO should cache those false and true, although pushing 0 and 1 isn't functional
// "false" => ctxt.push_instr(Bytecode::Push0),
// "true" => ctxt.push_instr(Bytecode::Push1),
_ => {
let name = ctxt.intern_symbol(name);
let idx = ctxt.push_literal(Literal::Symbol(name));
@@ -509,7 +525,8 @@ impl PrimMessageInliner for ast::Expression {
_ => return None
};

let block_ref = match ctxt.remove_literal(*block_idx as usize)? {
// todo pop the literal
let block_ref = match ctxt.get_literal(*block_idx as usize)? {
Literal::Block(val) => val.clone(),
_ => return None
};
@@ -525,22 +542,42 @@ impl PrimMessageInliner for ast::Expression {

self.inline_compiled_block(ctxt, block_ref.as_ref());

// println!("BYTECODES AFTER FIRST BLOCK:");
// for instr in ctxt.get_instructions() {
// println!("{}", instr);
// }
// dbg!(ctxt.get_literals_debug());

// println!("BYTECODES IN FIRST BLOCK:");
// for instr in &block_ref.as_ref().body {
// println!("{}", instr);
// }
// println!();
// println!("Block lits:");
// dbg!(&block_ref.as_ref().literals);

let loop_start_idx = ctxt.get_instr_idx();

ctxt.push_instr(Bytecode::JumpOnFalseTopNil(0));
ctxt.push_instr(Bytecode::JumpOnFalsePop(0));

self.inline_block_expr(ctxt, message.values.get(0).unwrap());

ctxt.push_instr(Bytecode::Pop);

let jump_to_cond_val = ctxt.get_instr_idx() - cond_idx;
ctxt.push_instr(Bytecode::JumpBackward(jump_to_cond_val));


let loop_jump_by = ctxt.get_instr_idx() - loop_start_idx;
ctxt.backpatch(loop_start_idx, Bytecode::JumpOnFalseTopNil(loop_jump_by));
ctxt.backpatch(loop_start_idx, Bytecode::JumpOnFalsePop(loop_jump_by));

ctxt.push_instr(Bytecode::PushNil);

// println!("BYTECODES:");
// for instr in ctxt.get_instructions() {
// println!("{}", instr);
// }
// println!("");
// println!();

return Some(());
}
@@ -580,29 +617,69 @@ impl PrimMessageInliner for ast::Expression {
// ctxt.push_local(String::from(block_local));
}

// let literals_offset = block.literals.len()- 1;
for block_lit in &block.literals {
match block_lit {
Literal::Symbol(interned) => {
ctxt.push_literal(Literal::Symbol(*interned));
}
_ => { todo!() }
};
}

// let literals_offset = block.literals.len();
// for block_lit in &block.literals {
// match block_lit {
// Literal::Symbol(interned) => {
// ctxt.push_literal(Literal::Symbol(*interned));
// }
// _ => { todo!() }
// };
// }

if let Some((last, body)) = block.body.split_last() {
for block_bc in body {
match block_bc {
Bytecode::PushLocal(up_idx, idx) => ctxt.push_instr( Bytecode::PushLocal(*up_idx - 1, *idx)),
Bytecode::PopLocal(up_idx, idx) => ctxt.push_instr( Bytecode::PopLocal(*up_idx - 1, *idx)),
Bytecode::PushArgument(up_idx, idx) => ctxt.push_instr( Bytecode::PushArgument(*up_idx - 1, *idx)),
Bytecode::Send1(lit_idx) => ctxt.push_instr( Bytecode::Send1(*lit_idx)),
Bytecode::PushLocal(up_idx, idx) => ctxt.push_instr(Bytecode::PushLocal(*up_idx - 1, *idx)),
Bytecode::PopLocal(up_idx, idx) => ctxt.push_instr(Bytecode::PopLocal(*up_idx - 1, *idx)),
Bytecode::PushArgument(up_idx, idx) => ctxt.push_instr(Bytecode::PushArgument(*up_idx - 1, *idx)),
Bytecode::Send1(lit_idx) => {
match block.literals.get(*lit_idx as usize)? {
Literal::Symbol(interned) => {
let idx = ctxt.push_literal(Literal::Symbol(*interned));
ctxt.push_instr(Bytecode::Send1(idx as u8));
},
_ => todo!()
}
},
Bytecode::Send2(lit_idx) => {
match block.literals.get(*lit_idx as usize)? {
Literal::Symbol(interned) => {
let idx = ctxt.push_literal(Literal::Symbol(*interned));
ctxt.push_instr(Bytecode::Send2(idx as u8));
},
_ => todo!()
}
},
Bytecode::Send3(lit_idx) => {
match block.literals.get(*lit_idx as usize)? {
Literal::Symbol(interned) => {
let idx = ctxt.push_literal(Literal::Symbol(*interned));
ctxt.push_instr(Bytecode::Send3(idx as u8));
},
_ => todo!()
}
},
Bytecode::SendN(lit_idx) => {
match block.literals.get(*lit_idx as usize)? {
Literal::Symbol(interned) => {
let idx = ctxt.push_literal(Literal::Symbol(*interned));
ctxt.push_instr(Bytecode::SendN(idx as u8));
},
_ => todo!()
}
},
_ => ctxt.push_instr(*block_bc)
}
}

match last {
Bytecode::ReturnLocal => {},
_ => ctxt.push_instr(*last) // afaik it's always the case, so maybe should always be popped.
_ => {
panic!("wait, this can happen?");
// ctxt.push_instr(*last);
}
}
}

@@ -697,14 +774,10 @@ fn compile_method(outer: &mut dyn GenCtxt, defn: &ast::MethodDef) -> Option<Meth
signature: ctxt.signature,
};

// println!("(method) compiled '{}' !", defn.signature);

Some(method)
}

fn compile_block(outer: &mut dyn GenCtxt, defn: &ast::Block) -> Option<Block> {
// println!("(system) compiling block ...");

let mut ctxt = BlockGenCtxt {
outer,
args: defn.parameters.iter().cloned().collect(),
@@ -731,8 +804,6 @@ fn compile_block(outer: &mut dyn GenCtxt, defn: &ast::Block) -> Option<Block> {
nb_params: ctxt.args.len(),
};

// println!("(system) compiled block !");

Some(block)
}

@@ -901,11 +972,5 @@ pub fn compile_class(
instance_class_mut.methods = instance_class_ctxt.methods;
drop(instance_class_mut);

// for method in instance_class.borrow().methods.values() {
// println!("{}", method);
// }

// println!("compiled '{}' !", defn.name);

Some(instance_class)
}
1 change: 1 addition & 0 deletions som-interpreter-bc/src/interpreter.rs
Original file line number Diff line number Diff line change
@@ -254,6 +254,7 @@ impl Interpreter {
// // };
// }

// dbg!(&frame.borrow().get_method().signature);
// if &frame.borrow().get_method().signature == "resolve:" {
// println!("cur bc: {}", bytecode);
// print!("");