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

[SSA] Fix up to_ssa.py and add test cases #119

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 20 additions & 6 deletions bril-ts/brili.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class Heap<X> {
return this.storage.size == 0;
}

private count = 0;
private count = 1;
private getNewBase():number {
let val = this.count;
this.count++;
Expand All @@ -64,19 +64,33 @@ export class Heap<X> {
return;
}

private getNullKey(): Key {
return new Key(0, 0);
}

private isNull(key: Key): boolean {
return key.base == 0;
}

alloc(amt:number): Key {
if (amt <= 0) {
if (amt < 0) {
throw error(`cannot allocate ${amt} entries`);
}
let base = this.getNewBase();
this.storage.set(base, new Array(amt))
return new Key(base, 0);
if (amt == 0) {
return this.getNullKey();
} else {
let base = this.getNewBase();
this.storage.set(base, new Array(amt))
return new Key(base, 0);
}
}

free(key: Key) {
if (this.storage.has(key.base) && key.offset == 0) {
this.freeKey(key);
this.storage.delete(key.base);
} else if (this.isNull(key) && key.offset == 0) {
// no-op
} else {
throw error(`Tried to free illegal memory location base: ${key.base}, offset: ${key.offset}. Offset must be 0.`);
}
Expand Down Expand Up @@ -205,7 +219,7 @@ function findFunc(func: bril.Ident, funcs: readonly bril.Function[]) {
function alloc(ptrType: bril.ParamType, amt:number, heap:Heap<Value>): Pointer {
if (typeof ptrType != 'object') {
throw error(`unspecified pointer type ${ptrType}`);
} else if (amt <= 0) {
} else if (amt < 0) {
throw error(`must allocate a positive amount of memory: ${amt} <= 0`);
} else {
let loc = heap.alloc(amt)
Expand Down
29 changes: 23 additions & 6 deletions brilirs/src/interp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,29 @@ impl Heap {
self.memory.is_empty()
}

fn null_base(&self) -> usize {
0
}

fn is_null(&self, key: &Pointer) -> bool {
key.base == self.null_base()
}

fn alloc(&mut self, amount: i64, ptr_type: bril_rs::Type) -> Result<Value, InterpError> {
if amount < 0 {
return Err(InterpError::CannotAllocSize(amount));
}
let base = self.base_num_counter;
self.base_num_counter += 1;
self
.memory
.insert(base, vec![Value::default(); amount as usize]);
let base = if amount > 0 {
// Add first to reserve base == 0 for null
self.base_num_counter += 1;
let base = self.base_num_counter;
self
.memory
.insert(base, vec![Value::default(); amount as usize]);
base
} else {
self.null_base()
};
Ok(Value::Pointer(Pointer {
base,
offset: 0,
Expand All @@ -77,7 +91,10 @@ impl Heap {
}

fn free(&mut self, key: Pointer) -> Result<(), InterpError> {
if self.memory.remove(&key.base).is_some() && key.offset == 0 {
if self.is_null(&key) && key.offset == 0 {
// no-op
Ok(())
} else if self.memory.remove(&key.base).is_some() && key.offset == 0 {
Ok(())
} else {
Err(InterpError::IllegalFree(key.base, key.offset))
Expand Down
9 changes: 9 additions & 0 deletions examples/test/from_ssa/argwrite.bril
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ARGS: 3
@main(a: int) {
cond: bool = const true;
br cond .here .there;
.here:
a: int = const 5;
.there:
print a;
}
1 change: 1 addition & 0 deletions examples/test/from_ssa/argwrite.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5
14 changes: 14 additions & 0 deletions examples/test/from_ssa/if-const.bril
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@main() {
cond: bool = const true;
br cond .true .false;
.true:
a: int = const 0;
jmp .zexit;
.false:
b: int = const 1;
jmp .zexit;
# zexit to trigger a bug in to_ssa.py that depends on
# the order that basic blocks get renamed.
.zexit:
print a;
}
1 change: 1 addition & 0 deletions examples/test/from_ssa/if-const.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
17 changes: 17 additions & 0 deletions examples/test/from_ssa/if-ssa.bril
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# ARGS: true
@main(cond: bool) {
.entry:
a.1: int = const 47;
br cond .left .right;
.left:
a.2: int = add a.1 a.1;
jmp .zexit;
.right:
a.3: int = mul a.1 a.1;
jmp .zexit;
# zexit to trigger a bug in to_ssa.py that depends on
# the order that basic blocks get renamed.
.zexit:
a.4: int = phi .left a.2 .right a.3;
print a.4;
}
1 change: 1 addition & 0 deletions examples/test/from_ssa/if-ssa.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
94
14 changes: 14 additions & 0 deletions examples/test/from_ssa/if.bril
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# ARGS: false
@main(cond: bool) {
.entry:
a: int = const 47;
br cond .left .right;
.left:
a: int = add a a;
jmp .exit;
.right:
a: int = mul a a;
jmp .exit;
.exit:
print a;
}
1 change: 1 addition & 0 deletions examples/test/from_ssa/if.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2209
24 changes: 24 additions & 0 deletions examples/test/from_ssa/loop-branch.bril
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@func(): int {
n: int = const 5;
ret n;
}

@loop(infinite: bool, print: bool) {
.entry:
.loop.header:
br infinite .loop.body .loop.end;
.loop.body:
br print .loop.print .loop.next;
.loop.print:
v: int = call @func;
print v;
.loop.next:
jmp .loop.header;
.loop.end:
}

@main() {
infinite: bool = const false;
print: bool = const true;
call @loop infinite print;
}
Empty file.
14 changes: 14 additions & 0 deletions examples/test/from_ssa/loop.bril
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@main {
.entry:
i: int = const 1;
jmp .loop;
.loop:
max: int = const 10;
cond: bool = lt i max;
br cond .body .exit;
.body:
i: int = add i i;
jmp .loop;
.exit:
print i;
}
1 change: 1 addition & 0 deletions examples/test/from_ssa/loop.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16
14 changes: 14 additions & 0 deletions examples/test/from_ssa/selfloop.bril
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@main {
.entry:
one: int = const 1;
zero: int = const 0;
x: int = const 5;
.loop:
x: int = sub x one;
done: bool = eq x zero;
.br:
br done .exit .loop;
.exit:
print x;
ret;
}
1 change: 1 addition & 0 deletions examples/test/from_ssa/selfloop.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions examples/test/from_ssa/turnt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
command = "bril2json < {filename} | python ../../to_ssa.py | python ../../from_ssa.py | brili {args}"
13 changes: 13 additions & 0 deletions examples/test/from_ssa/while.bril
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# ARGS: 5
@main(a: int) {
.while.cond:
zero: int = const 0;
is_term: bool = eq a zero;
br is_term .while.finish .while.body;
.while.body:
one: int = const 1;
a: int = sub a one;
jmp .while.cond;
.while.finish:
print a;
}
1 change: 1 addition & 0 deletions examples/test/from_ssa/while.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
2 changes: 2 additions & 0 deletions examples/test/to_ssa/argwrite.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@main(a: int) {
.b1:
__undefined.int: int = const 0;
__undefined.bool: bool = const false;
cond.0: bool = const true;
br cond.0 .here .there;
.here:
Expand Down
6 changes: 4 additions & 2 deletions examples/test/to_ssa/if-const.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@main {
.b1:
__undefined.int: int = const 0;
__undefined.bool: bool = const false;
cond.0: bool = const true;
br cond.0 .true .false;
.true:
Expand All @@ -9,8 +11,8 @@
b.0: int = const 1;
jmp .zexit;
.zexit:
b.1: int = phi b.0 b.0 .false .true;
a.1: int = phi __undefined a.0 .false .true;
b.1: int = phi b.0 __undefined.int .false .true;
a.1: int = phi __undefined.int a.0 .false .true;
print a.1;
ret;
}
6 changes: 4 additions & 2 deletions examples/test/to_ssa/if-ssa.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@main(cond: bool) {
.entry:
__undefined.int: int = const 0;
__undefined.bool: bool = const false;
a.1.0: int = const 47;
br cond .left .right;
.left:
Expand All @@ -9,8 +11,8 @@
a.3.0: int = mul a.1.0 a.1.0;
jmp .zexit;
.zexit:
a.3.1: int = phi __undefined a.3.0 .left .right;
a.2.1: int = phi a.2.0 a.2.0 .left .right;
a.3.1: int = phi __undefined.int a.3.0 .left .right;
a.2.1: int = phi a.2.0 __undefined.int .left .right;
a.4.0: int = phi a.2.1 a.3.1 .left .right;
print a.4.0;
ret;
Expand Down
2 changes: 2 additions & 0 deletions examples/test/to_ssa/if.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@main(cond: bool) {
.entry:
__undefined.int: int = const 0;
__undefined.bool: bool = const false;
a.0: int = const 47;
br cond .left .right;
.left:
Expand Down
24 changes: 24 additions & 0 deletions examples/test/to_ssa/loop-branch.bril
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@func(): int {
n: int = const 5;
ret n;
}

@loop(infinite: bool, print: bool) {
.entry:
.loop.header:
br infinite .loop.body .loop.end;
.loop.body:
br print .loop.print .loop.next;
.loop.print:
v: int = call @func;
print v;
.loop.next:
jmp .loop.header;
.loop.end:
}

@main() {
infinite: bool = const false;
print: bool = const true;
call @loop infinite print;
}
34 changes: 34 additions & 0 deletions examples/test/to_ssa/loop-branch.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@func: int {
.b1:
__undefined.int: int = const 0;
n.0: int = const 5;
ret n.0;
}
@loop(infinite: bool, print: bool) {
.entry:
__undefined.int: int = const 0;
__undefined.bool: bool = const false;
jmp .loop.header;
.loop.header:
v.0: int = phi __undefined.int v.1 .entry .loop.next;
br infinite .loop.body .loop.end;
.loop.body:
br print .loop.print .loop.next;
.loop.print:
v.2: int = call @func;
print v.2;
jmp .loop.next;
.loop.next:
v.1: int = phi v.0 v.2 .loop.body .loop.print;
jmp .loop.header;
.loop.end:
ret;
}
@main {
.b1:
__undefined.bool: bool = const false;
infinite.0: bool = const false;
print.0: bool = const true;
call @loop infinite.0 print.0;
ret;
}
6 changes: 4 additions & 2 deletions examples/test/to_ssa/loop.out
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
@main {
.entry:
__undefined.int: int = const 0;
__undefined.bool: bool = const false;
i.0: int = const 1;
jmp .loop;
.loop:
max.0: int = phi __undefined max.1 .entry .body;
max.0: int = phi __undefined.int max.1 .entry .body;
i.1: int = phi i.0 i.2 .entry .body;
cond.0: bool = phi __undefined cond.1 .entry .body;
cond.0: bool = phi __undefined.bool cond.1 .entry .body;
max.1: int = const 10;
cond.1: bool = lt i.1 max.1;
br cond.1 .body .exit;
Expand Down
4 changes: 3 additions & 1 deletion examples/test/to_ssa/selfloop.out
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
@main {
.entry:
__undefined.int: int = const 0;
__undefined.bool: bool = const false;
one.0: int = const 1;
zero.0: int = const 0;
x.0: int = const 5;
jmp .loop;
.loop:
x.1: int = phi x.0 x.2 .entry .br;
done.0: bool = phi __undefined done.1 .entry .br;
done.0: bool = phi __undefined.bool done.1 .entry .br;
x.2: int = sub x.1 one.0;
done.1: bool = eq x.2 zero.0;
jmp .br;
Expand Down
Loading