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:
@@ -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):
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user