Skip to content

Commit

Permalink
centralize Symbol::is_dead for DCE
Browse files Browse the repository at this point in the history
  • Loading branch information
mustafaquraish committed Nov 17, 2024
1 parent 5cae03e commit a13e2c3
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 46 deletions.
6 changes: 0 additions & 6 deletions compiler/ast/nodes.oc
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ struct Variable {

//* Original parsed type, for keeping track of locations
parsed_type: &Type

is_dead: bool
}

def Variable::new(type: &Type): &Variable {
Expand All @@ -84,7 +82,6 @@ struct Structure {
type: &Type
is_union: bool
span: Span
is_dead: bool

format_spec: str
format_args: str
Expand Down Expand Up @@ -116,7 +113,6 @@ struct Enum {
shared_fields: &Vector<&Variable>
variants: &Vector<&EnumVariant>
type: &Type
is_dead: bool

// To quickly check if this is a "normal" enum with no values stored
has_values: bool
Expand Down Expand Up @@ -229,8 +225,6 @@ struct Function {
exits: bool
is_static: bool
parent_type: &Type

is_dead: bool
}

def Function::new(): &Function {
Expand Down
7 changes: 5 additions & 2 deletions compiler/ast/scopes.oc
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ enum SymbolType {
Namespace
Variable
Constant
Closure
ClosedVariable

ClosureType // Represents the closure type, eg: @fn(i32, i32): str
Closure // Represents an actual closure function, eg: |a: 32, b: 32|: str { ... }
ClosedVariable // Represents a variable captured by a closure

Enum
EnumVariant
Expand Down Expand Up @@ -125,6 +127,7 @@ struct Symbol {
extern_name: str

template: &Template
is_dead: bool = false
}

def Symbol::out_name(&this): str {
Expand Down
3 changes: 2 additions & 1 deletion compiler/lsp/utils.oc
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def try_gen_expr_string(expr: &AST): str => match expr.type {
}

def gen_hover_string(sym: &Symbol): str => match sym.type {
TypeDef => gen_type_string(sym.u.type_def)
ClosureType | TypeDef => gen_type_string(sym.u.type_def)
Function => gen_type_string(sym.u.func.type)
Variable => {
let sb = Buffer::make()
Expand Down Expand Up @@ -238,6 +238,7 @@ def get_symbol_typedef(sym: &Symbol): &Type => match sym.type {
Enum => sym.u.enom.type
EnumVariant => sym.u.enum_var.parent.type
EnumField => sym.u.enum_field.variant.parent.type
ClosureType => sym.u.type_def
Closure => sym.u.func.type
ClosedVariable => sym.u.closed_var.orig.type
// else => std::panic(f"get_symbol_typedef: unhandled symbol type: {sym.type}")
Expand Down
40 changes: 19 additions & 21 deletions compiler/passes/code_generator.oc
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ def CodeGenerator::gen_yield_expression(&this, expr: &AST) {

def CodeGenerator::gen_constant(&this, node: &AST) {
let const_ = node.u.var_decl
if const_.is_dead return
if const_.sym.is_dead return

if not const_.sym.is_extern {
.gen_indent()
Expand All @@ -314,7 +314,7 @@ def CodeGenerator::gen_constants(&this, ns: &Namespace) {
def CodeGenerator::gen_global_variables(&this, ns: &Namespace) {
for node : ns.variables.iter() {
let var = node.u.var_decl
if var.is_dead continue
if var.sym.is_dead continue
if not var.sym.is_extern {
.gen_var_declaration(node)
.out += ";\n"
Expand Down Expand Up @@ -1411,7 +1411,7 @@ def CodeGenerator::gen_function(&this, func: &Function) {
if struc.sym.is_templated() then return
}
if func.sym.is_templated() then return
if func.is_dead then return
if func.sym.is_dead then return

.gen_debug_info(func.sym.span)
.gen_function_decl(func)
Expand Down Expand Up @@ -1464,7 +1464,7 @@ def CodeGenerator::gen_function_decl_toplevel(&this, func: &Function) {
let sym = instance.resolved
assert sym.type == Function
let func = sym.u.func
if func.is_dead then continue
if func.sym.is_dead then continue

.gen_function_decl(func)
if func.exits then .out += " __attribute__((noreturn))"
Expand All @@ -1473,7 +1473,7 @@ def CodeGenerator::gen_function_decl_toplevel(&this, func: &Function) {
return
}

if func.is_dead then return
if func.sym.is_dead then return
.gen_function_decl(func)
if func.exits then .out += " __attribute__((noreturn))"
.out += ";\n"
Expand Down Expand Up @@ -1524,7 +1524,7 @@ def CodeGenerator::gen_enum_dbg_method(&this, enom: &Enum) {

def CodeGenerator::gen_struct_typedef(&this, struc: &Structure) {
if struc.sym.is_extern return
if struc.is_dead return
if struc.sym.is_dead return

let strufull_name = struc.sym.out_name()
if struc.is_union {
Expand All @@ -1535,11 +1535,13 @@ def CodeGenerator::gen_struct_typedef(&this, struc: &Structure) {
}

def CodeGenerator::gen_closure_type_typedef(&this, sym: &Symbol) {
if sym.is_dead return
let name = sym.out_name()
.out <<= `typedef struct {name} {name};\n`
}

def CodeGenerator::gen_closure_type_def(&this, sym: &Symbol) {
if sym.is_dead return
let name = sym.out_name()
let type = sym.u.type_def
.out <<= `struct {name} \{\n`
Expand All @@ -1558,12 +1560,14 @@ def CodeGenerator::gen_closure_type_def(&this, sym: &Symbol) {
}

def CodeGenerator::gen_closure_typedef(&this, clos: &Function) {
if clos.sym.is_dead return
let name = clos.sym.out_name()
let type_name = cls::ctx_type(clos)
.out <<= `typedef struct {type_name} {type_name};\n`
}

def CodeGenerator::gen_closure_def(&this, clos: &Function) {
if clos.sym.is_dead return
let name = clos.sym.out_name()

let type_name = cls::ctx_type(clos)
Expand All @@ -1586,6 +1590,7 @@ def CodeGenerator::gen_closure_def(&this, clos: &Function) {
}

def CodeGenerator::gen_closure_func_decl(&this, clos: &Function) {
if clos.sym.is_dead return
let name = clos.sym.out_name()
let type = clos.type

Expand All @@ -1602,6 +1607,7 @@ def CodeGenerator::gen_closure_func_decl(&this, clos: &Function) {
}

def CodeGenerator::gen_closure_func(&this, clos: &Function) {
if clos.sym.is_dead return
let name = clos.sym.out_name()
let type = clos.type

Expand All @@ -1627,18 +1633,22 @@ def CodeGenerator::gen_closure_func(&this, clos: &Function) {
def CodeGenerator::gen_sym_typedef(&this, sym: &Symbol) => match sym.type {
Structure => .gen_struct_typedef(sym.u.struc)
Enum => .gen_enum_typedef(sym.u.enom)
Closure => .gen_closure_typedef(sym.u.func)
ClosureType => .gen_closure_type_typedef(sym)
else => assert false, `Unhandled symbol type in CodeGenerator::gen_typedef: {sym.type}`
}

def CodeGenerator::gen_sym_def(&this, sym: &Symbol) => match sym.type {
Structure => .gen_struct_def(sym.u.struc)
Enum => .gen_enum_def(sym.u.enom)
Closure => .gen_closure_def(sym.u.func)
ClosureType => .gen_closure_type_def(sym)
else => assert false, `Unhandled symbol type in CodeGenerator::gen_def: {sym.type}`
}

def CodeGenerator::gen_enum_typedef(&this, enom: &Enum) {
if enom.sym.is_extern return
if enom.is_dead return
if enom.sym.is_dead return

let name = enom.sym.out_name()
if enom.has_values {
Expand All @@ -1651,7 +1661,7 @@ def CodeGenerator::gen_enum_typedef(&this, enom: &Enum) {

def CodeGenerator::gen_struct_def(&this, struc: &Structure) {
if struc.sym.is_extern return
if struc.is_dead then return
if struc.sym.is_dead then return

let strufull_name = struc.sym.out_name()
if struc.is_union {
Expand All @@ -1672,7 +1682,7 @@ def CodeGenerator::gen_struct_def(&this, struc: &Structure) {
}

def CodeGenerator::gen_enum_def(&this, enom: &Enum) {
if enom.is_dead then return
if enom.sym.is_dead then return

let name = enom.sym.out_name()
defer .gen_enum_dbg_method(enom)
Expand Down Expand Up @@ -1737,24 +1747,12 @@ def CodeGenerator::generate(&this): str {
for sym in .o.program.ordered_symbols.iter() {
.gen_sym_typedef(sym)
}
for cty in .o.program.closure_types.iter() {
.gen_closure_type_typedef(cty.sym)
}
for clos in .o.program.closures.iter() {
.gen_closure_typedef(clos)
}
.out += "\n"

.out += "/* Structs */\n"
for sym in .o.program.ordered_symbols.iter() {
.gen_sym_def(sym)
}
for cty in .o.program.closure_types.iter() {
.gen_closure_type_def(cty.sym)
}
for clos in .o.program.closures.iter() {
.gen_closure_def(clos)
}

.out += "/* function declarations */\n"
.gen_function_decls(.o.program.global)
Expand Down
29 changes: 15 additions & 14 deletions compiler/passes/mark_dead_code.oc
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ def MarkDeadCode::mark_sym(&this, sym: &Symbol) {
Function => .mark_function(sym.u.func)
Structure => .mark_struct(sym.u.struc)
Enum => .mark_enum(sym.u.enom)

Constant | Variable => {
.mark_type(sym.u.var.type)
.mark(sym.u.var.default_value)
sym.u.var.is_dead = false
sym.u.var.sym.is_dead = false
}
Closure => .mark_function(sym.u.closure)
ClosureType => .mark_type(sym.u.type_def)
ClosedVariable => .mark_sym(sym.u.closed_var.orig.sym)
else => {}
}
}
Expand All @@ -55,7 +57,7 @@ def MarkDeadCode::mark_function(&this, f: &Function) {
if not f? or .done.contains(f as u64) return
.done.add(f as u64)

f.is_dead = false
f.sym.is_dead = false
.mark(f.body)

for param : f.params.iter() {
Expand All @@ -68,7 +70,7 @@ def MarkDeadCode::mark_type(&this, typ: &Type) {
match typ.base {
Pointer | Alias => .mark_type(typ.u.ptr)
Array => .mark_type(typ.u.arr.elem_type)
FunctionPtr => {
FunctionPtr | Closure => {
let ft = typ.u.func
.mark_type(ft.return_type)
for param : ft.params.iter() {
Expand All @@ -90,7 +92,7 @@ def MarkDeadCode::mark_struct(&this, s: &Structure) {
if not s? or .done.contains(s as u64) return
.done.add(s as u64)

s.is_dead = false
s.sym.is_dead = false
for field : s.fields.iter() {
.mark_type(field.type)
}
Expand All @@ -100,7 +102,7 @@ def MarkDeadCode::mark_enum(&this, e: &Enum) {
if not e? or .done.contains(e as u64) return
.done.add(e as u64)

e.is_dead = false
e.sym.is_dead = false
for var in e.variants.iter() {
.mark_sym(var.sym)
for field in var.specific_fields.iter() {
Expand Down Expand Up @@ -223,14 +225,7 @@ def MarkDeadCode::find_main_function(&this, program: &Program): &Function {

def MarkDeadCode::mark_sym_as_dead_by_default(&this, sym: &Symbol) {
if not sym? return

match sym.type {
Function => sym.u.func.is_dead = true
Structure => sym.u.struc.is_dead = true
Enum => sym.u.enom.is_dead = true
Constant | Variable => sym.u.var.is_dead = true
else => {}
}
sym.is_dead = true

if sym.template? {
for instance : sym.template.instances.iter() {
Expand Down Expand Up @@ -271,6 +266,12 @@ def MarkDeadCode::run(program: &Program) {
pass.mark_sym_as_dead_by_default(c.u.var_decl.sym)
}
}
for cty in program.closure_types.iter() {
pass.mark_sym_as_dead_by_default(cty.sym)
}
for clos in program.closures.iter() {
pass.mark_sym_as_dead_by_default(clos.sym)
}

// For constants and variables, mark their types as used
if main? {
Expand Down
2 changes: 1 addition & 1 deletion compiler/passes/mod.oc
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def run_typecheck_passes(program: &Program) {

//* Generates code for the program and returns it
def run_codegen_passes(program: &Program): str {
ReorderSymbols::run(program)
MarkDeadCode::run(program)
ReorderSymbols::run(program)
let code = CodeGenerator::run(program)
return code
}
2 changes: 1 addition & 1 deletion compiler/passes/typechecker.oc
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def TypeChecker::get_closure_type(&this, params: &Vector<&Variable>, return_type
let closure_name = `_ClosureTy_{.o.program.closure_types.size}`
.o.program.closure_types.push(canon)

let sym = Symbol::new(TypeDef, ns: null, closure_name, closure_name, closure_name, span)
let sym = Symbol::new(ClosureType, ns: null, closure_name, closure_name, closure_name, span)
sym.u.type_def = canon
canon.sym = sym
}
Expand Down

0 comments on commit a13e2c3

Please sign in to comment.