Skip to content

Commit

Permalink
Merge pull request #15 from GlowingScrewdriver/memory-and-pointers
Browse files Browse the repository at this point in the history
Add support for contiguous memory allocation and pointers
  • Loading branch information
chsasank authored Jun 3, 2024
2 parents 4cdf3c0 + f437726 commit 486881e
Show file tree
Hide file tree
Showing 22 changed files with 379 additions and 31 deletions.
25 changes: 19 additions & 6 deletions src/backend/brilisp.scm
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,17 @@
(args (rest header))
(instrs (rest (rest expr))))
`((name . ,name)
(type . ,type)
(type . ,(gen-type type))
(args . ,(map-vec gen-arg args))
(instrs . ,(map-vec gen-instr instrs)))))

(define (gen-arg arg)
`((name . ,(first arg)) (type . ,(second arg))))
`((name . ,(first arg)) (type . ,(gen-type (second arg)))))

(define (gen-type type)
(if (list? type)
`((,(first type) . ,(gen-type (second type))))
type))

(define (gen-instr instr)
(define (const? instr)
Expand All @@ -50,20 +55,20 @@
(let ((to (second instr))
(from (third instr)))
`((op . const)
(type . ,(second to))
(type . ,(gen-type (second to)))
(dest . ,(first to))
(value . ,(second from)))))

(define (value? instr)
(and (eq? (first instr) 'set)
(memq (first (third instr))
'(add mul sub div eq lt gt le ge not and or))))
'(add mul sub div eq lt gt le ge not and or alloc load ptradd id))))

(define (gen-value-instr instr)
(let ((to (second instr))
(from (third instr)))
`((op . ,(first from))
(type . ,(second to))
(type . ,(gen-type (second to)))
(dest . ,(first to))
(args . ,(list->vector (rest from))))))

Expand All @@ -81,7 +86,7 @@
(let ((to (second instr))
(from (third instr)))
`((op . call)
(type . ,(second to))
(type . ,(gen-type (second to)))
(dest . ,(first to))
(funcs . ,(vector (second from)))
(args . ,(list->vector (rest (rest from)))))))
Expand Down Expand Up @@ -113,6 +118,13 @@
(define (gen-nop-instr instr)
`((op . nop)))

(define (store? instr)
(eq? (first instr) 'store))

(define (gen-store-instr instr)
`((op . store)
(args . ,(list->vector (rest instr)))))

(cond
((const? instr) (gen-const-instr instr))
((value? instr) (gen-value-instr instr))
Expand All @@ -122,6 +134,7 @@
((label? instr) (gen-label-instr instr))
((br? instr) (gen-br-instr instr))
((nop? instr) (gen-nop-instr instr))
((store? instr) (gen-store-instr instr))
(else (error "unknown instruction: " instr))))

(bril (rest (read)))
100 changes: 75 additions & 25 deletions src/backend/llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
References:
1. https://github.com/eliben/pykaleidoscope/
2. https://llvm.org/docs/tutorial/
Assumes BRIL is in SSA form
"""

import sys
Expand Down Expand Up @@ -47,7 +45,12 @@ def generate(self, bril_prog):
self.gen_function(fn)

def gen_type(self, type):
if type == "int":
if isinstance(type, dict):
if "ptr" in type:
return self.gen_type(type["ptr"]).as_pointer()
else:
raise CodegenError(f"Unknown type {type}")
elif type == "int":
return ir.IntType(32)
elif type == "void":
return ir.VoidType()
Expand Down Expand Up @@ -158,29 +161,76 @@ def gen_comp(instr):
),
)

def gen_alloc(instr):
pointer_type = self.gen_type(instr.type)
self.declare_var(pointer_type, instr.dest)
self.gen_symbol_store(
instr.dest,
self.builder.alloca(
pointer_type.pointee, size=self.gen_var(instr.args[0])
),
)

def gen_store(instr):
ptr = self.gen_symbol_load(instr.args[0])
self.builder.store(self.gen_var(instr.args[1]), ptr)

def gen_load(instr):
self.declare_var(self.gen_type(instr.type), instr.dest)
ptr = self.gen_symbol_load(instr.args[0])
self.gen_symbol_store(instr.dest, self.builder.load(ptr))

def gen_ptradd(instr):
self.declare_var(self.gen_type(instr.type), instr.dest)
self.gen_symbol_store(
instr.dest,
self.builder.gep(
self.gen_var(instr.args[0]),
[self.gen_var(arg) for arg in instr["args"][1:]],
),
)

def gen_id(instr):
self.declare_var(self.gen_type(instr.type), instr.dest)
self.gen_symbol_store(instr.dest, self.gen_symbol_load(instr.args[0]))

for instr in instrs:
if "label" in instr:
gen_label(instr)
elif self.builder.block.is_terminated:
pass # Do not codegen for unreachable code
elif instr.op == "nop":
pass
elif instr.op == "jmp":
gen_jmp(instr)
elif instr.op == "br":
gen_br(instr)
elif instr.op == "call":
gen_call(instr)
elif instr.op == "ret":
gen_ret(instr)
elif instr.op == "const":
gen_const(instr)
elif instr.op in value_ops:
gen_value(instr)
elif instr.op in cmp_ops:
gen_comp(instr)
else:
raise CodegenError(f"Unknown op in the instruction: {dict(instr)}")
try:
if "label" in instr:
gen_label(instr)
elif self.builder.block.is_terminated:
pass # Do not codegen for unreachable code
elif instr.op == "nop":
pass
elif instr.op == "jmp":
gen_jmp(instr)
elif instr.op == "br":
gen_br(instr)
elif instr.op == "call":
gen_call(instr)
elif instr.op == "ret":
gen_ret(instr)
elif instr.op == "const":
gen_const(instr)
elif instr.op == "alloc":
gen_alloc(instr)
elif instr.op == "store":
gen_store(instr)
elif instr.op == "load":
gen_load(instr)
elif instr.op == "ptradd":
gen_ptradd(instr)
elif instr.op == "id":
gen_id(instr)
elif instr.op in value_ops:
gen_value(instr)
elif instr.op in cmp_ops:
gen_comp(instr)
else:
raise CodegenError(f"Unknown op in the instruction: {dict(instr)}")
except Exception as e:
print(f"Exception: {e}; in instruction {instr}:")
raise e

def gen_function_prototype(self, fn):
funcname = fn.name
Expand Down
1 change: 1 addition & 0 deletions src/backend/tests/brilisp/access.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8989898
20 changes: 20 additions & 0 deletions src/backend/tests/brilisp/access.sexp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(brilisp
(bril-define ((print int) (n int)))

(bril-define ((main int))
(set (inc int) (const 1))
(set (v int) (const 4545454))
(set (max int) (const 8989898))
(set (p (ptr int)) (alloc v))
(set (count int) (const 0))

(label lbl)
(set (count int) (add count inc))
(store p v)
(set (val int) (load p))
(set (loop bool) (ge count max))
(br loop end lbl)

(label end)
(set (tmp int) (call print count))
(ret tmp)))
1 change: 1 addition & 0 deletions src/backend/tests/brilisp/access_many.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8989898
21 changes: 21 additions & 0 deletions src/backend/tests/brilisp/access_many.sexp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(brilisp
(bril-define ((print int) (n int)))

(bril-define ((main int))
(set (inc int) (const 1))
(set (v int) (const 4545454))
(set (max int) (const 8989898))
(set (arr (ptr int)) (alloc v))
(set (count int) (const 0))

(label lbl)
(set (arr_i (ptr int)) (ptradd arr count))
(set (count int) (add count inc))
(store arr_i v)
(set (val int) (load arr_i))
(set (loop bool) (ge count max))
(br loop end lbl)

(label end)
(set (tmp int) (call print count))
(ret tmp)))
1 change: 1 addition & 0 deletions src/backend/tests/brilisp/access_ptr.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8989898
22 changes: 22 additions & 0 deletions src/backend/tests/brilisp/access_ptr.sexp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(brilisp
(bril-define ((print int) (n int)))

(bril-define ((main int))
(set (inc int) (const 1))
(set (v int) (const 4545))
(set (max int) (const 8989898))
(set (p (ptr int)) (alloc v))
(set (arr (ptr (ptr int))) (alloc v))
(set (count int) (const 0))

(label lbl)
(set (arr_i (ptr (ptr int))) (ptradd arr count))
(set (count int) (add count inc))
(store arr p)
(set (val (ptr int)) (load arr_i))
(set (loop bool) (ge count max))
(br loop end lbl)

(label end)
(set (tmp int) (call print count))
(ret tmp)))
1 change: 1 addition & 0 deletions src/backend/tests/brilisp/alloc.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
25 changes: 25 additions & 0 deletions src/backend/tests/brilisp/alloc.sexp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(brilisp
(bril-define ((print int) (n int)))

(bril-define ((print_bool int) (b bool))
(set (T int) (const 1))
(set (F int) (const 0))
(br b print_true print_false)
(label print_true)
(set (tmp int) (call print T))
(ret tmp)
(label print_false)
(set (tmp int) (call print F))
(ret tmp))

(bril-define ((main int))
(set (v int) (const 4))
(set (o1 int) (const 1))
(set (bp (ptr bool)) (alloc v))
(set (bp2 (ptr bool)) (ptradd bp o1))
(set (b bool) (const true))
(store bp b)
(store bp2 b)
(set (b bool) (load bp2))
(set (tmp int) (call print_bool b))
(ret tmp)))
1 change: 1 addition & 0 deletions src/backend/tests/brilisp/arr_sum.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
55
28 changes: 28 additions & 0 deletions src/backend/tests/brilisp/arr_sum.sexp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
(brilisp
(bril-define ((print int) (n int)))

(bril-define ((main int))
(set (len int) (const 10))
(set (arr (ptr int)) (alloc len))
(set (sum int) (const 0))
(set (idx int) (const 0))
(set (one int) (const 1))

(label init)
(set (arr_i (ptr int)) (ptradd arr idx))
(set (idx int) (add idx one))
(store arr_i idx)
(set (loop bool) (lt idx len))
(br loop init calc)

(label calc)
(set (idx int) (sub idx one))
(set (arr_i (ptr int)) (ptradd arr idx))
(set (v int) (load arr_i))
(set (sum int) (add sum v))
(set (loop bool) (ge idx one))
(br loop calc out)

(label out)
(set (tmp int) (call print sum))
(ret tmp)))
1 change: 1 addition & 0 deletions src/backend/tests/brilisp/fib.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
34
37 changes: 37 additions & 0 deletions src/backend/tests/brilisp/fib.sexp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
(brilisp
(bril-define ((print int) (n int)))

(bril-define ((main int))
(set (one int) (const 1))
(set (i int) (const 2))
(set (i_m_1 int) (const 1))
(set (i_m_2 int) (const 0))
(set (n int) (const 10))
(set (seq (ptr int)) (alloc n))

(set (v int) (const 0))
(store seq v)
(set (v int) (const 1))
(set (p (ptr int)) (ptradd seq i_m_1))
(store p v)

(label calc_i)
(set (p_m_2 (ptr int)) (ptradd seq i_m_2))
(set (p_m_1 (ptr int)) (ptradd seq i_m_1))
(set (v_m_2 int) (load p_m_2))
(set (v_m_1 int) (load p_m_1))
(set (v int) (add v_m_1 v_m_2))
(set (p (ptr int)) (ptradd seq i))
(store p v)
(set (i_m_1 int) (add i_m_1 one))
(set (i_m_2 int) (add i_m_2 one))
(set (i int) (add i one))
(set (loop bool) (le i n))
(br loop calc_i out)

(label out)
(set (i int) (sub n one))
(set (p (ptr int)) (ptradd seq i))
(set (v int) (load p))
(set (tmp int) (call print v))
(ret tmp)))
1 change: 1 addition & 0 deletions src/backend/tests/brilisp/mem_id.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7
13 changes: 13 additions & 0 deletions src/backend/tests/brilisp/mem_id.sexp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(brilisp
(bril-define ((print int) (n int)))

(bril-define ((main int))
(set (v int) (const 1))
(set (p (ptr int)) (alloc v))
(set (v int) (const 7))
(store p v)

(set (p2 (ptr int)) (id p))
(set (v int) (load p))
(set (tmp int) (call print v))
(ret tmp)))
Empty file.
9 changes: 9 additions & 0 deletions src/backend/tests/brilisp/ptr_call.sexp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(brilisp
(bril-define ((funcA void) (p (ptr int)))
(ret))

(bril-define ((main void))
(set (five int) (const 5))
(set (x (ptr int)) (alloc five))
(set (tmp void) (call funcA x))
(ret)))
Empty file.
Loading

0 comments on commit 486881e

Please sign in to comment.