Most users of AddImm and CheckConstantInt only use 1 byte immediates, so
I added an opcode variants for those. That way all those instructions
save 7 bytes.
Also added an opcode for AddTempRegister for the cases where there are
no register flags.
Space savings:
- AMDGPUGenGlobalISel: 470180 bytes to 422564 (-10%)
- AArch64GenGlobalISel.inc: 383893 bytes to 374046
Also disables generation of MutateOpcode. It's almost never used in
combiners anyway.
If we really want to use it, it needs to be investigated & properly
fixed (see TODO)
Fixes#70780
Use `MachineIRBuilder::buildConstant` to emit typed immediates in
'apply' MIR patterns.
This adds flexibility, e.g. it allows us to seamlessly handle vector
cases, where a `G_BUILD_VECTOR` is needed to create a splat.
Adds a new feature to MIR patterns: builtin instructions.
They offer some additional capabilities that currently cannot be expressed without falling back to C++ code.
There are two builtins added with this patch, but more can be added later as new needs arise:
- GIReplaceReg
- GIEraseRoot
Depends on D158714, D158713
Reviewed By: arsenm, aemerson
Differential Revision: https://reviews.llvm.org/D158975
Similar to SelectionDAG, this patch treats HwMode as an additional
predicate that needs to be satisfied for GIM_CheckFeatures.
The existing predicate passes around Record * that point to predicate
records. While HwMode expansion creates a string that needs to be
checked.
Each HwMode predicate string is uniqued by a new map that assigns
it an index. Each Rule stores the index, or -1 if HwMode doesn't
apply.
The HwMode indices each create a new Predicate feature bit and the
check string from the HwMode is used to set the feature bit.
GIM_CheckFeatures is emitted when the rule has Predicates or the HwModeIdx
is not -1.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D158660
BuildMI automatically adds the implicit operands of the
instruction. This meant we couldn''t set the dead flag on
dead implicit defs in that case.
Fix it by introducing an opcode to mark a given implicit
def as dead.
Fixes#64565
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D157515
Checks for implicit defs that are unused within a pattern and mark them as dead.
This is done directly at the TableGen level forr efficiency.
The instructions are directly created with the "dead" operand and no further analysis is needed later.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D157273
Adds a new backend to power the GISel Combiners using the InstructionSelector's match tables.
This does not depend on any of the data structures created for the current combiner and is intended to replace it entirely.
See the RFC for more details: https://discourse.llvm.org/t/rfc-matchtable-based-globalisel-combiners/71457/6
Note: this would replace D141135.
Reviewed By: aemerson, arsenm
Differential Revision: https://reviews.llvm.org/D153757
Makes `InstructionSelector.h`/`InstructionSelectorImpl.h` generic so the match tables can also be used for the combiner.
Some notes:
- Coverage was made an optional parameter of `executeMatchTable`, combines won't use it for now.
- `GIPFP_` -> `GICXXPred_` so it's more generic. Those are just C++ predicates and aren't PatFrag-specific.
- Pass the MatcherState directly to testMIPredicate_MI, the combiner will need it.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D153755
Accidentally copy-pasted them into the .cpp while refactoring the file in D151432
Those functions are currently only used in the .cpp so it didn't cause an issue, but it causes an undefined reference if another file attempts to use them.
This patch splits the GlobalISelEmitter.cpp file, which imports DAG ISel patterns for GISel, into separate "GISelMatchTable.h/cpp" files.
The main motive is readability & maintainability. GlobalISelEmitter.cpp was about 6400 lines of mixed code, some bits implementing the match table codegen, some others dedicated to importing DAG patterns.
Now it's down to 2700 + a 2150 header + 2000 impl.
It's a tiny bit more lines overall but that's to be expected - moving
inline definitions to out-of-line, adding comments in the .cpp, etc. all of that takes additional space, but I think the tradeoff is worth it.
I did as little unrelated code changes as possible, I would say the biggest change is the introduction of the `gi` namespace used to prevent name conflicts/ODR violations with type common names such as `Matcher`.
It was previously not an issue because all of the code was in an anonymous namespace.
This moves all of the "match table" code out of the file, so predicates,
rules, and actions are all separated now. I believe this helps separating concerns, now `GlobalISelEmitter.cpp` is more focused on importing DAG patterns into GI, instead of also containing the whole match table internals as well.
Note: the new files have a "GISel" prefix to make them distinct from the other "GI" files in the same folder, which are for the combiner.
Reviewed By: aemerson
Differential Revision: https://reviews.llvm.org/D151432