Skip to content

Commit b8eb631

Browse files
committed
Optimizations
1 parent 664de9b commit b8eb631

File tree

5 files changed

+72
-12
lines changed

5 files changed

+72
-12
lines changed

compiler/asm_extensions.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ def __init__(self, pos, writer, namespace, page_size=64, **kwargs):
1212
'memory_buffer': 'mb',
1313
'memory_slot': ('ms_%d', range(self.page_size))
1414
})
15-
self.add_page()
15+
if page_size > 0:
16+
self.add_page()
1617

1718
def add_page(self):
1819
mbr = Var('memory_buffer')
@@ -113,6 +114,7 @@ def __init__(self):
113114
'MOVINDD': self.handle_mov_ind_d,
114115
'MOVINDS': self.handle_mov_ind_s
115116
})
117+
self.use_mem = False
116118

117119
def handle_ret(self):
118120
if not self.enable_sync:
@@ -122,6 +124,7 @@ def handle_ret(self):
122124

123125
def handle_mov_ind(self, src, s_off, dest, d_off):
124126
"""Move indirect src to indirect dest"""
127+
self.use_mem = True
125128
src, dest = self.get_src_dest(src, dest)
126129
s_off = self.resolve_ref(*s_off)
127130
d_off = self.resolve_ref(*d_off)
@@ -140,6 +143,7 @@ def handle_mov_ind(self, src, s_off, dest, d_off):
140143

141144
def handle_mov_ind_d(self, src, dest, d_off):
142145
"""Move src to indirect dest"""
146+
self.use_mem = True
143147
src, dest = self.get_src_dest(src, dest)
144148
offset = self.resolve_ref(*d_off)
145149
assert type(offset) == int
@@ -152,6 +156,7 @@ def handle_mov_ind_d(self, src, dest, d_off):
152156

153157
def handle_mov_ind_s(self, src, s_off, dest):
154158
"""Move indirect src to dest"""
159+
self.use_mem = True
155160
src, dest = self.get_src_dest(src, dest)
156161
offset = self.resolve_ref(*s_off)
157162
assert type(offset) == int

compiler/compiler.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,7 @@ def __init__(self, ir_downstream):
861861
self.current_function = None
862862
self.loop_attacher = LoopAttacher(None, None, self, None)
863863
self.python_functions = {}
864+
self.temp_slots = set()
864865
self.pragmas = {}
865866

866867
def import_py_lib(self, lib_exports):
@@ -918,6 +919,14 @@ def unique_label(self, label):
918919
self.local_labels[label] += 1
919920
return IR.Label('%s_%d' %(label, self.local_labels[label]))
920921

922+
def consume_slot(self, slot):
923+
if slot in self.temp_slots:
924+
self.temp_slots.remove(slot)
925+
self.emit(IR.Free(slot))
926+
927+
def virtual_slot(self, slot):
928+
self.temp_slots.add(slot)
929+
921930
### Pragmas
922931

923932
def visit_pragma(self, pragma):
@@ -1169,6 +1178,7 @@ def visit_func_decl(self, decl):
11691178
self.current_function = func_symbol
11701179

11711180
self.local_labels = {}
1181+
self.temp_slots.clear()
11721182

11731183
pragma = {}
11741184
# check pragmas
@@ -1342,6 +1352,7 @@ def visit_while_stmt(self, stmt):
13421352
self.emit(begin)
13431353
cond = self.visit_expression(stmt.cond)
13441354
self.emit(IR.JumpIfNot(end, cond))
1355+
self.consume_slot(cond)
13451356
self.visit_statement(stmt.body)
13461357
self.emit(IR.Jump(begin))
13471358
self.emit(end)
@@ -1355,21 +1366,23 @@ def visit_do_while_stmt(self, stmt):
13551366
self.emit(cond_label)
13561367
cond = self.visit_expression(stmt.cond)
13571368
self.emit(IR.JumpIf(begin, cond))
1369+
self.consume_slot(cond)
13581370
self.emit(end)
13591371

13601372
def visit_for_stmt(self, stmt):
13611373
with self.loop(continue_='for_cont', break_='end_for') as (after_label, end):
13621374
if stmt.init:
1363-
self.visit_expression(stmt.init)
1375+
self.consume_slot(self.visit_expression(stmt.init))
13641376
cond_label = self.unique_label('for')
13651377
self.emit(cond_label)
13661378
if stmt.cond:
13671379
cond = self.visit_expression(stmt.cond)
13681380
self.emit(IR.JumpIfNot(end, cond))
1381+
self.consume_slot(cond)
13691382
self.visit_statement(stmt.body)
13701383
self.emit(after_label)
13711384
if stmt.after:
1372-
self.visit_expression(stmt.after)
1385+
self.consume_slot(self.visit_expression(stmt.after))
13731386
self.emit(IR.Jump(cond_label))
13741387
self.emit(end)
13751388

@@ -1379,6 +1392,7 @@ def visit_if_stmt(self, stmt):
13791392

13801393
cond = self.visit_expression(stmt.cond)
13811394
self.emit(IR.JumpIfNot(false_label, cond))
1395+
self.consume_slot(cond)
13821396

13831397
if self.exists(stmt.true):
13841398
self.visit_statement(stmt.true)
@@ -1415,6 +1429,7 @@ def visit_switch_stmt(self, stmt):
14151429
self.emit_op(IR.Op.Eq, option, self.int(choice), res)
14161430
self.emit(IR.JumpIf(dest, res))
14171431
self.emit(IR.Jump(default_label))
1432+
self.consume_slot(option)
14181433

14191434
for label, body in case_bodies:
14201435
self.emit(label)
@@ -1444,6 +1459,7 @@ def visit_return_stmt(self, stmt):
14441459
# for the return value, so store it there
14451460
dest = self.offset(IR.StackPointer, -ret_type.size, ret_type)
14461461
self.emit(IR.Move(ret_val, dest))
1462+
self.consume_slot(ret_val)
14471463
self.emit(IR.Return())
14481464

14491465
def visit_goto_stmt(self, stmt):
@@ -1453,7 +1469,7 @@ def visit_sync_stmt(self, stmt):
14531469
self.emit(IR.Sync())
14541470

14551471
def visit_expr_stmt(self, stmt):
1456-
self.visit_expression(stmt.expr)
1472+
self.consume_slot(self.visit_expression(stmt.expr))
14571473

14581474
### Expressions
14591475

@@ -1523,6 +1539,7 @@ def visit_binop_expr(self, expr):
15231539
op = IR.Op.lookup(expr.op)
15241540
res = mk_slot(left.type)
15251541
self.emit_op(op, left, right, res)
1542+
self.virtual_slot(res)
15261543
return res
15271544

15281545
def visit_member_access_expr(self, expr):

compiler/ir.py

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ def init(self):
337337
def emit(self, insn):
338338
if not self.dead:
339339
super().emit(insn)
340+
else:
341+
self.success()
340342

341343
def handle_entity_local(self, insn):
342344
self.dead = False
@@ -354,6 +356,10 @@ def handle_jump(self, insn):
354356
self.emit(insn)
355357
self.dead = True
356358

359+
def handle_return(self, insn):
360+
self.emit(insn)
361+
self.dead = True
362+
357363
def handle_label(self, insn):
358364
self.dead = False
359365
self.emit(insn)
@@ -432,6 +438,12 @@ class ConstantElimination(OptimizerVisitor):
432438

433439
def init(self):
434440
self.slot_value_map = {}
441+
self.slot_ref_map = {}
442+
self.clear()
443+
444+
def clear(self):
445+
self.slot_value_map = {}
446+
self.slot_ref_map = {}
435447

436448
def literal(self, ref):
437449
if isinstance(ref, IR.LiteralInt):
@@ -444,19 +456,19 @@ def int(self, val):
444456
return IR.LiteralInt(val, IntType())
445457

446458
def handle_fn_begin(self, insn):
447-
self.slot_value_map = {}
459+
self.clear()
448460
self.emit(insn)
449461

450462
def handle_label(self, insn):
451-
self.slot_value_map = {}
463+
self.clear()
452464
self.emit(insn)
453465

454466
def handle_jump(self, insn):
455-
self.slot_value_map = {}
467+
self.clear()
456468
self.emit(insn)
457469

458470
def handle_jump_if(self, insn):
459-
self.slot_value_map = {}
471+
self.clear()
460472
cond = self.literal(insn.cond)
461473
if cond is not None:
462474
self.success()
@@ -468,7 +480,7 @@ def handle_jump_if(self, insn):
468480
self.emit(insn)
469481

470482
def handle_jump_if_not(self, insn):
471-
self.slot_value_map = {}
483+
self.clear()
472484
cond = self.literal(insn.cond)
473485
if cond is not None:
474486
self.success()
@@ -480,13 +492,27 @@ def handle_jump_if_not(self, insn):
480492
self.emit(insn)
481493

482494
def handle_call(self, insn):
483-
self.slot_value_map = {}
495+
self.clear()
484496
self.emit(insn)
485497

486498
def handle_move(self, insn):
487499
val = self.literal(insn.src)
488500
if val is not None:
489501
self.slot_value_map[insn.dest] = val
502+
if insn.src == insn.dest: # useless move
503+
self.success()
504+
return
505+
if insn.dest in self.slot_ref_map:
506+
prev_val = self.slot_ref_map[insn.dest]
507+
if insn.src == prev_val: # useless move
508+
self.success()
509+
return
510+
if insn.src in self.slot_ref_map:
511+
src_ref = self.slot_ref_map[insn.src]
512+
if src_ref == insn.dest: # useless move
513+
self.success()
514+
return
515+
self.slot_ref_map[insn.dest] = insn.src
490516
self.emit(insn)
491517

492518
def handle_operation(self, insn):
@@ -529,5 +555,5 @@ def handle_operation(self, insn):
529555
self.emit(insn)
530556

531557
def handle_unary_operation(self, insn):
532-
self.slot_value_map = {}
558+
self.clear()
533559
self.emit(insn)

compiler_main.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,13 @@ def __iter__(self):
9191
writer = DummyWriter()
9292
writer.open()
9393

94+
page_size = args.page_size
95+
# don't bother with memory if not used
96+
if not assembler.use_mem:
97+
page_size = 0
9498
session = CompilerSession((x, y, z), writer, args.namespace, stack_size=args.stack,
9599
args=sargs, setup_on_load=args.setup_on_load, debug=args.debug,
96-
page_size=args.page_size)
100+
page_size=page_size)
97101
assembler.write_to_session(session)
98102
setup, cleanup = session.create_up_down_functions(args.spawn_location)
99103
writer.close()

session.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ def Tracked(command):
126126
current_push_func = 'stack_push_0'
127127
current_pop_func = 'stack_pop_0'
128128
self.scope.add_function_names((current_push_func, current_pop_func))
129+
stack_overflow = Execute.If(SelEquals(Var('success_tracker'), 0),
130+
Tellraw(['Stack overflow error!'], 'a'))
131+
stack_underflow = Execute.If(SelEquals(Var('success_tracker'), 0),
132+
Tellraw(['Stack underflow error!'], 'a'))
129133
for i in range(self.stack_size):
130134
stack_dump.append(Var('stack_slot', i))
131135
if i != self.stack_size - 1:
@@ -152,12 +156,16 @@ def Tracked(command):
152156
current_push_seq = Subsequence()
153157
current_pop_seq = Subsequence()
154158
else:
159+
current_push_seq.add_command(stack_overflow)
160+
current_pop_seq.add_command(stack_overflow)
155161
self.add_subsequence(current_push_func, current_push_seq)
156162
self.add_subsequence(current_pop_func, current_pop_seq)
157163
current_push_func = next_push_func
158164
current_pop_func = next_pop_func
159165

160166
if one_function:
167+
current_push_seq.add_command(stack_overflow)
168+
current_pop_seq.add_command(stack_overflow)
161169
self.add_subsequence(current_push_func, push_stack)
162170
self.add_subsequence(current_pop_func, pop_stack)
163171

0 commit comments

Comments
 (0)