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

Add Structs and Arrays #2

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
93b5cba
Add projection functors.
ritabt Jul 9, 2020
2c3740d
Update projection functor.
elliottslaughter Jul 9, 2020
3ddcbce
add proj_functor in Petra
Jul 11, 2020
39c3c38
add proj_functor in Petra
Jul 11, 2020
14d052c
Change setup proj_functor
Jul 12, 2020
74932b9
Change setup proj_functor
Jul 12, 2020
12ec589
Add VoidType
Jul 14, 2020
c4ceb7c
Add Makefile
Jul 14, 2020
bff3fde
Fix type declaration bugs
Jul 14, 2020
239c362
add tests for structs
Jul 15, 2020
bbc39b6
fix type declaration bugs
Jul 17, 2020
377adca
add attributes to args
Jul 17, 2020
c28bd03
add attributes
Jul 17, 2020
d402738
make args pointers
Jul 19, 2020
92c856b
fix declaration bug
Jul 20, 2020
03e853b
add attributes to add_func_decl
Jul 22, 2020
1fc069a
add attributes to add_func_decl
Jul 22, 2020
43829b0
add attributes to add_func_decl
Jul 22, 2020
9f55a7e
Fix stubs
Jul 22, 2020
534ce6e
Fix None attribute
Jul 22, 2020
aff07c0
Fix None attribute
Jul 22, 2020
f38deb7
add eq for pointers
Jul 22, 2020
637904c
add function attributes
Jul 31, 2020
403c779
add function to add_param_attributes
Aug 4, 2020
0a3c457
add addParamAttr and fix type errors
Aug 4, 2020
ac30c3e
Add option to add call params
Aug 6, 2020
3498fce
fix error in adding params
Aug 6, 2020
9a7dcfb
add call parameter attributes
Aug 6, 2020
1b3375c
add get_target_machine()
Aug 14, 2020
514fdab
add get_target_machine()
Aug 14, 2020
dc80287
add support for call param
Aug 17, 2020
995a938
add paramAttr function
Aug 17, 2020
a7b391c
fix mypy error
Aug 24, 2020
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
1 change: 1 addition & 0 deletions petra/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .truth import And, Eq, Gt, Gte, Lt, Lte, Neq, Not, Or
from .type import (
Bool_t,
Void_t,
Float32_t,
Float64_t,
Int8_t,
Expand Down
9 changes: 6 additions & 3 deletions petra/call.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ class Call(Expr):
A function call expression.
"""

def __init__(self, name: str, args: List[Expr]):
def __init__(self, name: str, args: List[Expr], attributes: Optional[Tuple[str, ...]] = None):
self.name = name
self.args = args
self.t: Union[Tuple[()], Optional[Type]] = None
self.attributes = attributes
self.validate()

def get_type(self) -> Type:
Expand Down Expand Up @@ -63,7 +64,9 @@ def typecheck(self, ctx: TypeContext) -> None:
def codegen(self, builder: ir.IRBuilder, ctx: CodegenContext) -> ir.Value:
def codegen_arg(arg: Expr) -> ir.Value:
return arg.codegen(builder, ctx)

args = tuple(map(codegen_arg, self.args))
func = ctx.funcs[self.name]
return builder.call(func, args)
output = builder.call(func, args)
if self.attributes is not None :
output.addParamAttr(self.attributes)
return output
12 changes: 10 additions & 2 deletions petra/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import re

from llvmlite import ir
from typing import Dict, List, Tuple
from typing import Dict, List, Tuple, Optional

from .block import Block
from .codegen import CodegenContext
Expand All @@ -28,11 +28,13 @@ def __init__(
t_out: Ftypeout,
block: Block,
functypes: Dict[str, Tuple[Ftypein, Ftypeout]],
attributes: Optional[Tuple[Tuple[str, ...], ...]] = None,
):
self.name = name
self.args = args
self.t_out = t_out
self.block = block
self.attributes = attributes
self.validate()
# Initial typecontext should contain arguments
ctx = TypeContext(functypes, t_out)
Expand Down Expand Up @@ -62,13 +64,19 @@ def typecheck(self, ctx: TypeContext) -> None:
self.block.typecheck(ctx)

def codegen(self, module: ir.Module, funcs: Dict[str, ir.Function]) -> None:

block = funcs[self.name].append_basic_block(name="start")
builder = ir.IRBuilder(block)
ctx = CodegenContext(funcs)
# Treat function arguments as variables declared at the beginning.
for i, arg in enumerate(self.args):
var = builder.alloca(arg.get_type().llvm_type(), name=arg.unique_name())
if self.attributes is not None and i < len(self.attributes) and self.attributes[i] is not None:
x: ir.Argument = funcs[self.name].args[i]
for a in self.attributes[i]:
x.add_attribute(a)
# FIXME: I'm not sure why I can't get this to type check
builder.store(funcs[self.name].args[i], var) # type: ignore
ctx.vars[arg] = var
self.block.codegen(builder, ctx)


69 changes: 44 additions & 25 deletions petra/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from __future__ import annotations # necessary to avoid forward declarations
from llvmlite import ir, binding
from typing import Dict, List, Tuple
from typing import Dict, List, Tuple, Optional

from .block import Block
from .codegen import convert_func_type
Expand All @@ -18,24 +18,51 @@ class Program(object):
A Petra program. Petra programs can be codegen'ed to LLVM.
"""

llvm_initialized: bool = False

def __init__(self, name: str):
self.module = ir.Module(name=name)
self.functypes: Dict[str, Tuple[Ftypein, Ftypeout]] = dict()
self.funcs: Dict[str, ir.Function] = dict()
binding.initialize()
binding.initialize_native_target()
binding.initialize_native_asmprinter()
target: binding.Target = binding.Target.from_default_triple()
self.target_machine: binding.TargetMachine = target.create_target_machine()

def add_func_decl(self, name: str, t_in: Ftypein, t_out: Ftypeout) -> Program:
def add_func_decl(
self,
name: str,
t_in: Ftypein,
t_out: Ftypeout,
attributes: Optional[Tuple[Tuple[str, ...], ...]] = None,
func_attributes: Optional[Tuple[str, ...]] = None,
) -> Program:
if name in self.functypes:
raise Exception("Function %s already exists in program." % name)
self.functypes[name] = (t_in, t_out)
self.funcs[name] = ir.Function(
self.module, convert_func_type(t_in, t_out), name
)
if attributes is not None:
for i in range(len(attributes)):
if attributes[i] is None:
continue
x: ir.Argument = self.funcs[name].args[i]
for a in attributes[i]:
x.add_attribute(a)
if func_attributes is not None:
for a in func_attributes:
if a is not None:
self.funcs[name].attributes.add(a)
return self

def add_func(
self, name: str, args: Tuple[Symbol, ...], t_out: Ftypeout, block: Block,
self,
name: str,
args: Tuple[Symbol, ...],
t_out: Ftypeout,
block: Block,
attributes: Optional[Tuple[Tuple[str, ...], ...]] = None,
func_attributes: Optional[Tuple[str, ...]] = None,
) -> Program:
if name in self.functypes:
raise Exception("Function %s already exists in program." % name)
Expand All @@ -44,40 +71,32 @@ def add_func(
self.funcs[name] = ir.Function(
self.module, convert_func_type(t_in, t_out), name
)
func = Function(name, args, t_out, block, self.functypes)
func = Function(name, args, t_out, block, self.functypes, attributes)
if func_attributes is not None:
for a in func_attributes:
if a is not None:
self.funcs[name].attributes.add(a)
func.codegen(self.module, self.funcs)
return self

def to_llvm(self) -> str:
return str(self.module)

def save_object(self, filename: str) -> None:
if not self.llvm_initialized:
self.llvm_initialized = True
binding.initialize()
binding.initialize_native_target()
binding.initialize_native_asmprinter()
# FIXME: Not sure why MyPy can't type check this, maybe a bug
target = binding.Target.from_default_triple() # type: ignore
target_machine = target.create_target_machine()
backing_mod = binding.parse_assembly(self.to_llvm())
with open(filename, "wb") as f:
f.write(target_machine.emit_object(backing_mod))
f.write(self.target_machine.emit_object(backing_mod))

def compile(self) -> binding.ExecutionEngine:
if not self.llvm_initialized:
self.llvm_initialized = True
binding.initialize()
binding.initialize_native_target()
binding.initialize_native_asmprinter()
# FIXME: Not sure why MyPy can't type check this, maybe a bug
target = binding.Target.from_default_triple() # type: ignore
target_machine = target.create_target_machine()
print(self.to_llvm())
backing_mod = binding.parse_assembly(self.to_llvm())
engine = binding.create_mcjit_compiler(backing_mod, target_machine)
engine = binding.create_mcjit_compiler(backing_mod, self.target_machine)
engine.finalize_object()
engine.run_static_constructors()
return engine

def get_target_machine(self) -> binding.TargetMachine:
return self.target_machine

def load_library(self, filename: str) -> None:
binding.load_library_permanently(filename)
binding.load_library_permanently(filename)
Loading