Skip to content

Commit bbaf880

Browse files
authored
NFC: exp DXIL prereq: Improve hctdb enums and _idx maps (#7975)
db_dxil_enum_value constructor arg order made consistent with db_dxil_enum constructor's valNameDocTuples arg. Move dxil_version_info into enum, as it tracks version markers for that enum. Removed version tracking for OpCodeClass because it didn't make sense and wasn't really usable (not stable, internal compiler enum). This causes a change in DxilConstants.h which removes these unused enum values. db_dxil_enum.add_value to construct, add, and return new enum value. Removed build_indices, adding to *_idx maps in add_enum_type and new add_inst now used by add_dxil_op and related functions. They show up in the index immediately, without having to call build_indices() to update multiple times during initialization.
1 parent 6679358 commit bbaf880

File tree

3 files changed

+55
-68
lines changed

3 files changed

+55
-68
lines changed

include/dxc/DXIL/DxilConstants.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,17 +1414,6 @@ enum class OpCodeClass : unsigned {
14141414
NodeOutputIsValid,
14151415
OutputComplete,
14161416

1417-
NumOpClasses_Dxil_1_0 = 93,
1418-
NumOpClasses_Dxil_1_1 = 95,
1419-
NumOpClasses_Dxil_1_2 = 97,
1420-
NumOpClasses_Dxil_1_3 = 118,
1421-
NumOpClasses_Dxil_1_4 = 120,
1422-
NumOpClasses_Dxil_1_5 = 143,
1423-
NumOpClasses_Dxil_1_6 = 149,
1424-
NumOpClasses_Dxil_1_7 = 153,
1425-
NumOpClasses_Dxil_1_8 = 174,
1426-
NumOpClasses_Dxil_1_9 = 196,
1427-
14281417
NumOpClasses = 196 // exclusive last value of enumeration
14291418
};
14301419
// OPCODECLASS-ENUM:END

utils/hct/hctdb.py

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@
6565
class db_dxil_enum_value(object):
6666
"A representation for a value in an enumeration type"
6767

68-
def __init__(self, name, value, doc):
69-
self.name = name # Name (identifier)
68+
def __init__(self, value, name, doc):
7069
self.value = value # Numeric value
70+
self.name = name # Name (identifier)
7171
self.doc = doc # Documentation string
7272
self.category = None
7373

@@ -78,14 +78,19 @@ class db_dxil_enum(object):
7878
def __init__(self, name, doc, valNameDocTuples=()):
7979
self.name = name
8080
self.doc = doc
81-
self.values = [
82-
db_dxil_enum_value(n, v, d) for v, n, d in valNameDocTuples
83-
] # Note transmutation
81+
self.values = [db_dxil_enum_value(*args) for args in valNameDocTuples]
8482
self.is_internal = False # whether this is never serialized
83+
self.last_value_name = None # optional last value name for dense enums
84+
self.dxil_version_info = {} # version info for this enum
8585

8686
def value_names(self):
8787
return [i.name for i in self.values]
8888

89+
def add_value(self, *args):
90+
v = db_dxil_enum_value(*args)
91+
self.values.append(v)
92+
return v
93+
8994

9095
class db_dxil_inst(object):
9196
"A representation for a DXIL instruction"
@@ -344,16 +349,20 @@ def __init__(self):
344349
self.passes = [] # inventory of available passes (db_dxil_pass)
345350
self.name_idx = {} # DXIL instructions by name
346351
self.enum_idx = {} # enumerations by name
347-
self.dxil_version_info = {}
348352
# list of counters for instructions and dxil ops,
349353
# starting with extra ones specified here
350354
self.counters = extra_counters
351355
self.next_dxil_op_id = 0 # next available DXIL op ID
352356

357+
# Add the OpCode enum type, which will also track version info.
358+
OpCodeEnum = self.add_enum_type(
359+
"OpCode", "Enumeration for operations specified by DXIL"
360+
)
361+
OpCodeEnum.last_value_name = "NumOpCodes"
362+
353363
self.populate_llvm_instructions()
354364
self.call_instr = self.get_instr_by_llvm_name("CallInst")
355365
self.populate_dxil_operations()
356-
self.build_indices()
357366
self.populate_extended_docs()
358367
self.populate_categories_and_models()
359368
self.build_opcode_enum()
@@ -362,7 +371,6 @@ def __init__(self):
362371
self.populate_passes()
363372
self.build_valrules()
364373
self.build_semantics()
365-
self.build_indices()
366374
self.populate_counters()
367375

368376
def __str__(self):
@@ -374,43 +382,37 @@ def next_id(self):
374382
self.next_dxil_op_id += 1
375383
return val
376384

377-
def add_enum_type(self, name, doc, valNameDocTuples):
378-
"Adds a new enumeration type with name/value/doc tuples"
379-
self.enums.append(db_dxil_enum(name, doc, valNameDocTuples))
380-
381-
def build_indices(self):
382-
"Build a name_idx dictionary with instructions and an enum_idx dictionary with enumeration types"
383-
self.name_idx = {}
384-
for i in self.instr:
385-
self.name_idx[i.name] = i
386-
self.enum_idx = {}
387-
for i in self.enums:
388-
self.enum_idx[i.name] = i
385+
def add_enum_type(self, name, doc, valNameDocTuples=()):
386+
"Adds a new enumeration type with optional name/value/doc tuples"
387+
assert name not in self.enum_idx, "Enumeration type %s already exists" % (name)
388+
enum = db_dxil_enum(name, doc, valNameDocTuples)
389+
self.enum_idx[enum.name] = enum
390+
self.enums.append(enum)
391+
return enum
389392

390393
def build_opcode_enum(self):
391394
# Build enumeration from instructions
392-
OpCodeEnum = db_dxil_enum(
393-
"OpCode", "Enumeration for operations specified by DXIL"
394-
)
395+
OpCodeEnum = self.enum_idx["OpCode"]
396+
397+
# Keep track of last seen class/category pairs for OpCodeClass
395398
class_dict = {}
396399
class_dict["LlvmInst"] = "LLVM Instructions"
397400
for i in self.instr:
398401
if i.is_dxil_op:
399-
v = db_dxil_enum_value(i.dxil_op, i.dxil_opid, i.doc)
402+
v = OpCodeEnum.add_value(i.dxil_opid, i.dxil_op, i.doc)
400403
v.category = i.category
401404
class_dict[i.dxil_class] = i.category
402-
OpCodeEnum.values.append(v)
403-
self.enums.append(OpCodeEnum)
404-
OpCodeClass = db_dxil_enum(
405+
406+
# Build OpCodeClass enum
407+
OpCodeClass = self.add_enum_type(
405408
"OpCodeClass",
406409
"Groups for DXIL operations with equivalent function templates",
407410
)
408411
OpCodeClass.is_internal = True
412+
OpCodeClass.last_value_name = "NumOpClasses"
409413
for k, v in iter(class_dict.items()):
410-
ev = db_dxil_enum_value(k, 0, None)
414+
ev = OpCodeClass.add_value(0, k, None)
411415
ev.category = v
412-
OpCodeClass.values.append(ev)
413-
self.enums.append(OpCodeClass)
414416

415417
def mark_disallowed_operations(self):
416418
# Disallow indirect branching, unreachable instructions and support for exception unwinding.
@@ -436,9 +438,7 @@ def verify_dense(self, it, pred, name_proj):
436438
val = i_val
437439

438440
def set_op_count_for_version(self, major, minor):
439-
info = self.dxil_version_info.setdefault((major, minor), dict())
440-
info["NumOpCodes"] = self.next_dxil_op_id
441-
info["NumOpClasses"] = len(set([op.dxil_class for op in self.instr]))
441+
self.enum_idx["OpCode"].dxil_version_info[(major, minor)] = self.next_dxil_op_id
442442
return self.next_dxil_op_id
443443

444444
def populate_categories_and_models(self):
@@ -5890,7 +5890,6 @@ def UFI(name, **mappings):
58905890
)
58915891

58925892
# Set interesting properties.
5893-
self.build_indices()
58945893
for (
58955894
i
58965895
) in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY,Sample,SampleBias,SampleCmp,SampleCmpBias".split(
@@ -7024,7 +7023,7 @@ def add_pass(name, type_name, doc, opts):
70247023
self.pass_idx_args.add(anarg.name)
70257024

70267025
def build_semantics(self):
7027-
SemanticKind = db_dxil_enum(
7026+
SemanticKind = self.add_enum_type(
70287027
"SemanticKind",
70297028
"Semantic kind; Arbitrary or specific system value.",
70307029
[
@@ -7064,8 +7063,7 @@ def build_semantics(self):
70647063
(33, "Invalid", ""),
70657064
],
70667065
)
7067-
self.enums.append(SemanticKind)
7068-
SigPointKind = db_dxil_enum(
7066+
SigPointKind = self.add_enum_type(
70697067
"SigPointKind",
70707068
"Signature Point is more specific than shader stage or signature as it is unique in both stage and item dimensionality or frequency.",
70717069
[
@@ -7112,8 +7110,7 @@ def build_semantics(self):
71127110
(21, "Invalid", ""),
71137111
],
71147112
)
7115-
self.enums.append(SigPointKind)
7116-
PackingKind = db_dxil_enum(
7113+
self.add_enum_type(
71177114
"PackingKind",
71187115
"Kind of signature point",
71197116
[
@@ -7126,7 +7123,7 @@ def build_semantics(self):
71267123
],
71277124
)
71287125

7129-
Float32DenormMode = db_dxil_enum(
7126+
self.add_enum_type(
71307127
"Float32DenormMode",
71317128
"float32 denorm behavior",
71327129
[
@@ -7140,7 +7137,6 @@ def build_semantics(self):
71407137
(7, "Reserve7", "Reserved Value. Not used for now"),
71417138
],
71427139
)
7143-
self.enums.append(Float32DenormMode)
71447140

71457141
SigPointCSV = """
71467142
SigPoint, Related, ShaderKind, PackingKind, SignatureKind
@@ -7178,8 +7174,7 @@ def build_semantics(self):
71787174
assert False and "SigPointKind does not align with SigPointCSV row labels"
71797175
self.sigpoint_table = table
71807176

7181-
self.enums.append(PackingKind)
7182-
SemanticInterpretationKind = db_dxil_enum(
7177+
self.add_enum_type(
71837178
"SemanticInterpretationKind",
71847179
"Defines how a semantic is interpreted at a particular SignaturePoint",
71857180
[
@@ -7208,7 +7203,6 @@ def build_semantics(self):
72087203
(9, "Invalid", ""),
72097204
],
72107205
)
7211-
self.enums.append(SemanticInterpretationKind)
72127206

72137207
# The following has SampleIndex, Coverage, and InnerCoverage as loaded with instructions rather than from the signature
72147208
SemanticInterpretationCSV = """
@@ -8483,14 +8477,13 @@ def build_valrules(self):
84838477
"UNI": "Uniform analysis",
84848478
"DECL": "Declaration",
84858479
}
8486-
valrule_enum = db_dxil_enum("ValidationRule", "Known validation rules")
8480+
valrule_enum = self.add_enum_type("ValidationRule", "Known validation rules")
84878481
valrule_enum.is_internal = True
84888482
for vr in self.val_rules:
84898483
vr.category = cat_names[vr.group_name]
8490-
vrval = db_dxil_enum_value(vr.enum_name, vr.rule_id, vr.doc)
8484+
vrval = valrule_enum.add_value(vr.rule_id, vr.enum_name, vr.doc)
84918485
vrval.category = vr.category
84928486
vrval.err_msg = vr.err_msg
8493-
valrule_enum.values.append(vrval)
84948487
self.enums.append(valrule_enum)
84958488

84968489
def populate_counters(self):
@@ -8517,6 +8510,14 @@ def add_valrule_msg(self, name, desc, err_msg):
85178510
db_dxil_valrule(name, len(self.val_rules), err_msg=err_msg, doc=desc)
85188511
)
85198512

8513+
def add_inst(self, i):
8514+
if i.name != "UDiv":
8515+
# These should not overlap, but UDiv is a known collision.
8516+
assert i.name not in self.name_idx, f"Duplicate instruction name: {i.name}"
8517+
self.name_idx[i.name] = i
8518+
self.instr.append(i)
8519+
return i
8520+
85208521
def add_llvm_instr(
85218522
self, kind, llvm_id, name, llvm_name, doc, oload_types, op_params, **props
85228523
):
@@ -8529,7 +8530,7 @@ def add_llvm_instr(
85298530
oload_types=oload_types,
85308531
)
85318532
i.props = props
8532-
self.instr.append(i)
8533+
return self.add_inst(i)
85338534

85348535
def add_dxil_op(
85358536
self, name, code_class, doc, oload_types, fn_attr, op_params, **props
@@ -8549,7 +8550,7 @@ def add_dxil_op(
85498550
fn_attr=fn_attr,
85508551
)
85518552
i.props = props
8552-
self.instr.append(i)
8553+
return self.add_inst(i)
85538554

85548555
def add_dxil_op_reserved(self, name):
85558556
# The return value is parameter 0, insert the opcode as 1.
@@ -8566,7 +8567,7 @@ def add_dxil_op_reserved(self, name):
85668567
oload_types="v",
85678568
fn_attr="",
85688569
)
8569-
self.instr.append(i)
8570+
return self.add_inst(i)
85708571

85718572
def reserve_dxil_op_range(self, group_name, count, start_reserved_id=0):
85728573
"Reserve a range of dxil opcodes for future use; returns next id"

utils/hct/hctdb_instrhelp.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -423,8 +423,6 @@ class db_enumhelp_gen:
423423

424424
def __init__(self, db):
425425
self.db = db
426-
# Some enums should get a last enum marker.
427-
self.lastEnumNames = {"OpCode": "NumOpCodes", "OpCodeClass": "NumOpClasses"}
428426

429427
def print_enum(self, e, **kwargs):
430428
print("// %s" % e.doc)
@@ -451,12 +449,11 @@ def print_enum(self, e, **kwargs):
451449
if v.doc:
452450
line_format += " // {doc}"
453451
print(line_format.format(name=v.name, value=v.value, doc=v.doc))
454-
if e.name in self.lastEnumNames:
455-
lastName = self.lastEnumNames[e.name]
452+
if e.last_value_name:
453+
lastName = e.last_value_name
456454
versioned = [
457-
"%s_Dxil_%d_%d = %d," % (lastName, major, minor, info[lastName])
458-
for (major, minor), info in sorted(self.db.dxil_version_info.items())
459-
if lastName in info
455+
"%s_Dxil_%d_%d = %d," % (lastName, major, minor, count)
456+
for (major, minor), count in sorted(e.dxil_version_info.items())
460457
]
461458
if versioned:
462459
print("")

0 commit comments

Comments
 (0)