Compute top-level register classes for each register bank.

A top-level register class is one that has no sub-classes. It is
possible to have multiple top-level register classes in the same
register bank. For example, ARM's FPR bank has both D and Q top-level
register classes.

Number register classes such that all top-level register classes appear
as a contiguous sequence starting from 0. This will be used by the
register allocator when counting used registers per top-level register
class.
This commit is contained in:
Jakob Stoklund Olesen
2017-05-15 13:39:59 -07:00
parent ca6eddaf88
commit 09ac27a797
5 changed files with 66 additions and 24 deletions

View File

@@ -42,6 +42,7 @@ class TargetISA(object):
self.instruction_groups = instruction_groups
self.cpumodes = list() # type: List[CPUMode]
self.regbanks = list() # type: List[RegBank]
self.regclasses = list() # type: List[RegClass]
def finish(self):
# type: () -> TargetISA
@@ -109,11 +110,23 @@ class TargetISA(object):
Every register class needs a unique index, and the classes need to be
topologically ordered.
We also want all the top-level register classes to be first.
"""
rc_index = 0
# Compute subclasses and top-level classes in each bank.
# Collect the top-level classes so they get numbered consecutively.
for bank in self.regbanks:
bank.finish_regclasses(rc_index)
rc_index += len(bank.classes)
bank.finish_regclasses()
self.regclasses.extend(bank.toprcs)
# Collect all of the non-top-level register classes.
# They are numbered strictly after the top-level classes.
for bank in self.regbanks:
self.regclasses.extend(
rc for rc in bank.classes if not rc.is_toprc())
for idx, rc in enumerate(self.regclasses):
rc.index = idx
class CPUMode(object):

View File

@@ -75,6 +75,8 @@ class RegBank(object):
self.prefix = prefix
self.names = names
self.classes = list() # type: List[RegClass]
self.toprcs = list() # type: List[RegClass]
self.first_toprc_index = None # type: int
assert len(names) <= units
@@ -95,11 +97,10 @@ class RegBank(object):
return ('RegBank({}, units={}, first_unit={})'
.format(self.name, self.units, self.first_unit))
def finish_regclasses(self, first_index):
# type: (int) -> None
def finish_regclasses(self):
# type: () -> None
"""
Assign indexes to the register classes in this bank, starting from
`first_index`.
Compute subclasses and the top-level register class.
Verify that the set of register classes satisfies:
@@ -115,14 +116,10 @@ class RegBank(object):
"""
cmap = dict() # type: Dict[RCTup, RegClass]
for idx, rc in enumerate(self.classes):
for rc in self.classes:
# All register classes must be given a name.
assert rc.name, "Anonymous register class found"
# Assign a unique index.
assert rc.index is None
rc.index = idx + first_index
# Check for duplicates.
tup = rc.rctup()
if tup in cmap:
@@ -133,6 +130,7 @@ class RegBank(object):
# Check intersections and topological order.
for idx, rc1 in enumerate(self.classes):
rc1.toprc = rc1
for rc2 in self.classes[0:idx]:
itup = rc1.intersect(rc2)
if itup is None:
@@ -151,6 +149,10 @@ class RegBank(object):
# The intersection of rc1 and rc2 is rc1, so it must be a
# sub-class.
rc2.subclasses.append(rc1)
rc1.toprc = rc2.toprc
if rc1.is_toprc():
self.toprcs.append(rc1)
def unit_by_name(self, name):
# type: (str) -> int
@@ -192,6 +194,7 @@ class RegClass(object):
# This is computed later in `finish_regclasses()`.
self.subclasses = list() # type: List[RegClass]
self.toprc = None # type: RegClass
assert width > 0
assert start >= 0 and start < bank.units
@@ -206,6 +209,16 @@ class RegClass(object):
# type: () -> str
return self.name
def is_toprc(self):
# type: () -> bool
"""
Is this a top-level register class?
A top-level register class has no sub-classes. This can only be
answered aster running `finish_regclasses()`.
"""
return self.toprc is self
def rctup(self):
# type: () -> RCTup
"""