got rid of multi-assignments

This commit is contained in:
Irmen de Jong 2018-02-20 01:16:16 +01:00
parent de3bca0763
commit 920b6ca51e
9 changed files with 41 additions and 59 deletions

View File

@ -37,7 +37,6 @@ class PlyParser:
module.scope.define_builtin_functions()
self.process_imports(module)
self.check_and_merge_zeropages(module)
self.create_multiassigns(module)
if not self.imported_module:
# the following shall only be done on the main module after all imports have been done:
self.check_all_symbolnames(module)
@ -249,24 +248,6 @@ class PlyParser:
for node in module.all_nodes(SymbolName):
check_symbol_definition(node.name, node.my_scope(), node.sourceref) # type: ignore
@no_type_check
def create_multiassigns(self, module: Module) -> None:
# create multi-assign statements from nested assignments (A=B=C=5),
def reduce_right(assign: Assignment) -> Assignment:
if isinstance(assign.right, Assignment):
right = reduce_right(assign.right)
for rn in right.left.nodes:
rn.parent = assign.left
assign.left.nodes.extend(right.left.nodes)
assign.right = right.right
assign.right.parent = assign
return assign
for node in module.all_nodes(Assignment):
if isinstance(node.right, Assignment):
multi = reduce_right(node)
assert multi is node and len(multi.left.nodes) > 1 and not isinstance(multi.right, Assignment)
@no_type_check
def apply_directive_options(self, module: Module) -> None:
def set_save_registers(scope: Scope, save_dir: Directive) -> None:

View File

@ -40,7 +40,6 @@ class Optimizer:
self.optimize_assignments()
self.remove_superfluous_assignments()
self.combine_assignments_into_multi()
self.optimize_multiassigns()
# @todo optimize addition with self into shift 1 (A+=A -> A<<=1)
self.optimize_goto_compare_with_zero()
self.join_incrdecrs()
@ -301,19 +300,6 @@ class Optimizer:
rvalue = None
assignments.clear()
@no_type_check
def optimize_multiassigns(self) -> None:
# optimize multi-assign statements (remove duplicate targets, optimize order)
for assignment in self.module.all_nodes(Assignment):
if len(assignment.left.nodes) > 1:
# remove duplicates
lvalues = set(assignment.left.nodes)
if len(lvalues) != len(assignment.left.nodes):
print("{}: removed duplicate assignment targets".format(assignment.sourceref))
# @todo change order: first registers, then zp addresses, then non-zp addresses, then the rest (if any)
assignment.left.nodes = list(lvalues)
self.optimizations_performed = True
@no_type_check
def remove_unused_subroutines(self) -> None:
# some symbols are used by the emitted assembly code from the code generator,

View File

@ -846,10 +846,7 @@ class Return(AstNode):
@attr.s(cmp=False, slots=True, repr=False)
class Assignment(AstNode):
# can be single- or multi-assignment
# has two subnodes: left (=Register/SymbolName/Dereference ) and right (=Expression,
# or another Assignment but those will be converted into multi assign)
# has two subnodes: left (=Register/SymbolName/Dereference ) and right (=Expression)
@property
def left(self) -> Union[Register, SymbolName, Dereference]:
return self.nodes[0] # type: ignore
@ -1475,7 +1472,6 @@ def p_symbolname(p):
def p_assignment(p):
"""
assignment : assignment_target IS expression
| assignment_target IS assignment
"""
p[0] = Assignment(sourceref=_token_sref(p, 2))
p[0].nodes.append(p[1])

View File

@ -288,13 +288,9 @@ want to work on later, because the contents of the ignored block are not fully p
### Assignments
Assignment statements assign a single value to one or more variables or memory locations.
If you know that you have to assign the same value to more than one thing at once, it is more
efficient to write it as a multi-assign instead of several separate assignments. The compiler
tries to detect this situation however and optimize it itself if it finds the case.
Assignment statements assign a single value to a target variable or memory location.
target = value-expression
target1 = target2 = target3 [,...] = value-expression
### Augmented Assignments

View File

@ -153,8 +153,6 @@ start:
A = 0
A = '@'
A = 1.2345
A=X=Y= true
A=XY= true
A = false
A = 255
A = X
@ -180,8 +178,6 @@ start:
XY = uninitbyte1
XY = "text-immediate"
AY = "text-immediate"
; AX = &"text-immediate" ; equivalent to simply assigning the string directly
; AX = & "text-immediate" ; equivalent to simply assigning the string directly
AX = ctext3
AX = ""
AX = XY
@ -190,7 +186,7 @@ start:
XY = membyte2
XY = memword1
XY = sin
; XY = &sin ; @todo not yet implemented
XY = &sin ; @todo not yet implemented
[$c000] = A
@ -214,7 +210,7 @@ start:
[$c000.word] = ""
[$c000.word] = uninitbyte1
[$c000.word] = membyte2
; [$c000.word] = &membyte2 ; @todo not yet implemented
[$c000.word] = &membyte2 ; @todo not yet implemented
[$c000.word] = [cword2]
[$c000.word] = memword1
[$c000.float] = 65535
@ -228,7 +224,7 @@ start:
[$c112.word] = [$c223.byte]
[$c222.word] = [$c333.word]
[$c333.word] = sin
; [$c333.word] = &sin ; @todo not yet implemented
[$c333.word] = &sin ; @todo not yet implemented
SC = 0
@ -264,7 +260,7 @@ start:
uninitfloat = 9.8765
uninitfloat = '@'
initword1 = sin
; initword1 = &sin ; @todo not yet implemented
initword1 = &sin ; @todo not yet implemented
membyte1 = A
@ -280,7 +276,7 @@ start:
memword1 = 2233
memfloat = 3.4567
memword1 = sin
; memword1 = &sin ; @todo not yet implemented
memword1 = &sin ; @todo not yet implemented
membyte1 = A
memword1 = A

View File

@ -15,7 +15,7 @@ start:
A = c64.VMCSB
A |= 2
c64.VMCSB = A
;c64.VMCSB |= 2 ; @todo when this works it replaces the three lines above
c64.VMCSB |= 2 ; @todo when this works it replaces the three lines above
; greeting
c64scr.print_string("Enter your name: ")

View File

@ -33,7 +33,19 @@ start: ;foo
Y = X
X = 66
screen = 0
screen = border = cursor = X = Y = A = X = Y = A = border = cursor = border = cursor = 66 ; multi-assign!
screen = 66
border = 66
cursor = 66
X = 66
Y = 66
A = 66
X = 66
Y = 66
A = 66
border = 66
cursor = 66
border = 66
cursor = 66
border = false
border = true
border = 0
@ -58,7 +70,9 @@ start: ;foo
Y = 2
Y = true
Y = false
A = Y = X = 0 ; multi assign!
A = 0
Y = 0
X = 0
; [646,Y] = [$d020,X]
@ -130,8 +144,19 @@ somelabel1:
goto somelabel1
goto block2.somelabel1222
A=X=Y=A=X=Y=A=X=Y=99
[$d020]=[$d021]=[$d020]=[$d021]=55
A=99
X=99
Y=99
A=99
X=99
Y=99
A=99
X=99
Y=99
[$d020]=55
[$d021]=55
[$d020]=55
[$d021]=55
A=1
X=1

View File

@ -67,7 +67,8 @@ start:
~ global2 {
make_screen_black:
c64.EXTCOL = c64.BGCOL0 = 0
c64.EXTCOL = 0
c64.BGCOL0 = 0
c64.COLOR = 3
Y = true
return

View File

@ -53,7 +53,8 @@ start2:
~ global2 {
make_screen_black:
c64.EXTCOL = c64.BGCOL0 = 0
c64.EXTCOL = 0
c64.BGCOL0 = 0
c64.COLOR = 3
return