Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the renaming of reserved registers configurable #50

Merged
merged 2 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions slothy/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,37 @@ def outputs(self):
def reserved_regs(self):
"""Set of architectural registers _not_ available for register renaming.
May be unset (None) to pick the default reserved registers for the target
architecture. If set, it _overwrites_ the default reserved registers for
the target architecture -- that is, if you still want the default reserved
registers to remain reserved, you have to explicitly list them.
architecture.

In the lingo of inline assembly, this can be seen as the complement of
the clobber list."""
the clobber list.

NOTE: Reserved registers are, by default, considered "locked": They
will not be _introduced_ during renaming, but existing uses will not
be touched. If you want to remove existing uses of reserved registers
through renaming, you should disable `reserved_regs_are_locked`.

WARNING: When this is set, it _overwrites_ the default reserved registers for
the target architecture. If you still want the default reserved
registers to remain reserved, you have to explicitly list them!"""
if self._reserved_regs is not None:
return self._reserved_regs
return self._arch.RegisterType.default_reserved()

@property
def reserved_regs_are_locked(self):
"""Indicates whether reserved registers should be locked by default.

Reserved registers are not introduced during renaming. However, where
they are already used by the input assembly, their use will not be
eliminated or altered -- that is, reserved registers are 'locked' by
default.

Disable this configuration option to allow (in fact, force) renaming
of existing uses of reserved registers. This can be useful when trying
to eliminate uses of particular registers from some piece of assembly."""
return self._reserved_regs_are_locked

@property
def selfcheck(self):
"""Indicates whether SLOTHY performs a self-check on the optimization result.
Expand Down Expand Up @@ -262,8 +283,12 @@ def inputs_are_outputs(self):
@property
def locked_registers(self):
"""List of architectural registers that should not be renamed when they are
used as output registers. Reserved registers are always treated as locked."""
return set(self.reserved_regs).union(self._locked_registers)
used as output registers. Reserved registers are treated as locked if
the option `reserved_regs_are_locked` is set."""
if self.reserved_regs_are_locked:
return set(self.reserved_regs).union(self._locked_registers)
else:
return set(self._locked_registers)

@property
def sw_pipelining(self):
Expand Down Expand Up @@ -1023,6 +1048,7 @@ def __init__(self, Arch, Target):

self._locked_registers = []
self._reserved_regs = None
self._reserved_regs_are_locked = True

self._selfcheck = True
self._allow_useless_instructions = False
Expand Down Expand Up @@ -1119,6 +1145,9 @@ def _check_rename_config(self, lst):
@reserved_regs.setter
def reserved_regs(self,val):
self._reserved_regs = val
@reserved_regs_are_locked.setter
def reserved_regs_are_locked(self,val):
self._reserved_regs_are_locked = val
@variable_size.setter
def variable_size(self,val):
self._variable_size = val
Expand Down
1 change: 1 addition & 0 deletions slothy/targets/aarch64/aarch64_neon.py
Original file line number Diff line number Diff line change
Expand Up @@ -2636,6 +2636,7 @@ def make(cls, src):
obj.increment = None
obj.pre_index = None
obj.addr = obj.args_in[0]
return obj

def write(self):
# For now, assert that no fixup has happened
Expand Down
Loading