Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
peephole
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
peephole
Commits
8d6930d4
Commit
8d6930d4
authored
Dec 31, 2011
by
Taddeus Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improved local copy propagation.
parent
f58d2e0b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
171 additions
and
49 deletions
+171
-49
src/optimize/advanced.py
src/optimize/advanced.py
+125
-37
src/program.py
src/program.py
+23
-6
src/statement.py
src/statement.py
+23
-6
No files found.
src/optimize/advanced.py
View file @
8d6930d4
import
re
from
src.statement
import
Statement
as
S
from
src.liveness
import
is_reg_dead_after
from
src.liveness
import
RESERVED_REGISTERS
,
is_reg_dead_after
from
src.dataflow
import
succ
#def reg_can_be_used_in(reg, block, start, end):
...
...
@@ -342,6 +343,83 @@ def fold_constants(block):
# return changed
#def copy_propagation(block):
# """
# Unpack a move instruction, by replacing its destination
# address with its source address in the code following the move instruction.
# This way, the move statement might be a target for dead code elimination.
#
# move $regA, $regB move $regA, $regB
# ... ...
# Code not writing $regA, -> ...
# $regB ...
# ... ...
# addu $regC, $regA, ... addu $regC, $regB, ...
# """
# changed = False
#
# moves = {}
#
# block.reset()
#
# while not block.end():
# s = block.read()
#
# if not s.is_command():
# continue
#
# if s.name == 'move':
# # Register the move
# reg_to, reg_from = s
#
# if reg_from in moves:
# if moves[reg_from] == reg_to:
# continue
# else:
# moves[reg_to] = moves[reg_from]
# elif reg_to == reg_from:
# del moves[reg_to]
# else:
# moves[reg_to] = reg_from
#
# s.set_message(' Move: %s = %s' % (reg_to, moves[reg_to]))
# continue
#
# # Replace used registers with moved equivalents when possible
# for i, reg in s.get_use(True):
# if reg in moves:
# #s.replace_usage(reg, moves[reg], i)
# #changed = True
# replaced_before = hasattr(s, 'replaced')
# xy = (reg, moves[reg])
#
# if not replaced_before or xy not in s.replaced:
# s.replace_usage(reg, moves[reg], i)
# changed = True
#
# if replaced_before:
# s.replaced.append(xy)
# else:
# s.replaced = [xy]
#
# # If a known moved register is overwritten, remove it from the
# # registration
# defined = s.get_def()
# delete = []
#
# for move_to, move_from in moves.iteritems():
# if move_to in defined or move_from in defined:
# delete.append(move_to)
#
# if len(delete):
# s.set_message(' Moves deleted: %s' % ', '.join(delete))
#
# for reg in delete:
# del moves[reg]
#
# return changed
def
copy_propagation
(
block
):
"""
Unpack a move instruction, by replacing its destination
...
...
@@ -357,54 +435,64 @@ def copy_propagation(block):
"""
changed
=
False
moves
=
{}
block
.
reset
()
while
not
block
.
end
():
s
=
block
.
read
()
if
not
s
.
is_command
():
continue
if
s
.
name
==
'move'
:
# Register the move
reg_to
,
reg_from
=
s
# For each copy statement s: x = y do
if
s
.
is_command
(
'move'
):
x
,
y
=
s
if
reg_from
in
moves
:
if
moves
[
reg_from
]
==
reg_to
:
continue
else
:
moves
[
reg_to
]
=
moves
[
reg_from
]
elif
reg_to
==
reg_from
:
del
moves
[
reg_to
]
else
:
moves
[
reg_to
]
=
reg_from
# Moves to reserved registers will never be removed, so don't
# bother replacing them
#if x in RESERVED_REGISTERS:
# continue
s
.
set_message
(
' Move: %s = %s'
%
(
reg_to
,
moves
[
reg_to
]))
continue
# Determine the uses of x reached by this definition of x
for
s2
in
block
[
block
.
pointer
:]:
i
=
s2
.
uses
(
x
,
True
)
replaced_before
=
hasattr
(
s2
,
'replaced'
)
# Replace used registers with moved equivalents when possible
for
i
,
reg
in
s
.
get_use
(
True
):
if
reg
in
moves
:
s
[
i
]
=
re
.
sub
(
'
\
\
'
+
reg
+
'(?!
\
d)
'
, moves[reg], s[i])
s.set_message('
Replaced
%
s
with
%
s
' % (reg, moves[reg]))
changed = True
if
i
!=
-
1
and
(
not
replaced_before
\
or
(
x
,
y
)
not
in
s2
.
replaced
):
s2
.
replace_usage
(
x
,
y
,
i
)
changed
=
True
# If a known moved register is overwritten, remove it from the
# registration
defined = s.get_def()
delete = [
]
if
replaced_before
:
s2
.
replaced
.
append
((
x
,
y
))
else
:
s2
.
replaced
=
[(
x
,
y
)
]
for move_to, move_from in moves.iteritems():
if move_to in defined or move_from in defined:
delete.append(move_to)
# An assignment to x or y kills the copy statement x = y
defined
=
s2
.
get_def
()
if len(delete)
:
s.set_message('
Moves
deleted
:
%
s
' % '
,
'.join(delete))
if
x
in
defined
or
y
in
defined
:
break
for reg in delete:
del moves[reg]
# Determine uses of x in successors of the block
# Determine if for each of those uses if this is the only
# definition reaching it -> s in in[B_use]
#if s.sid in block.reach_out:
# for b in filter(lambda b: (x, y) in b.copy_in, succ(block)):
# print b
# for s2 in b:
# # Determine if for each of those uses this is the only
# # definition reaching it -> s in in[B_use]
# i = s2.uses(x, True)
# if i != -1:
# s2.replace_usage(x, y, i, block.bid)
# print ' Replaced %s with %s from block %d' \
# % (x, y, block.bid)
# changed = True
# # An assignment to x or y kills the copy statement x =
# # y
# defined = s2.get_def()
# if x in defined or y in defined:
# break
return
changed
...
...
src/program.py
View file @
8d6930d4
...
...
@@ -8,6 +8,7 @@ from optimize.advanced import eliminate_common_subexpressions, \
import
liveness
import
reaching_definitions
#import copy_propagation as copy_propagation_flow
from
writer
import
write_statements
...
...
@@ -85,12 +86,27 @@ class Program(Block):
changed
=
False
for
block
in
self
.
blocks
:
if
remove_redundancies
(
block
)
\
|
eliminate_common_subexpressions
(
block
)
\
|
fold_constants
(
block
)
\
|
copy_propagation
(
block
)
\
|
eliminate_dead_code
(
block
):
changed
=
True
if
remove_redundancies
(
block
):
changed
=
True
if
eliminate_common_subexpressions
(
block
):
changed
=
True
if
fold_constants
(
block
):
changed
=
True
if
copy_propagation
(
block
):
changed
=
True
if
eliminate_dead_code
(
block
):
changed
=
True
#if remove_redundancies(block) \
# | eliminate_common_subexpressions(block) \
# | fold_constants(block) \
# | copy_propagation(block) \
# | eliminate_dead_code(block):
# changed = True
return
changed
...
...
@@ -113,6 +129,7 @@ class Program(Block):
generate_flow_graph
(
self
.
blocks
)
liveness
.
create_in_out
(
self
.
blocks
)
reaching_definitions
.
create_in_out
(
self
.
blocks
)
#copy_propagation_flow.create_in_out(self.blocks)
def
save
(
self
,
filename
):
"""Save the program in the specified file."""
...
...
src/statement.py
View file @
8d6930d4
...
...
@@ -40,7 +40,10 @@ class Statement:
%
(
self
.
stype
,
self
.
name
,
self
.
args
)
def
set_message
(
self
,
message
):
self
.
options
[
'message'
]
=
message
if
len
(
self
.
options
.
get
(
'message'
,
''
)):
self
.
options
[
'message'
]
+=
' |'
+
message
else
:
self
.
options
[
'message'
]
=
message
def
set_inline_comment
(
self
,
comment
):
self
.
options
[
'comment'
]
=
comment
...
...
@@ -235,14 +238,28 @@ class Statement:
"""Check if this statement defines the given register."""
return reg in self.get_def()
def uses(self, reg):
def uses(self, reg
, as_index=False
):
"""Check if this statement uses the given register."""
return reg in self.get_use(
)
use = self.get_use(as_index
)
def replace_usage(self, x, y):
if as_index:
for index, register in use:
if register == reg:
return index
return -1
return reg in use
def replace_usage(self, x, y, index, bid=0):
"""Replace the uses of register x by y."""
for i, arg in enumerate(self):
self[i] = re.sub('
\\
' + x + '
(
?!
\
d
)
', y, str(arg))
self[index] = re.sub('
\\
' + x + '
(
?!
\
d
)
', y, str(self[index]))
if bid:
self.set_message('
Replaced
%
s
with
%
s
from
block
%
d
'
\
% (x, y, bid))
else:
self.set_message('
Replaced
%
s
with
%
s
' % (x, y))
class Block:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment