Remove the number field from the PredNode union type.

Predicate numbers are available in the maps
isa.settings.predicate_number and isa.instp_number instead.

Like the name field, predicate numbers don't interact well with
unique_pred().
This commit is contained in:
Jakob Stoklund Olesen
2017-07-26 11:01:47 -07:00
parent 84fffa79f6
commit ac830e0446
4 changed files with 21 additions and 31 deletions

View File

@@ -103,23 +103,17 @@ class TargetISA(object):
""" """
Collect and number all predicates in use. Collect and number all predicates in use.
Sets `instp.number` for all used instruction predicates and places them
in `self.all_instps` in numerical order.
Ensures that all ISA predicates have an assigned bit number in Ensures that all ISA predicates have an assigned bit number in
`self.settings`. `self.settings`.
""" """
self.all_instps = list() # type: List[PredNode] self.instp_number = OrderedDict() # type: OrderedDict[PredNode, int]
instps = set() # type: Set[PredNode]
for cpumode in self.cpumodes: for cpumode in self.cpumodes:
for enc in cpumode.encodings: for enc in cpumode.encodings:
instp = enc.instp instp = enc.instp
if instp and instp not in instps: if instp and instp not in self.instp_number:
# assign predicate number starting from 0. # assign predicate number starting from 0.
assert instp.number is None n = len(self.instp_number)
instp.number = len(instps) self.instp_number[instp] = n
instps.add(instp)
self.all_instps.append(instp)
# All referenced ISA predicates must have a number in # All referenced ISA predicates must have a number in
# `self.settings`. This may cause some parent predicates to be # `self.settings`. This may cause some parent predicates to be

View File

@@ -80,7 +80,6 @@ class Predicate(object):
def __init__(self, parts): def __init__(self, parts):
# type: (Sequence[PredNode]) -> None # type: (Sequence[PredNode]) -> None
self.number = None # type: int
self.parts = parts self.parts = parts
self.context = reduce( self.context = reduce(
_descendant, _descendant,
@@ -210,7 +209,6 @@ class FieldPredicate(object):
def __init__(self, field, function, args): def __init__(self, field, function, args):
# type: (FormatField, str, Sequence[Any]) -> None # type: (FormatField, str, Sequence[Any]) -> None
self.number = None # type: int
self.field = field self.field = field
self.function = function self.function = function
self.args = args self.args = args
@@ -330,7 +328,6 @@ class TypePredicate(object):
assert value_type is not None assert value_type is not None
self.value_arg = value_arg self.value_arg = value_arg
self.value_type = value_type self.value_type = value_type
self.number = None # type: int
def __str__(self): def __str__(self):
# type: () -> str # type: () -> str

View File

@@ -23,7 +23,6 @@ class Setting(object):
def __init__(self, doc): def __init__(self, doc):
# type: (str) -> None # type: (str) -> None
self.name = None # type: str # Assigned later by `extract_names()`. self.name = None # type: str # Assigned later by `extract_names()`.
self.number = None # type: int
self.__doc__ = doc self.__doc__ = doc
# Offset of byte in settings vector containing this setting. # Offset of byte in settings vector containing this setting.
self.byte_offset = None # type: int self.byte_offset = None # type: int

View File

@@ -124,13 +124,13 @@ def emit_instp(instp, fmt, has_dfg=False):
def emit_inst_predicates(instps, fmt): def emit_inst_predicates(instps, fmt):
# type: (Sequence[PredNode], srcgen.Formatter) -> None # type: (OrderedDict[PredNode, int], srcgen.Formatter) -> None
""" """
Emit private functions for matching instruction predicates as well as a Emit private functions for matching instruction predicates as well as a
static `INST_PREDICATES` array indexed by predicate number. static `INST_PREDICATES` array indexed by predicate number.
""" """
for instp in instps: for instp, number in instps.items():
name = 'inst_predicate_{}'.format(instp.number) name = 'inst_predicate_{}'.format(number)
with fmt.indented( with fmt.indented(
'fn {}(dfg: &ir::DataFlowGraph, inst: &ir::InstructionData)' 'fn {}(dfg: &ir::DataFlowGraph, inst: &ir::InstructionData)'
'-> bool {{'.format(name), '}'): '-> bool {{'.format(name), '}'):
@@ -140,12 +140,12 @@ def emit_inst_predicates(instps, fmt):
with fmt.indented( with fmt.indented(
'pub static INST_PREDICATES: [InstPredicate; {}] = [' 'pub static INST_PREDICATES: [InstPredicate; {}] = ['
.format(len(instps)), '];'): .format(len(instps)), '];'):
for instp in instps: for instp, number in instps.items():
fmt.format('inst_predicate_{},', instp.number) fmt.format('inst_predicate_{},', number)
def emit_recipe_predicates(recipes, fmt): def emit_recipe_predicates(isa, fmt):
# type: (Sequence[EncRecipe], srcgen.Formatter) -> None # type: (TargetISA, srcgen.Formatter) -> None
""" """
Emit private functions for checking recipe predicates as well as a static Emit private functions for checking recipe predicates as well as a static
`RECIPE_PREDICATES` array indexed by recipe number. `RECIPE_PREDICATES` array indexed by recipe number.
@@ -158,7 +158,7 @@ def emit_recipe_predicates(recipes, fmt):
pname = dict() # type: Dict[RecipePred, str] pname = dict() # type: Dict[RecipePred, str]
# Generate unique recipe predicates. # Generate unique recipe predicates.
for rcp in recipes: for rcp in isa.all_recipes:
p = rcp.recipe_pred() p = rcp.recipe_pred()
if p is None or p in pname: if p is None or p in pname:
continue continue
@@ -174,17 +174,16 @@ def emit_recipe_predicates(recipes, fmt):
name, name,
'isap' if isap else '_'), '}'): 'isap' if isap else '_'), '}'):
if isap: if isap:
with fmt.indented( n = isa.settings.predicate_number[isap]
'if isap.test({})'.format(isap.number), with fmt.indented('if isap.test({})'.format(n), '}'):
'}'):
fmt.line('return false;') fmt.line('return false;')
emit_instp(instp, fmt) emit_instp(instp, fmt)
# Generate the static table. # Generate the static table.
with fmt.indented( with fmt.indented(
'pub static RECIPE_PREDICATES: [RecipePredicate; {}] = [' 'pub static RECIPE_PREDICATES: [RecipePredicate; {}] = ['
.format(len(recipes)), '];'): .format(len(isa.all_recipes)), '];'):
for rcp in recipes: for rcp in isa.all_recipes:
p = rcp.recipe_pred() p = rcp.recipe_pred()
if p is None: if p is None:
fmt.line('None,') fmt.line('None,')
@@ -229,7 +228,7 @@ class Encoder:
# type: (TargetISA) -> None # type: (TargetISA) -> None
self.isa = isa self.isa = isa
self.NR = len(isa.all_recipes) self.NR = len(isa.all_recipes)
self.NI = len(isa.all_instps) self.NI = len(isa.instp_number)
# u16 encoding list words. # u16 encoding list words.
self.words = list() # type: List[int] self.words = list() # type: List[int]
# Documentation comments: Index into `words` + comment. # Documentation comments: Index into `words` + comment.
@@ -287,7 +286,8 @@ class Encoder:
def instp(self, pred, skip): def instp(self, pred, skip):
# type: (PredNode, int) -> None # type: (PredNode, int) -> None
"""Add an instruction predicate entry.""" """Add an instruction predicate entry."""
self._pred(pred, skip, pred.number) number = self.isa.instp_number[pred]
self._pred(pred, skip, number)
def isap(self, pred, skip): def isap(self, pred, skip):
# type: (PredNode, int) -> None # type: (PredNode, int) -> None
@@ -836,10 +836,10 @@ def gen_isa(isa, fmt):
# type: (TargetISA, srcgen.Formatter) -> None # type: (TargetISA, srcgen.Formatter) -> None
# Make the `RECIPE_PREDICATES` table. # Make the `RECIPE_PREDICATES` table.
emit_recipe_predicates(isa.all_recipes, fmt) emit_recipe_predicates(isa, fmt)
# Make the `INST_PREDICATES` table. # Make the `INST_PREDICATES` table.
emit_inst_predicates(isa.all_instps, fmt) emit_inst_predicates(isa.instp_number, fmt)
# Level1 tables, one per CPU mode # Level1 tables, one per CPU mode
level1_tables = dict() level1_tables = dict()