Change CodeEmitterGen to de-duplicate case statements emitted for
encoding instruction fields for different HW modes when they contain the
same code. When 2 or more HW modes share the same code for encoding the
fields of an instruction, we currently generate a case statement for
each mode and emit the same code in each case body. Instead, unique the
case statement bodies and emit each body just once.
Some minor refactor to help with this:
1. Make `emitCaseMap` a standalone static function and use
`ListSeparator` to emit the case statements.
2. Add a type-alias for the map of cases.
No upstream target seems to use this feature (`EncodingInfos`) but this
results in ~3% code size reduction in a downstream target.
Change various `InstBits` tables have an entry only for non-pseudo
target instructions and adjust the indexing into these tables
accordingly.
Some minor refactoring related to this:
- Use early return after handling variable length encodings
- Reduce the scope of anonymous namespace to just the class declaration.
Example reductions in these table sizes for some targets:
```
Target FirstSupportedOpcode Reduction in size
AMDGPU 10813 10813 * 16 = 168KB
RISCV 12051 12051 * 8 = 94KB
```
`Predicates` and `Features` fields serve the same purpose. They should
be kept in sync, but not all predicates are based on features. This
resulted in introducing dummy features for that only reason.
This patch removes `Features` field and changes TableGen emitters to use
`Predicates` instead.
Historically, predicates were written with the assumption that the
checking code will be used in `SelectionDAGISel` subclasses, meaning
they will have access to the subclass variables, such as `Subtarget`.
There are no such variables in the generated
`GenSubtargetInfo::getHwModeSet()`, so we need to provide them. This can
be achieved by subclassing `HwModePredicateProlog`, see an example in
`Hexagon.td`.
1. Bitwise operations are used to access HwMode, allowing for the
coexistence of HwMode IDs for different features (such as RegInfo and
EncodingInfo). This will provide better scalability for HwMode.
Currently, most users utilize HwMode primarily for configuring
Register-related information, and few use it for configuring Encoding.
The limited scalability of HwMode has been a significant factor in this
usage pattern.
2. Sink the HwMode Encodings selection logic down to per instruction
level, this makes the logic for choosing encodings clearer and provides
better error messages.
3. Add some HwMode ID conflict detection to the getHwMode() interface.