Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
peephole
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
Taddeüs Kroes
peephole
Commits
8d6930d4
Commit
8d6930d4
authored
13 years ago
by
Taddeus Kroes
Browse files
Options
Downloads
Patches
Plain Diff
Improved local copy propagation.
parent
f58d2e0b
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/optimize/advanced.py
+125
-37
125 additions, 37 deletions
src/optimize/advanced.py
src/program.py
+23
-6
23 additions, 6 deletions
src/program.py
src/statement.py
+23
-6
23 additions, 6 deletions
src/statement.py
with
171 additions
and
49 deletions
src/optimize/advanced.py
+
125
−
37
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
...
...
This diff is collapsed.
Click to expand it.
src/program.py
+
23
−
6
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.
"""
...
...
This diff is collapsed.
Click to expand it.
src/statement.py
+
23
−
6
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
:
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment